From eeb40fe863137ec3d52085fd8bc4ad73a8c66d13 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 14 Aug 2017 14:58:58 -0700 Subject: [PATCH 01/60] session.ts: Revert some `emptyArray` back to `undefined` (#17781) * session.ts: Revert some `emptyArray` back to `undefined` * Fix --- 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 80909362989a9..92d402b343a53 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,7 +601,7 @@ namespace ts.server { const definitions = project.getLanguageService().getDefinitionAtPosition(file, position); if (!definitions) { - return emptyArray; + return undefined; } if (simplifiedResult) { @@ -669,7 +669,7 @@ namespace ts.server { const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position); if (!occurrences) { - return emptyArray; + return undefined; } return occurrences.map(occurrence => { @@ -913,7 +913,7 @@ namespace ts.server { if (simplifiedResult) { const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position); if (!nameInfo) { - return emptyArray; + return undefined; } const displayString = displayPartsToString(nameInfo.displayParts); @@ -1176,7 +1176,7 @@ namespace ts.server { const completions = project.getLanguageService().getCompletionsAtPosition(file, position); if (!completions) { - return emptyArray; + return undefined; } if (simplifiedResult) { return mapDefined(completions.entries, entry => { From 8f029792847343886f2e5c0cc4955fb04ead1679 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 14 Aug 2017 10:11:49 -0700 Subject: [PATCH 02/60] Accept missing baseline updates for #13721 --- .../reference/errorForUsingPropertyOfTypeAsType01.js | 2 +- .../baselines/reference/exportDefaultClassInNamespace.js | 4 ++-- .../baselines/reference/expressionTypeNodeShouldError.js | 6 +++--- .../reference/importCallExpressionAsyncES3AMD.js | 4 ++-- .../reference/importCallExpressionAsyncES3CJS.js | 4 ++-- .../reference/importCallExpressionAsyncES3System.js | 4 ++-- .../reference/importCallExpressionAsyncES3UMD.js | 4 ++-- .../reference/importCallExpressionAsyncES5AMD.js | 4 ++-- .../reference/importCallExpressionAsyncES5CJS.js | 4 ++-- .../reference/importCallExpressionAsyncES5System.js | 4 ++-- .../reference/importCallExpressionAsyncES5UMD.js | 4 ++-- tests/baselines/reference/importCallExpressionES5AMD.js | 4 ++-- tests/baselines/reference/importCallExpressionES5CJS.js | 4 ++-- .../baselines/reference/importCallExpressionES5System.js | 4 ++-- tests/baselines/reference/importCallExpressionES5UMD.js | 4 ++-- tests/baselines/reference/jsdocTypeTagCast.js | 6 +++--- tests/baselines/reference/mappedTypePartialConstraints.js | 4 ++-- tests/baselines/reference/mergedDeclarationExports.js | 2 +- tests/baselines/reference/mixingApparentTypeOverrides.js | 8 ++++---- tests/baselines/reference/noUnusedLocals_selfReference.js | 6 +++--- tests/baselines/reference/promiseDefinitionTest.js | 2 +- .../signatureInstantiationWithRecursiveConstraints.js | 4 ++-- 22 files changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.js b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.js index 26903a97989da..78e65bca40007 100644 --- a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.js +++ b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.js @@ -52,7 +52,7 @@ var Test1; })(Test1 || (Test1 = {})); var Test2; (function (Test2) { - var Foo = (function () { + var Foo = /** @class */ (function () { function Foo() { } return Foo; diff --git a/tests/baselines/reference/exportDefaultClassInNamespace.js b/tests/baselines/reference/exportDefaultClassInNamespace.js index 641e5ed61a513..47ecf64a303df 100644 --- a/tests/baselines/reference/exportDefaultClassInNamespace.js +++ b/tests/baselines/reference/exportDefaultClassInNamespace.js @@ -11,7 +11,7 @@ namespace ns_abstract_class { //// [exportDefaultClassInNamespace.js] var ns_class; (function (ns_class) { - var default_1 = (function () { + var default_1 = /** @class */ (function () { function default_1() { } return default_1; @@ -20,7 +20,7 @@ var ns_class; })(ns_class || (ns_class = {})); var ns_abstract_class; (function (ns_abstract_class) { - var default_2 = (function () { + var default_2 = /** @class */ (function () { function default_2() { } return default_2; diff --git a/tests/baselines/reference/expressionTypeNodeShouldError.js b/tests/baselines/reference/expressionTypeNodeShouldError.js index 80f9f82145af1..73850a6a6c6ba 100644 --- a/tests/baselines/reference/expressionTypeNodeShouldError.js +++ b/tests/baselines/reference/expressionTypeNodeShouldError.js @@ -48,7 +48,7 @@ type ItemType3 = true.typeof(nodes.item(0)); //// [string.js] -var C = (function () { +var C = /** @class */ (function () { function C() { } C.prototype.foo = function () { @@ -60,7 +60,7 @@ var C = (function () { var nodes = document.getElementsByTagName("li"); typeof (nodes.item(0)); //// [number.js] -var C2 = (function () { +var C2 = /** @class */ (function () { function C2() { } C2.prototype.foo = function () { @@ -72,7 +72,7 @@ var C2 = (function () { var nodes2 = document.getElementsByTagName("li"); typeof (nodes.item(0)); //// [boolean.js] -var C3 = (function () { +var C3 = /** @class */ (function () { function C3() { } C3.prototype.foo = function () { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3AMD.js b/tests/baselines/reference/importCallExpressionAsyncES3AMD.js index f0246f4ce5e86..90465c0e6e483 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3AMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3AMD.js @@ -83,7 +83,7 @@ define(["require", "exports"], function (require, exports) { }); } exports.fn = fn; - var cl1 = (function () { + var cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -117,7 +117,7 @@ define(["require", "exports"], function (require, exports) { }); }); } }; - var cl2 = (function () { + var cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3CJS.js b/tests/baselines/reference/importCallExpressionAsyncES3CJS.js index 6b4006e05be0a..8c3c0d1da6fc4 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3CJS.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3CJS.js @@ -82,7 +82,7 @@ function fn() { }); } exports.fn = fn; -var cl1 = (function () { +var cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -116,7 +116,7 @@ exports.obj = { }); }); } }; -var cl2 = (function () { +var cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3System.js b/tests/baselines/reference/importCallExpressionAsyncES3System.js index 542ce1080396f..c55d8788c982e 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3System.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3System.js @@ -87,7 +87,7 @@ System.register([], function (exports_1, context_1) { return { setters: [], execute: function () { - cl1 = (function () { + cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -121,7 +121,7 @@ System.register([], function (exports_1, context_1) { }); }); } }); - cl2 = (function () { + cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3UMD.js b/tests/baselines/reference/importCallExpressionAsyncES3UMD.js index 4404cad5937a2..fce2af411e035 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3UMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3UMD.js @@ -92,7 +92,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }); } exports.fn = fn; - var cl1 = (function () { + var cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -126,7 +126,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }); }); } }; - var cl2 = (function () { + var cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5AMD.js b/tests/baselines/reference/importCallExpressionAsyncES5AMD.js index 8e7b2005e787b..3bad6ffa1f551 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5AMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5AMD.js @@ -83,7 +83,7 @@ define(["require", "exports"], function (require, exports) { }); } exports.fn = fn; - var cl1 = (function () { + var cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -117,7 +117,7 @@ define(["require", "exports"], function (require, exports) { }); }); } }; - var cl2 = (function () { + var cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5CJS.js b/tests/baselines/reference/importCallExpressionAsyncES5CJS.js index 2e04783fa89d6..87499670f3a27 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5CJS.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5CJS.js @@ -82,7 +82,7 @@ function fn() { }); } exports.fn = fn; -var cl1 = (function () { +var cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -116,7 +116,7 @@ exports.obj = { }); }); } }; -var cl2 = (function () { +var cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5System.js b/tests/baselines/reference/importCallExpressionAsyncES5System.js index b7d89d158b178..b9fad57455000 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5System.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5System.js @@ -87,7 +87,7 @@ System.register([], function (exports_1, context_1) { return { setters: [], execute: function () { - cl1 = (function () { + cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -121,7 +121,7 @@ System.register([], function (exports_1, context_1) { }); }); } }); - cl2 = (function () { + cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5UMD.js b/tests/baselines/reference/importCallExpressionAsyncES5UMD.js index 102d78cfa0592..a3b3e74db6bb4 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5UMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5UMD.js @@ -92,7 +92,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }); } exports.fn = fn; - var cl1 = (function () { + var cl1 = /** @class */ (function () { function cl1() { } cl1.prototype.m = function () { @@ -126,7 +126,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }); }); } }; - var cl2 = (function () { + var cl2 = /** @class */ (function () { function cl2() { var _this = this; this.p = { diff --git a/tests/baselines/reference/importCallExpressionES5AMD.js b/tests/baselines/reference/importCallExpressionES5AMD.js index 8fa22d81dc9ae..eec2f378ac095 100644 --- a/tests/baselines/reference/importCallExpressionES5AMD.js +++ b/tests/baselines/reference/importCallExpressionES5AMD.js @@ -48,7 +48,7 @@ define(["require", "exports"], function (require, exports) { function foo() { var p2 = new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); } - var C = (function () { + var C = /** @class */ (function () { function C() { } C.prototype.method = function () { @@ -56,7 +56,7 @@ define(["require", "exports"], function (require, exports) { }; return C; }()); - var D = (function () { + var D = /** @class */ (function () { function D() { } D.prototype.method = function () { diff --git a/tests/baselines/reference/importCallExpressionES5CJS.js b/tests/baselines/reference/importCallExpressionES5CJS.js index 2cf5d3157e21b..521044a10ceb7 100644 --- a/tests/baselines/reference/importCallExpressionES5CJS.js +++ b/tests/baselines/reference/importCallExpressionES5CJS.js @@ -45,7 +45,7 @@ exports.p2 = Promise.resolve().then(function () { return require("./0"); }); function foo() { var p2 = Promise.resolve().then(function () { return require("./0"); }); } -var C = (function () { +var C = /** @class */ (function () { function C() { } C.prototype.method = function () { @@ -53,7 +53,7 @@ var C = (function () { }; return C; }()); -var D = (function () { +var D = /** @class */ (function () { function D() { } D.prototype.method = function () { diff --git a/tests/baselines/reference/importCallExpressionES5System.js b/tests/baselines/reference/importCallExpressionES5System.js index 3dabfce80c9ab..def99752bb1b1 100644 --- a/tests/baselines/reference/importCallExpressionES5System.js +++ b/tests/baselines/reference/importCallExpressionES5System.js @@ -57,7 +57,7 @@ System.register([], function (exports_1, context_1) { return zero.foo(); }); exports_1("p2", p2 = context_1.import("./0")); - C = (function () { + C = /** @class */ (function () { function C() { } C.prototype.method = function () { @@ -65,7 +65,7 @@ System.register([], function (exports_1, context_1) { }; return C; }()); - D = (function () { + D = /** @class */ (function () { function D() { } D.prototype.method = function () { diff --git a/tests/baselines/reference/importCallExpressionES5UMD.js b/tests/baselines/reference/importCallExpressionES5UMD.js index 5727744aa7129..0ca61909ddc0c 100644 --- a/tests/baselines/reference/importCallExpressionES5UMD.js +++ b/tests/baselines/reference/importCallExpressionES5UMD.js @@ -65,7 +65,7 @@ export class D { function foo() { var p2 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); } - var C = (function () { + var C = /** @class */ (function () { function C() { } C.prototype.method = function () { @@ -73,7 +73,7 @@ export class D { }; return C; }()); - var D = (function () { + var D = /** @class */ (function () { function D() { } D.prototype.method = function () { diff --git a/tests/baselines/reference/jsdocTypeTagCast.js b/tests/baselines/reference/jsdocTypeTagCast.js index efada5ee4dc88..65e46c97757c9 100644 --- a/tests/baselines/reference/jsdocTypeTagCast.js +++ b/tests/baselines/reference/jsdocTypeTagCast.js @@ -98,13 +98,13 @@ var a; var s; var a = ("" + 4); var s = "" + /** @type {*} */ (4); -var SomeBase = (function () { +var SomeBase = /** @class */ (function () { function SomeBase() { this.p = 42; } return SomeBase; }()); -var SomeDerived = (function (_super) { +var SomeDerived = /** @class */ (function (_super) { __extends(SomeDerived, _super); function SomeDerived() { var _this = _super.call(this) || this; @@ -113,7 +113,7 @@ var SomeDerived = (function (_super) { } return SomeDerived; }(SomeBase)); -var SomeOther = (function () { +var SomeOther = /** @class */ (function () { function SomeOther() { this.q = 42; } diff --git a/tests/baselines/reference/mappedTypePartialConstraints.js b/tests/baselines/reference/mappedTypePartialConstraints.js index 1c83e2506dd0c..505a4eff9cbe0 100644 --- a/tests/baselines/reference/mappedTypePartialConstraints.js +++ b/tests/baselines/reference/mappedTypePartialConstraints.js @@ -28,13 +28,13 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var MyClass = (function () { +var MyClass = /** @class */ (function () { function MyClass() { } MyClass.prototype.doIt = function (data) { }; return MyClass; }()); -var MySubClass = (function (_super) { +var MySubClass = /** @class */ (function (_super) { __extends(MySubClass, _super); function MySubClass() { return _super !== null && _super.apply(this, arguments) || this; diff --git a/tests/baselines/reference/mergedDeclarationExports.js b/tests/baselines/reference/mergedDeclarationExports.js index 068f7b683c349..aefdc6728c520 100644 --- a/tests/baselines/reference/mergedDeclarationExports.js +++ b/tests/baselines/reference/mergedDeclarationExports.js @@ -28,7 +28,7 @@ export namespace N {} exports.__esModule = true; exports.b = 1; exports.t = 0; -var d = (function () { +var d = /** @class */ (function () { function d() { } return d; diff --git a/tests/baselines/reference/mixingApparentTypeOverrides.js b/tests/baselines/reference/mixingApparentTypeOverrides.js index 20db894abb8d1..160a2ba3f0b1b 100644 --- a/tests/baselines/reference/mixingApparentTypeOverrides.js +++ b/tests/baselines/reference/mixingApparentTypeOverrides.js @@ -40,7 +40,7 @@ var __extends = (this && this.__extends) || (function () { }; })(); function Tagged(Base) { - return (function (_super) { + return /** @class */ (function (_super) { __extends(class_1, _super); function class_1() { var args = []; @@ -54,7 +54,7 @@ function Tagged(Base) { return class_1; }(Base)); } -var A = (function () { +var A = /** @class */ (function () { function A() { } A.prototype.toString = function () { @@ -62,7 +62,7 @@ var A = (function () { }; return A; }()); -var B = (function (_super) { +var B = /** @class */ (function (_super) { __extends(B, _super); function B() { return _super !== null && _super.apply(this, arguments) || this; @@ -72,7 +72,7 @@ var B = (function (_super) { }; return B; }(Tagged(A))); -var C = (function (_super) { +var C = /** @class */ (function (_super) { __extends(C, _super); function C() { return _super !== null && _super.apply(this, arguments) || this; diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.js b/tests/baselines/reference/noUnusedLocals_selfReference.js index 74a39923d574f..5f206fbc3dc46 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.js +++ b/tests/baselines/reference/noUnusedLocals_selfReference.js @@ -20,7 +20,7 @@ P; "use strict"; exports.__esModule = true; function f() { f; } -var C = (function () { +var C = /** @class */ (function () { function C() { } C.prototype.m = function () { C; }; @@ -33,14 +33,14 @@ var E; })(E || (E = {})); // Does not detect mutual recursion. function g() { D; } -var D = (function () { +var D = /** @class */ (function () { function D() { } D.prototype.m = function () { g; }; return D; }()); // Does not work on private methods. -var P = (function () { +var P = /** @class */ (function () { function P() { } P.prototype.m = function () { this.m; }; diff --git a/tests/baselines/reference/promiseDefinitionTest.js b/tests/baselines/reference/promiseDefinitionTest.js index 317e15c99caeb..892e3c6487efe 100644 --- a/tests/baselines/reference/promiseDefinitionTest.js +++ b/tests/baselines/reference/promiseDefinitionTest.js @@ -40,7 +40,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var Promise = (function () { +var Promise = /** @class */ (function () { function Promise() { } return Promise; diff --git a/tests/baselines/reference/signatureInstantiationWithRecursiveConstraints.js b/tests/baselines/reference/signatureInstantiationWithRecursiveConstraints.js index 0be7fa1444d00..358376ce76cdc 100644 --- a/tests/baselines/reference/signatureInstantiationWithRecursiveConstraints.js +++ b/tests/baselines/reference/signatureInstantiationWithRecursiveConstraints.js @@ -15,13 +15,13 @@ const myVar: Foo = new Bar(); //// [signatureInstantiationWithRecursiveConstraints.js] "use strict"; // Repro from #17148 -var Foo = (function () { +var Foo = /** @class */ (function () { function Foo() { } Foo.prototype.myFunc = function (arg) { }; return Foo; }()); -var Bar = (function () { +var Bar = /** @class */ (function () { function Bar() { } Bar.prototype.myFunc = function (arg) { }; From a5c9f40344d625ab3a86acad474fcc8474412fc0 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 15 Aug 2017 14:59:26 -0700 Subject: [PATCH 03/60] In services, show the aliasSymbol for a type even if it's not accessible in the current scope (#17810) --- src/compiler/checker.ts | 10 +++++++--- src/compiler/types.ts | 2 ++ src/services/utilities.ts | 1 + .../quickInfoTypeAliasDefinedInDifferentFile.ts | 11 +++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoTypeAliasDefinedInDifferentFile.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 903287707503c..15fd97ca5ba8d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2153,6 +2153,11 @@ namespace ts { return false; } + function isTypeSymbolAccessible(typeSymbol: Symbol, enclosingDeclaration: Node): boolean { + const access = isSymbolAccessible(typeSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false); + return access.accessibility === SymbolAccessibility.Accessible; + } + /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * @@ -2483,8 +2488,7 @@ namespace ts { // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } - if (!inTypeAlias && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) { + if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { const name = symbolToTypeReferenceName(type.aliasSymbol); const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return createTypeReferenceNode(name, typeArgumentNodes); @@ -3251,7 +3255,7 @@ namespace ts { buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); } else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) { + ((flags & TypeFormatFlags.UseAliasDefinedOutsideCurrentScope) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { const typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, length(typeArguments), nextFlags); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0a09bb5b6ecba..11921122fa0d3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2713,6 +2713,8 @@ namespace ts { AddUndefined = 1 << 13, // Add undefined to types of initialized, non-optional parameters WriteClassExpressionAsTypeLiteral = 1 << 14, // Write a type literal instead of (Anonymous class) InArrayType = 1 << 15, // Writing an array element type + UseAliasDefinedOutsideCurrentScope = 1 << 16, // For a `type T = ... ` defined in a different file, write `T` instead of its value, + // even though `T` can't be accessed in the current scope. } export const enum SymbolFormatFlags { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index a5b035154beae..27215190db3fd 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1261,6 +1261,7 @@ namespace ts { } export function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] { + flags |= TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; return mapToDisplayParts(writer => { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); diff --git a/tests/cases/fourslash/quickInfoTypeAliasDefinedInDifferentFile.ts b/tests/cases/fourslash/quickInfoTypeAliasDefinedInDifferentFile.ts new file mode 100644 index 0000000000000..2597b5e888d3e --- /dev/null +++ b/tests/cases/fourslash/quickInfoTypeAliasDefinedInDifferentFile.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: /a.ts +////export type X = { x: number }; +////export function f(x: X): void {} + +// @Filename: /b.ts +////import { f } from "./a"; +/////**/f({ x: 1 }); + +verify.quickInfoAt("", "(alias) f(x: X): void\nimport f"); From f45ec9209035e9bb2bdcb78f06c97cab8faca795 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Aug 2017 10:42:18 -0700 Subject: [PATCH 04/60] Fixed lints. --- src/harness/harness.ts | 2 +- src/lib/es2015.symbol.wellknown.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 55a8f3ebb4d71..7122f55cae2ad 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -420,7 +420,7 @@ namespace Utils { const maxHarnessFrames = 1; - export function filterStack(error: Error, stackTraceLimit: number = Infinity) { + export function filterStack(error: Error, stackTraceLimit = Infinity) { const stack = (error).stack; if (stack) { const lines = stack.split(/\r\n?|\n/g); diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 578cf0acbc2f2..b7c2610e652c6 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -110,7 +110,7 @@ interface Map { readonly [Symbol.toStringTag]: "Map"; } -interface WeakMap{ +interface WeakMap { readonly [Symbol.toStringTag]: "WeakMap"; } From 4e570f0784a852f8a8eb97342efb71a2574f4b6b Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 18 Aug 2017 11:31:10 -0700 Subject: [PATCH 05/60] Revert public API changes to logger (#17901) --- src/harness/harnessLanguageService.ts | 5 +-- .../unittests/tsserverProjectSystem.ts | 5 +-- src/server/editorServices.ts | 32 +++++++++---------- src/server/server.ts | 28 ++++++++-------- src/server/session.ts | 4 +-- src/server/utilities.ts | 17 +++++++--- 6 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 5e8d6e76716e8..58df0d9a5e207 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -686,7 +686,7 @@ namespace Harness.LanguageService { this.host.log(message); } - err(message: string): void { + msg(message: string): void { this.host.log(message); } @@ -702,7 +702,8 @@ namespace Harness.LanguageService { return false; } - group() { throw ts.notImplemented(); } + startGroup() { throw ts.notImplemented(); } + endGroup() { throw ts.notImplemented(); } perftrc(message: string): void { return this.host.log(message); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 596e080430ca9..6e548231c9140 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -39,8 +39,9 @@ namespace ts.projectSystem { loggingEnabled: () => false, perftrc: noop, info: noop, - err: noop, - group: noop, + msg: noop, + startGroup: noop, + endGroup: noop, getLogFileName: (): string => undefined }; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index fe7946fc0f7cc..cb497ff774f1c 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -958,28 +958,28 @@ namespace ts.server { return; } - this.logger.group(info => { - let counter = 0; - counter = printProjects(this.externalProjects, info, counter); - counter = printProjects(this.configuredProjects, info, counter); - printProjects(this.inferredProjects, info, counter); - - info("Open files: "); - for (const rootFile of this.openFiles) { - info(`\t${rootFile.fileName}`); - } - }); - - function printProjects(projects: Project[], info: (msg: string) => void, counter: number): number { + this.logger.startGroup(); + let counter = 0; + const printProjects = (projects: Project[], counter: number): number => { for (const project of projects) { project.updateGraph(); - info(`Project '${project.getProjectName()}' (${ProjectKind[project.projectKind]}) ${counter}`); - info(project.filesToString()); - info("-----------------------------------------------"); + this.logger.info(`Project '${project.getProjectName()}' (${ProjectKind[project.projectKind]}) ${counter}`); + this.logger.info(project.filesToString()); + this.logger.info("-----------------------------------------------"); counter++; } return counter; + }; + counter = printProjects(this.externalProjects, counter); + counter = printProjects(this.configuredProjects, counter); + printProjects(this.inferredProjects, counter); + + this.logger.info("Open files: "); + for (const rootFile of this.openFiles) { + this.logger.info(`\t${rootFile.fileName}`); } + + this.logger.endGroup(); } private findConfiguredProjectByProjectName(configFileName: NormalizedPath) { diff --git a/src/server/server.ts b/src/server/server.ts index 66467fd46ae32..0fe37dd8ba0d5 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -140,6 +140,8 @@ namespace ts.server { class Logger implements server.Logger { private fd = -1; private seq = 0; + private inGroup = false; + private firstInGroup = true; constructor(private readonly logFilename: string, private readonly traceToConsole: boolean, @@ -169,24 +171,24 @@ namespace ts.server { } perftrc(s: string) { - this.msg(s, "Perf"); + this.msg(s, Msg.Perf); } info(s: string) { - this.msg(s, "Info"); + this.msg(s, Msg.Info); } err(s: string) { - this.msg(s, "Err"); + this.msg(s, Msg.Err); } - group(logGroupEntries: (log: (msg: string) => void) => void) { - let firstInGroup = false; - logGroupEntries(s => { - this.msg(s, "Info", /*inGroup*/ true, firstInGroup); - firstInGroup = false; - }); - this.seq++; + startGroup() { + this.inGroup = true; + this.firstInGroup = true; + } + + endGroup() { + this.inGroup = false; } loggingEnabled() { @@ -197,16 +199,16 @@ namespace ts.server { return this.loggingEnabled() && this.level >= level; } - private msg(s: string, type: string, inGroup = false, firstInGroup = false) { + msg(s: string, type: Msg.Types = Msg.Err) { if (!this.canWrite) return; s = `[${nowString()}] ${s}\n`; - if (!inGroup || firstInGroup) { + if (!this.inGroup || this.firstInGroup) { const prefix = Logger.padStringRight(type + " " + this.seq.toString(), " "); s = prefix + s; } this.write(s); - if (!inGroup) { + if (!this.inGroup) { this.seq++; } } diff --git a/src/server/session.ts b/src/server/session.ts index 92d402b343a53..9556028d05a17 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -368,7 +368,7 @@ namespace ts.server { msg += "\n" + (err).stack; } } - this.logger.err(msg); + this.logger.msg(msg, Msg.Err); } public send(msg: protocol.Message) { @@ -1950,7 +1950,7 @@ namespace ts.server { return this.executeWithRequestId(request.seq, () => handler(request)); } else { - this.logger.err(`Unrecognized JSON command: ${JSON.stringify(request)}`); + this.logger.msg(`Unrecognized JSON command: ${JSON.stringify(request)}`, Msg.Err); this.output(undefined, CommandNames.Unknown, request.seq, `Unrecognized JSON command: ${request.command}`); return { responseRequired: false }; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 0d4bc101ff63a..e2e2a67eaf12d 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -17,11 +17,22 @@ namespace ts.server { loggingEnabled(): boolean; perftrc(s: string): void; info(s: string): void; - err(s: string): void; - group(logGroupEntries: (log: (msg: string) => void) => void): void; + startGroup(): void; + endGroup(): void; + msg(s: string, type?: Msg.Types): void; getLogFileName(): string; } + export namespace Msg { + export type Err = "Err"; + export const Err: Err = "Err"; + export type Info = "Info"; + export const Info: Info = "Info"; + export type Perf = "Perf"; + export const Perf: Perf = "Perf"; + export type Types = Err | Info | Perf; + } + function getProjectRootPath(project: Project): Path { switch (project.projectKind) { case ProjectKind.Configured: @@ -115,9 +126,7 @@ namespace ts.server { } export function createNormalizedPathMap(): NormalizedPathMap { -/* tslint:disable:no-null-keyword */ const map = createMap(); -/* tslint:enable:no-null-keyword */ return { get(path) { return map.get(path); From b3ac76550351baca977885a5ae2b9de9d6fdb261 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 11:36:27 -0700 Subject: [PATCH 06/60] Updated version for next publish. --- package.json | 2 +- src/compiler/core.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2c5f8f929a793..845c37127afa0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "2.5.0", + "version": "2.5.1", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 85514987b3b03..eea8793e74532 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -6,7 +6,7 @@ namespace ts { // If changing the text in this section, be sure to test `configureNightly` too. export const versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - export const version = `${versionMajorMinor}.0`; + export const version = `${versionMajorMinor}.1`; } /* @internal */ From baeedab96c609ec3b48877b7f535b587e0f480c3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 11:47:41 -0700 Subject: [PATCH 07/60] Accepted LKG --- lib/lib.d.ts | 2 +- lib/lib.es2015.symbol.wellknown.d.ts | 2 +- lib/lib.es5.d.ts | 2 +- lib/lib.es6.d.ts | 4 +- lib/protocol.d.ts | 9 +- lib/tsc.js | 1523 ++++++----- lib/tsserver.js | 3531 ++++++++++++++++--------- lib/tsserverlibrary.d.ts | 205 +- lib/tsserverlibrary.js | 3469 +++++++++++++++++-------- lib/typescript.d.ts | 64 +- lib/typescript.js | 3533 ++++++++++++++++++-------- lib/typescriptServices.d.ts | 64 +- lib/typescriptServices.js | 3533 ++++++++++++++++++-------- lib/typingsInstaller.js | 621 ++--- 14 files changed, 10999 insertions(+), 5563 deletions(-) diff --git a/lib/lib.d.ts b/lib/lib.d.ts index 1a8b1d728333f..9be33b4d63b42 100644 --- a/lib/lib.d.ts +++ b/lib/lib.d.ts @@ -236,7 +236,7 @@ interface ObjectConstructor { * Returns the names of the enumerable properties and methods of an object. * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - keys(o: any): string[]; + keys(o: {}): string[]; } /** diff --git a/lib/lib.es2015.symbol.wellknown.d.ts b/lib/lib.es2015.symbol.wellknown.d.ts index 1d17534723a98..f323260bf896d 100644 --- a/lib/lib.es2015.symbol.wellknown.d.ts +++ b/lib/lib.es2015.symbol.wellknown.d.ts @@ -130,7 +130,7 @@ interface Map { readonly [Symbol.toStringTag]: "Map"; } -interface WeakMap{ +interface WeakMap { readonly [Symbol.toStringTag]: "WeakMap"; } diff --git a/lib/lib.es5.d.ts b/lib/lib.es5.d.ts index f628dc4fe84c1..383fb60589163 100644 --- a/lib/lib.es5.d.ts +++ b/lib/lib.es5.d.ts @@ -236,7 +236,7 @@ interface ObjectConstructor { * Returns the names of the enumerable properties and methods of an object. * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - keys(o: any): string[]; + keys(o: {}): string[]; } /** diff --git a/lib/lib.es6.d.ts b/lib/lib.es6.d.ts index 588c609a16467..abcb4337e7bed 100644 --- a/lib/lib.es6.d.ts +++ b/lib/lib.es6.d.ts @@ -236,7 +236,7 @@ interface ObjectConstructor { * Returns the names of the enumerable properties and methods of an object. * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - keys(o: any): string[]; + keys(o: {}): string[]; } /** @@ -5689,7 +5689,7 @@ interface Map { readonly [Symbol.toStringTag]: "Map"; } -interface WeakMap{ +interface WeakMap { readonly [Symbol.toStringTag]: "WeakMap"; } diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index 7b4bdfe4718c6..2f76e5f6115ea 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -714,7 +714,7 @@ declare namespace ts.server.protocol { /** * An array of span groups (one per file) that refer to the item to be renamed. */ - locs: SpanGroup[]; + locs: ReadonlyArray; } /** * Rename response message. @@ -953,6 +953,12 @@ declare namespace ts.server.protocol { * Compiler options to be used with inferred projects. */ options: ExternalProjectCompilerOptions; + /** + * Specifies the project root path used to scope compiler options. + * It is an error to provide this property if the server has not been started with + * `useInferredProjectPerProjectRoot` enabled. + */ + projectRootPath?: string; } /** * Response to SetCompilerOptionsForInferredProjectsResponse request. This is just an acknowledgement, so @@ -1922,6 +1928,7 @@ declare namespace ts.server.protocol { paths?: MapLike; plugins?: PluginImport[]; preserveConstEnums?: boolean; + preserveSymlinks?: boolean; project?: string; reactNamespace?: string; removeComments?: boolean; diff --git a/lib/tsc.js b/lib/tsc.js index 9ad790d1385ad..76af89c7672b9 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -14,6 +14,14 @@ and limitations under the License. ***************************************************************************** */ "use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; var ts; (function (ts) { var OperationCanceledException = (function () { @@ -144,7 +152,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; @@ -428,10 +436,9 @@ var ts; ts.removeWhere = removeWhere; function filterMutate(array, f) { var outIndex = 0; - for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { - var item = array_3[_i]; - if (f(item)) { - array[outIndex] = item; + for (var i = 0; i < array.length; i++) { + if (f(array[i], i, array)) { + array[outIndex] = array[i]; outIndex++; } } @@ -477,8 +484,8 @@ var ts; var result; if (array) { result = []; - for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { - var v = array_4[_i]; + for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { + var v = array_3[_i]; if (v) { if (isArray(v)) { addRange(result, v); @@ -548,11 +555,13 @@ var ts; ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; - for (var i = 0; i < array.length; i++) { - var item = array[i]; - var mapped = mapFn(item, i); - if (mapped !== undefined) { - result.push(mapped); + if (array) { + for (var i = 0; i < array.length; i++) { + var item = array[i]; + var mapped = mapFn(item, i); + if (mapped !== undefined) { + result.push(mapped); + } } } return result; @@ -620,8 +629,8 @@ var ts; function some(array, predicate) { if (array) { if (predicate) { - for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { - var v = array_5[_i]; + for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { + var v = array_4[_i]; if (predicate(v)) { return true; } @@ -646,8 +655,8 @@ var ts; var result; if (array) { result = []; - loop: for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { - var item = array_6[_i]; + loop: for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { + var item = array_5[_i]; for (var _a = 0, result_1 = result; _a < result_1.length; _a++) { var res = result_1[_a]; if (areEqual ? areEqual(res, item) : res === item) { @@ -735,8 +744,8 @@ var ts; ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; - for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { - var v = array_7[_i]; + for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { + var v = array_6[_i]; result += v[prop]; } return result; @@ -996,8 +1005,8 @@ var ts; ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); - for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { - var value = array_8[_i]; + for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { + var value = array_7[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; @@ -1157,11 +1166,11 @@ var ts; ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { var end = start + length; - Debug.assert(start >= 0, "start must be non-negative, is " + start); - Debug.assert(length >= 0, "length must be non-negative, is " + length); + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); if (file) { - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + Debug.assertLessThanOrEqual(start, file.text.length); + Debug.assertLessThanOrEqual(end, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { @@ -1645,8 +1654,28 @@ var ts; ts.fileExtensionIsOneOf = fileExtensionIsOneOf; var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42, 63]; - var singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; - var singleAsteriskRegexFragmentOther = "[^/]*"; + ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; + var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; + var filesMatcher = { + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } + }; + var directoriesMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } + }; + var excludeMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } + }; + var wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher + }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { @@ -1661,18 +1690,16 @@ var ts; if (specs === undefined || specs.length === 0) { return undefined; } - var replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther; - var singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther; - var doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; return flatMap(specs, function (spec) { - return spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); + return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } function isImplicitGlob(lastPathComponent) { return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; - function getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter) { + function getSubPatternFromSpec(spec, basePath, usage, _a) { + var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; @@ -1704,16 +1731,24 @@ var ts; subpattern += ts.directorySeparator; } if (usage !== "exclude") { + var componentPattern = ""; if (component.charCodeAt(0) === 42) { - subpattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63) { - subpattern += "[^./]"; + componentPattern += "[^./]"; component = component.substr(1); } + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } hasWrittenComponent = true; } @@ -1723,12 +1758,6 @@ var ts; } return subpattern; } - function replaceWildCardCharacterFiles(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentFiles); - } - function replaceWildCardCharacterOther(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentOther); - } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } @@ -1865,14 +1894,7 @@ var ts; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } - var extensions = allSupportedExtensions.slice(0); - for (var _i = 0, extraFileExtensions_1 = extraFileExtensions; _i < extraFileExtensions_1.length; _i++) { - var extInfo = extraFileExtensions_1[_i]; - if (extensions.indexOf(extInfo.extension) === -1) { - extensions.push(extInfo.extension); - } - } - return extensions; + return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; }))); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { @@ -2000,12 +2022,37 @@ var ts; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + verboseDebugInfo(); + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; + function assertEqual(a, b, msg, msg2) { + if (a !== b) { + var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; + fail("Expected " + a + " === " + b + ". " + message); + } + } + Debug.assertEqual = assertEqual; + function assertLessThan(a, b, msg) { + if (a >= b) { + fail("Expected " + a + " < " + b + ". " + (msg || "")); + } + } + Debug.assertLessThan = assertLessThan; + function assertLessThanOrEqual(a, b) { + if (a > b) { + fail("Expected " + a + " <= " + b); + } + } + Debug.assertLessThanOrEqual = assertLessThanOrEqual; + function assertGreaterThanOrEqual(a, b) { + if (a < b) { + fail("Expected " + a + " >= " + b); + } + } + Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); @@ -2140,6 +2187,10 @@ var ts; Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; + function isAnySupportedFileExtension(path) { + return tryGetExtensionFromPath(path) !== undefined; + } + ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } @@ -2151,6 +2202,12 @@ var ts; })(ts || (ts = {})); var ts; (function (ts) { + function setStackTraceLimit() { + if (Error.stackTraceLimit < 100) { + Error.stackTraceLimit = 100; + } + } + ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; @@ -2200,7 +2257,7 @@ var ts; watcher.referenceCount += 1; return; } - watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); + watcher = _fs.watch(dirPath || ".", { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; @@ -3021,6 +3078,7 @@ var ts; Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), + Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), @@ -3208,6 +3266,7 @@ var ts; Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), + Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), @@ -3461,6 +3520,8 @@ var ts; Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), + Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), }; })(ts || (ts = {})); var ts; @@ -5077,19 +5138,6 @@ var ts; return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; - function findDeclaration(symbol, predicate) { - var declarations = symbol.declarations; - if (declarations) { - for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { - var declaration = declarations_2[_i]; - if (predicate(declaration)) { - return declaration; - } - } - } - return undefined; - } - ts.findDeclaration = findDeclaration; var stringWriter = createSingleLineStringWriter(); var stringWriterAcquired = false; function createSingleLineStringWriter() { @@ -5152,9 +5200,13 @@ var ts; function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && - oldResolution.resolvedFileName === newResolution.resolvedFileName; + oldResolution.resolvedFileName === newResolution.resolvedFileName && + packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; + function packageIdIsEqual(a, b) { + return a === b || a && b && a.name === b.name && a.version === b.version; + } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } @@ -5219,14 +5271,6 @@ var ts; return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; - function getStartPosOfNode(node) { - return node.pos; - } - ts.getStartPosOfNode = getStartPosOfNode; - function isDefined(value) { - return value !== undefined; - } - ts.isDefined = isDefined; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); @@ -5257,6 +5301,25 @@ var ts; return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; + function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { + if (text.charCodeAt(commentPos + 1) === 47 && + commentPos + 2 < commentEnd && + text.charCodeAt(commentPos + 2) === 47) { + var textSubStr = text.substring(commentPos, commentEnd); + return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || + textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || + textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || + textSubStr.match(defaultLibReferenceRegEx) ? + true : false; + } + return false; + } + ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; + function isPinnedComment(text, comment) { + return text.charCodeAt(comment.pos + 1) === 42 && + text.charCodeAt(comment.pos + 2) === 33; + } + ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { if (nodeIsMissing(node)) { return node.pos; @@ -5313,15 +5376,20 @@ var ts; var escapeText = getEmitFlags(node) & 16777216 ? escapeString : escapeNonAsciiString; switch (node.kind) { case 9: - return '"' + escapeText(node.text) + '"'; + if (node.singleQuote) { + return "'" + escapeText(node.text, 39) + "'"; + } + else { + return '"' + escapeText(node.text, 34) + '"'; + } case 13: - return "`" + escapeText(node.text) + "`"; + return "`" + escapeText(node.text, 96) + "`"; case 14: - return "`" + escapeText(node.text) + "${"; + return "`" + escapeText(node.text, 96) + "${"; case 15: - return "}" + escapeText(node.text) + "${"; + return "}" + escapeText(node.text, 96) + "${"; case 16: - return "}" + escapeText(node.text) + "`"; + return "}" + escapeText(node.text, 96) + "`"; case 8: return node.text; } @@ -5576,10 +5644,6 @@ var ts; return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos); } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; - function getLeadingCommentRangesOfNodeFromText(node, text) { - return ts.getLeadingCommentRanges(text, node.pos); - } - ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 146 || node.kind === 145 || @@ -5587,7 +5651,7 @@ var ts; node.kind === 187 || node.kind === 185) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); + ts.getLeadingCommentRanges(text, node.pos); return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 && text.charCodeAt(comment.pos + 2) === 42 && @@ -5596,8 +5660,9 @@ var ts; } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; + var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; + var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (158 <= node.kind && node.kind <= 173) { return true; @@ -5824,21 +5889,11 @@ var ts; } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { - while (true) { - node = node.parent; - if (!node || ts.isFunctionLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { - while (true) { - node = node.parent; - if (!node || ts.isClassLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { @@ -6642,14 +6697,14 @@ var ts; ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*/gim; + var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim"); if (simpleReferenceRegEx.test(comment)) { if (isNoDefaultLibRegEx.test(comment)) { return { isNoDefaultLib: true }; } else { var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment); - var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); var match = refMatchResult || refLibResult; if (match) { var pos = commentRange.pos + match[1].length + match[2].length; @@ -6830,10 +6885,6 @@ var ts; return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; - function getOriginalSourceFiles(sourceFiles) { - return ts.sameMap(sourceFiles, getOriginalSourceFile); - } - ts.getOriginalSourceFiles = getOriginalSourceFiles; function getExpressionAssociativity(expression) { var operator = getOperator(expression); var hasArguments = expression.kind === 182 && expression.arguments !== undefined; @@ -7067,7 +7118,9 @@ var ts; } } ts.createDiagnosticCollection = createDiagnosticCollection; - var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", @@ -7078,11 +7131,16 @@ var ts; "\n": "\\n", "\\": "\\\\", "\"": "\\\"", + "\'": "\\\'", + "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" }); - function escapeString(s) { + function escapeString(s, quoteChar) { + var escapedCharsRegExp = quoteChar === 96 ? backtickQuoteEscapedCharsRegExp : + quoteChar === 39 ? singleQuoteEscapedCharsRegExp : + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } ts.escapeString = escapeString; @@ -7100,8 +7158,8 @@ var ts; return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; - function escapeNonAsciiString(s) { - s = escapeString(s); + function escapeNonAsciiString(s, quoteChar) { + s = escapeString(s, quoteChar); return nonAsciiCharacters.test(s) ? s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) : s; @@ -7442,7 +7500,7 @@ var ts; var currentDetachedCommentInfo; if (removeComments) { if (node.pos === 0) { - leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment); + leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { @@ -7474,9 +7532,8 @@ var ts; } } return currentDetachedCommentInfo; - function isPinnedComment(comment) { - return text.charCodeAt(comment.pos + 1) === 42 && - text.charCodeAt(comment.pos + 2) === 33; + function isPinnedCommentLocal(comment) { + return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; @@ -7547,9 +7604,13 @@ var ts; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { - return (getModifierFlags(node) & flags) !== 0; + return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; + function getSelectedModifierFlags(node, flags) { + return getModifierFlags(node) & flags; + } + ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912) { return node.modifierFlagsCache & ~536870912; @@ -7625,21 +7686,6 @@ var ts; return false; } ts.isDestructuringAssignment = isDestructuringAssignment; - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 71) { - return true; - } - else if (ts.isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } - } function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } @@ -7752,72 +7798,6 @@ var ts; return carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; - function isSimpleExpression(node) { - return isSimpleExpressionWorker(node, 0); - } - ts.isSimpleExpression = isSimpleExpression; - function isSimpleExpressionWorker(node, depth) { - if (depth <= 5) { - var kind = node.kind; - if (kind === 9 - || kind === 8 - || kind === 12 - || kind === 13 - || kind === 71 - || kind === 99 - || kind === 97 - || kind === 101 - || kind === 86 - || kind === 95) { - return true; - } - else if (kind === 179) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 180) { - return isSimpleExpressionWorker(node.expression, depth + 1) - && isSimpleExpressionWorker(node.argumentExpression, depth + 1); - } - else if (kind === 192 - || kind === 193) { - return isSimpleExpressionWorker(node.operand, depth + 1); - } - else if (kind === 194) { - return node.operatorToken.kind !== 40 - && isSimpleExpressionWorker(node.left, depth + 1) - && isSimpleExpressionWorker(node.right, depth + 1); - } - else if (kind === 195) { - return isSimpleExpressionWorker(node.condition, depth + 1) - && isSimpleExpressionWorker(node.whenTrue, depth + 1) - && isSimpleExpressionWorker(node.whenFalse, depth + 1); - } - else if (kind === 190 - || kind === 189 - || kind === 188) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 177) { - return node.elements.length === 0; - } - else if (kind === 178) { - return node.properties.length === 0; - } - else if (kind === 181) { - if (!isSimpleExpressionWorker(node.expression, depth + 1)) { - return false; - } - for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { - var argument = _a[_i]; - if (!isSimpleExpressionWorker(argument, depth + 1)) { - return false; - } - } - return true; - } - } - return false; - } function formatEnum(value, enumObject, isFlags) { if (value === void 0) { value = 0; } var members = getEnumMembers(enumObject); @@ -7886,18 +7866,6 @@ var ts; return formatEnum(flags, ts.ObjectFlags, true); } ts.formatObjectFlags = formatObjectFlags; - function getRangePos(range) { - return range ? range.pos : -1; - } - ts.getRangePos = getRangePos; - function getRangeEnd(range) { - return range ? range.end : -1; - } - ts.getRangeEnd = getRangeEnd; - function movePos(pos, value) { - return ts.positionIsSynthesized(pos) ? -1 : pos + value; - } - ts.movePos = movePos; function createRange(pos, end) { return { pos: pos, end: end }; } @@ -7926,14 +7894,6 @@ var ts; return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; - function collapseRangeToStart(range) { - return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos); - } - ts.collapseRangeToStart = collapseRangeToStart; - function collapseRangeToEnd(range) { - return isCollapsedRange(range) ? range : moveRangePos(range, range.end); - } - ts.collapseRangeToEnd = collapseRangeToEnd; function createTokenRange(pos, token) { return createRange(pos, pos + ts.tokenToString(token).length); } @@ -7986,22 +7946,6 @@ var ts; function isInitializedVariable(node) { return node.initializer !== undefined; } - function isMergedWithClass(node) { - if (node.symbol) { - for (var _i = 0, _a = node.symbol.declarations; _i < _a.length; _i++) { - var declaration = _a[_i]; - if (declaration.kind === 229 && declaration !== node) { - return true; - } - } - } - return false; - } - ts.isMergedWithClass = isMergedWithClass; - function isFirstDeclarationOfKind(node, kind) { - return node.symbol && getDeclarationOfKind(node.symbol, kind) === node; - } - ts.isFirstDeclarationOfKind = isFirstDeclarationOfKind; function isWatchSet(options) { return options.watch && options.hasOwnProperty("watch"); } @@ -8202,6 +8146,20 @@ var ts; return ts.hasModifier(node, 92) && node.parent.kind === 152 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function isEmptyBindingPattern(node) { + if (ts.isBindingPattern(node)) { + return ts.every(node.elements, isEmptyBindingElement); + } + return false; + } + ts.isEmptyBindingPattern = isEmptyBindingPattern; + function isEmptyBindingElement(node) { + if (ts.isOmittedExpression(node)) { + return true; + } + return isEmptyBindingPattern(node.name); + } + ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 176 || ts.isBindingPattern(node))) { node = node.parent; @@ -9282,6 +9240,18 @@ var ts; return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; + function isUnaryExpressionWithWrite(expr) { + switch (expr.kind) { + case 193: + return true; + case 192: + return expr.operator === 43 || + expr.operator === 44; + default: + return false; + } + } + ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; function isExpressionKind(kind) { return kind === 195 || kind === 197 @@ -9466,9 +9436,19 @@ var ts; var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) - || kind === 207; + || isBlockStatement(node); } ts.isStatement = isStatement; + function isBlockStatement(node) { + if (node.kind !== 207) + return false; + if (node.parent !== undefined) { + if (node.parent.kind === 224 || node.parent.kind === 260) { + return false; + } + } + return !ts.isFunctionBlock(node); + } function isModuleReference(node) { var kind = node.kind; return kind === 248 @@ -11367,11 +11347,31 @@ var ts; var node = parseTokenNode(); return token() === 23 ? undefined : node; } - function parseLiteralTypeNode() { + function parseLiteralTypeNode(negative) { var node = createNode(173); - node.literal = parseSimpleUnaryExpression(); - finishNode(node); - return node; + var unaryMinusExpression; + if (negative) { + unaryMinusExpression = createNode(192); + unaryMinusExpression.operator = 38; + nextToken(); + } + var expression; + switch (token()) { + case 9: + case 8: + expression = parseLiteralLikeNode(token()); + break; + case 101: + case 86: + expression = parseTokenNode(); + } + if (negative) { + unaryMinusExpression.operand = expression; + finishNode(unaryMinusExpression); + expression = unaryMinusExpression; + } + node.literal = expression; + return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8; @@ -11403,7 +11403,7 @@ var ts; case 86: return parseLiteralTypeNode(); case 38: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference(); + return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(true) : parseTypeReference(); case 105: case 95: return parseTokenNode(); @@ -11452,6 +11452,7 @@ var ts; case 101: case 86: case 134: + case 39: return true; case 38: return lookAhead(nextTokenIsNumericLiteral); @@ -11770,7 +11771,7 @@ var ts; if (!arrowFunction) { return undefined; } - var isAsync = !!(ts.getModifierFlags(arrowFunction) & 256); + var isAsync = ts.hasModifier(arrowFunction, 256); var lastToken = token(); arrowFunction.equalsGreaterThanToken = parseExpectedToken(36, false, ts.Diagnostics._0_expected, "=>"); arrowFunction.body = (lastToken === 36 || lastToken === 17) @@ -11886,7 +11887,7 @@ var ts; function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNode(187); node.modifiers = parseModifiersForArrowFunction(); - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; fillSignature(56, isAsync | (allowAmbiguity ? 0 : 8), node); if (!node.parameters) { return undefined; @@ -12619,7 +12620,7 @@ var ts; parseExpected(89); node.asteriskToken = parseOptionalToken(39); var isGenerator = node.asteriskToken ? 1 : 0; - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : @@ -12844,10 +12845,13 @@ var ts; function parseCatchClause() { var result = createNode(260); parseExpected(74); - if (parseExpected(19)) { + if (parseOptional(19)) { result.variableDeclaration = parseVariableDeclaration(); + parseExpected(20); + } + else { + result.variableDeclaration = undefined; } - parseExpected(20); result.block = parseBlock(false); return finishNode(result); } @@ -14535,8 +14539,8 @@ var ts; array._children = undefined; array.pos += delta; array.end += delta; - for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { - var node = array_9[_i]; + for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { + var node = array_8[_i]; visitNode(node); } } @@ -14608,8 +14612,8 @@ var ts; array.intersectsChange = true; array._children = undefined; adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (var _i = 0, array_10 = array; _i < array_10.length; _i++) { - var node = array_10[_i]; + for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { + var node = array_9[_i]; visitNode(node); } return; @@ -15359,40 +15363,23 @@ var ts; return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: flags, - expression: expression, - antecedent: antecedent - }; + return { flags: flags, expression: expression, antecedent: antecedent }; } function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) { if (!isNarrowingExpression(switchStatement.expression)) { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: 128, - switchStatement: switchStatement, - clauseStart: clauseStart, - clauseEnd: clauseEnd, - antecedent: antecedent - }; + return { flags: 128, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent }; } function createFlowAssignment(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 16, - antecedent: antecedent, - node: node - }; + return { flags: 16, antecedent: antecedent, node: node }; } function createFlowArrayMutation(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 256, - antecedent: antecedent, - node: node - }; + var res = { flags: 256, antecedent: antecedent, node: node }; + return res; } function finishFlowLabel(flow) { var antecedents = flow.antecedents; @@ -16855,7 +16842,6 @@ var ts; } function computeParameter(node, subtreeFlags) { var transformFlags = subtreeFlags; - var modifierFlags = ts.getModifierFlags(node); var name = node.name; var initializer = node.initializer; var dotDotDotToken = node.dotDotDotToken; @@ -16865,7 +16851,7 @@ var ts; || ts.isThisIdentifier(name)) { transformFlags |= 3; } - if (modifierFlags & 92) { + if (ts.hasModifier(node, 92)) { transformFlags |= 3 | 262144; } if (subtreeFlags & 1048576) { @@ -16894,8 +16880,7 @@ var ts; } function computeClassDeclaration(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); - if (modifierFlags & 2) { + if (ts.hasModifier(node, 2)) { transformFlags = 3; } else { @@ -16941,7 +16926,10 @@ var ts; } function computeCatchClause(node, subtreeFlags) { var transformFlags = subtreeFlags; - if (node.variableDeclaration && ts.isBindingPattern(node.variableDeclaration.name)) { + if (!node.variableDeclaration) { + transformFlags |= 8; + } + else if (ts.isBindingPattern(node.variableDeclaration.name)) { transformFlags |= 192; } node.transformFlags = transformFlags | 536870912; @@ -17105,9 +17093,8 @@ var ts; } function computeVariableStatement(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); var declarationListTransformFlags = node.declarationList.transformFlags; - if (modifierFlags & 2) { + if (ts.hasModifier(node, 2)) { transformFlags = 3; } else { @@ -17415,6 +17402,12 @@ var ts; return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; + function withPackageId(packageId, r) { + return r && { path: r.path, extension: r.ext, packageId: packageId }; + } + function noPackageId(r) { + return withPackageId(undefined, r); + } var Extensions; (function (Extensions) { Extensions[Extensions["TypeScript"] = 0] = "TypeScript"; @@ -17430,12 +17423,11 @@ var ts; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { - resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport }, + resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } - function tryReadPackageJsonFields(readTypes, packageJsonPath, baseDirectory, state) { - var jsonContent = readJson(packageJsonPath, state.host); + function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { @@ -17529,7 +17521,9 @@ var ts; } var resolvedTypeReferenceDirective; if (resolved) { - resolved = realpath(resolved, host, traceEnabled); + if (!options.preserveSymlinks) { + resolved = realpath(resolved, host, traceEnabled); + } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary); } @@ -17830,7 +17824,7 @@ var ts; if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, false, state); if (path_1 !== undefined) { - return { path: path_1, extension: extension }; + return { path: path_1, extension: extension, packageId: undefined }; } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); @@ -17851,7 +17845,7 @@ var ts; function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, undefined, true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { - throw new Error("Could not resolve JS module " + moduleName + " starting at " + initialDir + ". Looked in: " + failedLookupLocations.join(", ")); + throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } @@ -17877,7 +17871,13 @@ var ts; trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); - return resolved_1 && { value: resolved_1.value && { resolved: { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }, isExternalLibraryImport: true } }; + if (!resolved_1) + return undefined; + var resolvedValue = resolved_1.value; + if (!compilerOptions.preserveSymlinks) { + resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); + } + return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); @@ -17912,7 +17912,7 @@ var ts; } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return resolvedFromFile; + return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { @@ -17930,6 +17930,9 @@ var ts; return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; + function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { + return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + } function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); if (resolvedByAddingExtension) { @@ -17959,9 +17962,9 @@ var ts; case Extensions.JavaScript: return tryExtension(".js") || tryExtension(".jsx"); } - function tryExtension(extension) { - var path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); - return path && { path: path, extension: extension }; + function tryExtension(ext) { + var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + return path && { path: path, ext: ext }; } } function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) { @@ -17984,12 +17987,20 @@ var ts; function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); + var packageId; if (considerPackageJson) { var packageJsonPath = pathToPackageJson(candidate); if (directoryExists && state.host.fileExists(packageJsonPath)) { - var fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); + } + var jsonContent = readJson(packageJsonPath, state.host); + if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") { + packageId = { name: jsonContent.name, version: jsonContent.version }; + } + var fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { - return fromPackageJson; + return withPackageId(packageId, fromPackageJson); } } else { @@ -17999,13 +18010,10 @@ var ts; failedLookupLocations.push(packageJsonPath); } } - return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return withPackageId(packageId, loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state)); } - function loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); - } - var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { + var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } @@ -18021,11 +18029,15 @@ var ts; } } var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; - return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + if (result) { + ts.Debug.assert(result.packageId === undefined); + return { path: result.path, ext: result.extension }; + } } function resolvedIfExtensionMatches(extensions, path) { - var extension = ts.tryGetExtensionFromPath(path); - return extension !== undefined && extensionIsOk(extensions, extension) ? { path: path, extension: extension } : undefined; + var ext = ts.tryGetExtensionFromPath(path); + return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } function extensionIsOk(extensions, extension) { switch (extensions) { @@ -18042,7 +18054,7 @@ var ts; } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || + return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { @@ -18116,7 +18128,7 @@ var ts; if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { @@ -18127,7 +18139,7 @@ var ts; var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, false, failedLookupLocations); function tryResolve(extensions) { - var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); + var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -18139,7 +18151,7 @@ var ts; return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, false, state)); }); if (resolved_3) { return resolved_3; @@ -18150,7 +18162,7 @@ var ts; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, false, state)); } } } @@ -18376,11 +18388,10 @@ var ts; getSuggestionForNonexistentProperty: function (node, type) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentProperty(node, type)); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning)); }, getBaseConstraintOfType: getBaseConstraintOfType, - getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, - resolveNameAtLocation: function (location, name, meaning) { - location = ts.getParseTreeNode(location); - return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, undefined, ts.escapeLeadingUnderscores(name)); + resolveName: function (name, location, meaning) { + return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, undefined, undefined); }, + getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, }; var tupleTypes = []; var unionTypes = ts.createMap(); @@ -18820,13 +18831,13 @@ var ts; current.parent.kind === 149 && current.parent.initializer === current; if (initializerOfProperty) { - if (ts.getModifierFlags(current.parent) & 32) { + if (ts.hasModifier(current.parent, 32)) { if (declaration.kind === 151) { return true; } } else { - var isDeclarationInstanceProperty = declaration.kind === 149 && !(ts.getModifierFlags(declaration) & 32); + var isDeclarationInstanceProperty = declaration.kind === 149 && !ts.hasModifier(declaration, 32); if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } @@ -18906,7 +18917,7 @@ var ts; break; case 149: case 148: - if (ts.isClassLike(location.parent) && !(ts.getModifierFlags(location) & 32)) { + if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32)) { var ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & 107455)) { @@ -18923,7 +18934,7 @@ var ts; result = undefined; break; } - if (lastLocation && ts.getModifierFlags(lastLocation) & 32) { + if (lastLocation && ts.hasModifier(lastLocation, 32)) { error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters); return undefined; } @@ -18983,7 +18994,7 @@ var ts; lastLocation = location; location = location.parent; } - if (result && nameNotFoundMessage && noUnusedIdentifiers) { + if (result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) { result.isReferenced = true; } if (!result) { @@ -19064,7 +19075,7 @@ var ts; error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol)); return true; } - if (location === container && !(ts.getModifierFlags(location) & 32)) { + if (location === container && !ts.hasModifier(location, 32)) { var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -19804,6 +19815,10 @@ var ts; } return false; } + function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) { + var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064, false); + return access.accessibility === 0; + } function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) { if (symbol && enclosingDeclaration && !(symbol.flags & 262144)) { var initialSymbol = symbol; @@ -19859,7 +19874,7 @@ var ts; if (!isDeclarationVisible(declaration)) { var anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(ts.getModifierFlags(anyImportSyntax) & 1) && + !ts.hasModifier(anyImportSyntax, 1) && isDeclarationVisible(anyImportSyntax.parent)) { if (shouldComputeAliasToMakeVisible) { getNodeLinks(declaration).isVisible = true; @@ -20057,8 +20072,7 @@ var ts; var name = symbolToName(type.symbol, context, 793064, false); return ts.createTypeReferenceNode(name, undefined); } - if (!inTypeAlias && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, 793064, false).accessibility === 0) { + if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { var name = symbolToTypeReferenceName(type.aliasSymbol); var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return ts.createTypeReferenceNode(name, typeArgumentNodes); @@ -20133,8 +20147,8 @@ var ts; return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192) && + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16) && (symbol.parent || ts.forEach(symbol.declarations, function (declaration) { @@ -20146,10 +20160,8 @@ var ts; } } function createTypeNodeFromObjectType(type) { - if (type.objectFlags & 32) { - if (getConstraintTypeFromMappedType(type).flags & (16384 | 262144)) { - return createMappedTypeNodeFromType(type); - } + if (isGenericMappedType(type)) { + return createMappedTypeNodeFromType(type); } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -20677,7 +20689,7 @@ var ts; buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064, 0, nextFlags); } else if (!(flags & 1024) && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, 793064, false).accessibility === 0) { + ((flags & 65536) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { var typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags); } @@ -20821,9 +20833,7 @@ var ts; if (!symbolStack) { symbolStack = []; } - var isConstructorObject = type.flags & 32768 && - getObjectFlags(type) & 16 && - type.symbol && type.symbol.flags & 32; + var isConstructorObject = type.objectFlags & 16 && type.symbol && type.symbol.flags & 32; if (isConstructorObject) { writeLiteralType(type, flags); } @@ -20838,16 +20848,16 @@ var ts; writeLiteralType(type, flags); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192) && + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16) && (symbol.parent || - ts.forEach(symbol.declarations, function (declaration) { + ts.some(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 || declaration.parent.kind === 234; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { return !!(flags & 4) || - (ts.contains(symbolStack, symbol)); + ts.contains(symbolStack, symbol); } } } @@ -20884,11 +20894,9 @@ var ts; return false; } function writeLiteralType(type, flags) { - if (type.objectFlags & 32) { - if (getConstraintTypeFromMappedType(type).flags & (16384 | 262144)) { - writeMappedType(type); - return; - } + if (isGenericMappedType(type)) { + writeMappedType(type); + return; } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -21256,7 +21264,7 @@ var ts; case 154: case 151: case 150: - if (ts.getModifierFlags(node) & (8 | 16)) { + if (ts.hasModifier(node, 8 | 16)) { return false; } case 152: @@ -21933,8 +21941,8 @@ var ts; } } function appendTypeParameters(typeParameters, declarations) { - for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { - var declaration = declarations_3[_i]; + for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { + var declaration = declarations_2[_i]; var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); if (!typeParameters) { typeParameters = [tp]; @@ -22203,7 +22211,9 @@ var ts; if (!pushTypeResolution(symbol, 2)) { return unknownType; } - var declaration = ts.findDeclaration(symbol, function (d) { return d.kind === 283 || d.kind === 231; }); + var declaration = ts.find(symbol.declarations, function (d) { + return d.kind === 283 || d.kind === 231; + }); var type = getTypeFromTypeNode(declaration.kind === 283 ? declaration.typeExpression : declaration.type); if (popTypeResolution()) { var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -22802,8 +22812,7 @@ var ts; return getObjectFlags(type) & 32 && !!type.declaration.questionToken; } function isGenericMappedType(type) { - return getObjectFlags(type) & 32 && - maybeTypeOfKind(getConstraintTypeFromMappedType(type), 540672 | 262144); + return getObjectFlags(type) & 32 && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type) { if (!type.members) { @@ -22903,6 +22912,10 @@ var ts; return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } function getConstraintOfIndexedAccess(type) { + var transformed = getTransformedIndexedAccessType(type); + if (transformed) { + return transformed; + } var baseObjectType = getBaseConstraintOfType(type.objectType); var baseIndexType = getBaseConstraintOfType(type.indexType); return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; @@ -22965,11 +22978,18 @@ var ts; return stringType; } if (t.flags & 524288) { + var transformed = getTransformedIndexedAccessType(t); + if (transformed) { + return getBaseConstraint(transformed); + } var baseObjectType = getBaseConstraint(t.objectType); var baseIndexType = getBaseConstraint(t.indexType); var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (isGenericMappedType(t)) { + return emptyObjectType; + } return t; } } @@ -23517,7 +23537,7 @@ var ts; function getIndexInfoOfSymbol(symbol, kind) { var declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, (ts.getModifierFlags(declaration) & 64) !== 0, declaration); + return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64), declaration); } return undefined; } @@ -23785,8 +23805,8 @@ var ts; function getTypeOfGlobalSymbol(symbol, arity) { function getTypeDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { - var declaration = declarations_4[_i]; + for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { + var declaration = declarations_3[_i]; switch (declaration.kind) { case 229: case 230: @@ -24243,11 +24263,11 @@ var ts; return getTypeOfSymbol(prop); } } - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 262178 | 84 | 512)) { + if (!(indexType.flags & 6144) && isTypeAssignableToKind(indexType, 262178 | 84 | 512)) { if (isTypeAny(objectType)) { return anyType; } - var indexInfo = isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84) && getIndexInfoOfType(objectType, 1) || + var indexInfo = isTypeAssignableToKind(indexType, 84) && getIndexInfoOfType(objectType, 1) || getIndexInfoOfType(objectType, 0) || undefined; if (indexInfo) { @@ -24285,25 +24305,69 @@ var ts; return anyType; } function getIndexedAccessForMappedType(type, indexType, accessNode) { - var accessExpression = accessNode && accessNode.kind === 180 ? accessNode : undefined; - if (accessExpression && ts.isAssignmentTarget(accessExpression) && type.declaration.readonlyToken) { - error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); - return unknownType; + if (accessNode) { + if (!isTypeAssignableTo(indexType, getIndexType(type))) { + error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(type)); + return unknownType; + } + if (accessNode.kind === 180 && ts.isAssignmentTarget(accessNode) && type.declaration.readonlyToken) { + error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); + return unknownType; + } } var mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]); var templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; return instantiateType(getTemplateTypeFromMappedType(type), templateMapper); } + function isGenericObjectType(type) { + return type.flags & 540672 ? true : + getObjectFlags(type) & 32 ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : + type.flags & 196608 ? ts.forEach(type.types, isGenericObjectType) : + false; + } + function isGenericIndexType(type) { + return type.flags & (540672 | 262144) ? true : + type.flags & 196608 ? ts.forEach(type.types, isGenericIndexType) : + false; + } + function isStringIndexOnlyType(type) { + if (type.flags & 32768 && !isGenericMappedType(type)) { + var t = resolveStructuredTypeMembers(type); + return t.properties.length === 0 && + t.callSignatures.length === 0 && t.constructSignatures.length === 0 && + t.stringIndexInfo && !t.numberIndexInfo; + } + return false; + } + function getTransformedIndexedAccessType(type) { + var objectType = type.objectType; + if (objectType.flags & 131072 && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) { + var regularTypes = []; + var stringIndexTypes = []; + for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, 0)); + } + else { + regularTypes.push(t); + } + } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + return undefined; + } function getIndexedAccessType(objectType, indexType, accessNode) { - if (maybeTypeOfKind(indexType, 540672 | 262144) || - maybeTypeOfKind(objectType, 540672) && !(accessNode && accessNode.kind === 180) || - isGenericMappedType(objectType)) { + if (isGenericMappedType(objectType)) { + return getIndexedAccessForMappedType(objectType, indexType, accessNode); + } + if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180) && isGenericObjectType(objectType)) { if (objectType.flags & 1) { return objectType; } - if (isGenericMappedType(objectType)) { - return getIndexedAccessForMappedType(objectType, indexType, accessNode); - } var id = objectType.id + "," + indexType.id; var type = indexedAccessTypes.get(id); if (!type) { @@ -24502,7 +24566,7 @@ var ts; var container = ts.getThisContainer(node, false); var parent = container && container.parent; if (parent && (ts.isClassLike(parent) || parent.kind === 230)) { - if (!(ts.getModifierFlags(container) & 32) && + if (!ts.hasModifier(container, 32) && (container.kind !== 152 || ts.isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } @@ -24649,7 +24713,7 @@ var ts; } function cloneTypeMapper(mapper) { return mapper && isInferenceContext(mapper) ? - createInferenceContext(mapper.signature, mapper.flags | 2, mapper.inferences) : + createInferenceContext(mapper.signature, mapper.flags | 2, mapper.compareTypes, mapper.inferences) : mapper; } function identityMapper(type) { @@ -24913,11 +24977,13 @@ var ts; if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) { return true; } - if (node.kind === 187) { - return false; + if (node.kind !== 187) { + var parameter = ts.firstOrUndefined(node.parameters); + if (!(parameter && ts.parameterIsThisKeyword(parameter))) { + return true; + } } - var parameter = ts.firstOrUndefined(node.parameters); - return !(parameter && ts.parameterIsThisKeyword(parameter)); + return node.body.kind === 207 ? false : isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func) { return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); @@ -24980,7 +25046,7 @@ var ts; return 0; } if (source.typeParameters) { - source = instantiateSignatureInContextOf(source, target); + source = instantiateSignatureInContextOf(source, target, undefined, compareTypes); } var result = -1; var sourceThisType = getThisTypeOfSignature(source); @@ -25029,7 +25095,7 @@ var ts; var sourceReturnType = getReturnTypeOfSignature(source); if (target.typePredicate) { if (source.typePredicate) { - result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes); + result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes); } else if (ts.isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { @@ -25045,7 +25111,7 @@ var ts; } return result; } - function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) { + function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) { if (source.kind !== target.kind) { if (reportErrors) { errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); @@ -25054,11 +25120,13 @@ var ts; return 0; } if (source.kind === 1) { - var sourceIdentifierPredicate = source; - var targetIdentifierPredicate = target; - if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + var sourcePredicate = source; + var targetPredicate = target; + var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0); + var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0); + if (sourceIndex !== targetIndex) { if (reportErrors) { - errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0; @@ -25317,11 +25385,21 @@ var ts; !(target.flags & 65536) && !isIntersectionConstituent && source !== globalObjectType && - getPropertiesOfType(source).length > 0 && + (getPropertiesOfType(source).length > 0 || + getSignaturesOfType(source, 0).length > 0 || + getSignaturesOfType(source, 1).length > 0) && isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { - reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + var calls = getSignaturesOfType(source, 0); + var constructs = getSignaturesOfType(source, 1); + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, false)) { + reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target)); + } + else { + reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + } } return 0; } @@ -25942,6 +26020,9 @@ var ts; if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } + if (isGenericMappedType(source)) { + return kind === 0 && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); + } if (isObjectLiteralType(source)) { var related = -1; if (kind === 0) { @@ -25975,8 +26056,8 @@ var ts; if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } - var sourceAccessibility = ts.getModifierFlags(sourceSignature.declaration) & 24; - var targetAccessibility = ts.getModifierFlags(targetSignature.declaration) & 24; + var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24); + var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24); if (targetAccessibility === 8) { return true; } @@ -26028,7 +26109,7 @@ var ts; var symbol = type.symbol; if (symbol && symbol.flags & 32) { var declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && ts.getModifierFlags(declaration) & 128) { + if (declaration && ts.hasModifier(declaration, 128)) { return true; } } @@ -26414,13 +26495,14 @@ var ts; callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } } - function createInferenceContext(signature, flags, baseInferences) { + function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; + context.compareTypes = compareTypes || compareTypesAssignable; return context; function mapper(t) { for (var i = 0; i < inferences.length; i++) { @@ -26508,6 +26590,19 @@ var ts; return inference.candidates && getUnionType(inference.candidates, true); } } + function isPossiblyAssignableTo(source, target) { + var properties = getPropertiesOfObjectType(target); + for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { + var targetProp = properties_5[_i]; + if (!(targetProp.flags & (16777216 | 4194304))) { + var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); + if (!sourceProp) { + return false; + } + } + } + return true; + } function inferTypes(inferences, originalSource, originalTarget, priority) { if (priority === void 0) { priority = 0; } var symbolStack; @@ -26668,15 +26763,17 @@ var ts; return; } } - inferFromProperties(source, target); - inferFromSignatures(source, target, 0); - inferFromSignatures(source, target, 1); - inferFromIndexTypes(source, target); + if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) { + inferFromProperties(source, target); + inferFromSignatures(source, target, 0); + inferFromSignatures(source, target, 1); + inferFromIndexTypes(source, target); + } } function inferFromProperties(source, target) { var properties = getPropertiesOfObjectType(target); - for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { - var targetProp = properties_5[_i]; + for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { + var targetProp = properties_6[_i]; var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); if (sourceProp) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); @@ -26775,7 +26872,7 @@ var ts; var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); if (constraint) { var instantiatedConstraint = instantiateType(constraint, context); - if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } @@ -26823,16 +26920,6 @@ var ts; } return undefined; } - function getLeftmostIdentifierOrThis(node) { - switch (node.kind) { - case 71: - case 99: - return node; - case 179: - return getLeftmostIdentifierOrThis(node.expression); - } - return undefined; - } function getBindingElementNameText(element) { if (element.parent.kind === 174) { var name = element.propertyName || element.name; @@ -27324,7 +27411,7 @@ var ts; parent.parent.operatorToken.kind === 58 && parent.parent.left === parent && !ts.isAssignmentTarget(parent.parent) && - isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression(parent.argumentExpression), 84 | 2048); + isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84); return isLengthPushOrUnshift || isElementAssignment; } function maybeTypePredicateCall(node) { @@ -27470,7 +27557,7 @@ var ts; } else { var indexType = getTypeOfExpression(node.left.argumentExpression); - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 | 2048)) { + if (isTypeAssignableToKind(indexType, 84)) { evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right); } } @@ -28156,7 +28243,7 @@ var ts; break; case 149: case 148: - if (ts.getModifierFlags(container) & 32) { + if (ts.hasModifier(container, 32)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); } break; @@ -28247,14 +28334,14 @@ var ts; if (!isCallExpression && container.kind === 152) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if ((ts.getModifierFlags(container) & 32) || isCallExpression) { + if (ts.hasModifier(container, 32) || isCallExpression) { nodeCheckFlag = 512; } else { nodeCheckFlag = 256; } getNodeLinks(node).flags |= nodeCheckFlag; - if (container.kind === 151 && ts.getModifierFlags(container) & 256) { + if (container.kind === 151 && ts.hasModifier(container, 256)) { if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= 4096; } @@ -28299,7 +28386,7 @@ var ts; } else { if (ts.isClassLike(container.parent) || container.parent.kind === 178) { - if (ts.getModifierFlags(container) & 32) { + if (ts.hasModifier(container, 32)) { return container.kind === 151 || container.kind === 150 || container.kind === 153 || @@ -28825,10 +28912,7 @@ var ts; } } function isNumericComputedName(name) { - return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), 84); - } - function isTypeAnyOrAllConstituentTypesHaveKind(type, kind) { - return isTypeAny(type) || isTypeOfKind(type, kind); + return isTypeAssignableToKind(checkComputedPropertyName(name), 84); } function isInfinityOrNaNString(name) { return name === "Infinity" || name === "-Infinity" || name === "NaN"; @@ -28840,7 +28924,9 @@ var ts; var links = getNodeLinks(node.expression); if (!links.resolvedType) { links.resolvedType = checkExpression(node.expression); - if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 84 | 262178 | 512)) { + if (links.resolvedType.flags & 6144 || + !isTypeAssignableToKind(links.resolvedType, 262178 | 84 | 512) && + !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -29325,9 +29411,7 @@ var ts; return undefined; } function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) { - if (!elementType) { - elementType = checkExpression(openingLikeElement.tagName); - } + if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); } if (elementType.flags & 65536) { var types = elementType.types; return getUnionType(types.map(function (type) { @@ -29422,11 +29506,12 @@ var ts; } function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) { var links = getNodeLinks(node); - if (!links.resolvedJsxElementAttributesType) { + var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { var elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); } - return links.resolvedJsxElementAttributesType; + return links[linkLocation]; } function getAllAttributesTypeFromJsxOpeningLikeElement(node) { if (isJsxIntrinsicIdentifier(node.tagName)) { @@ -29782,7 +29867,7 @@ var ts; if (prop && noUnusedIdentifiers && (prop.flags & 106500) && - prop.valueDeclaration && (ts.getModifierFlags(prop.valueDeclaration) & 8)) { + prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8)) { if (ts.getCheckFlags(prop) & 1) { getSymbolLinks(prop).target.isReferenced = true; } @@ -30053,8 +30138,8 @@ var ts; } return undefined; } - function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper) { - var context = createInferenceContext(signature, 1); + function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) { + var context = createInferenceContext(signature, 1, compareTypes); forEachMatchingParameterType(contextualSignature, signature, function (source, target) { inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); }); @@ -30284,7 +30369,7 @@ var ts; return getLiteralType(element.name.text); case 144: var nameType = checkComputedPropertyName(element.name); - if (isTypeOfKind(nameType, 512)) { + if (isTypeAssignableToKind(nameType, 512)) { return nameType; } else { @@ -30377,9 +30462,10 @@ var ts; return resolveErrorCall(node); } var args = getEffectiveCallArguments(node); + var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; var excludeArgument; var excludeCount = 0; - if (!isDecorator) { + if (!isDecorator && !isSingleNonGenericCandidate) { for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { if (isContextSensitive(args[i])) { if (!excludeArgument) { @@ -30471,6 +30557,17 @@ var ts; if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; + if (isSingleNonGenericCandidate) { + var candidate = candidates[0]; + if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + return undefined; + } + if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, false)) { + candidateForArgumentError = candidate; + return undefined; + } + return candidate; + } for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { var originalCandidate = candidates[candidateIndex]; if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { @@ -30601,7 +30698,7 @@ var ts; return resolveErrorCall(node); } var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && ts.getModifierFlags(valueDecl) & 128) { + if (valueDecl && ts.hasModifier(valueDecl, 128)) { error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -30637,8 +30734,8 @@ var ts; return true; } var declaration = signature.declaration; - var modifiers = ts.getModifierFlags(declaration); - if (!(modifiers & 24)) { + var modifiers = ts.getSelectedModifierFlags(declaration, 24); + if (!modifiers) { return true; } var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); @@ -30841,11 +30938,33 @@ var ts; if (moduleSymbol) { var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); } } return createPromiseReturnType(node, anyType); } + function getTypeWithSyntheticDefaultImportType(type, symbol) { + if (allowSyntheticDefaultImports && type && type !== unknownType) { + var synthType = type; + if (!synthType.syntheticType) { + if (!getPropertyOfType(type, "default")) { + var memberTable = ts.createSymbolTable(); + var newSymbol = createSymbol(2097152, "default"); + newSymbol.target = resolveSymbol(symbol); + memberTable.set("default", newSymbol); + var anonymousSymbol = createSymbol(2048, "__type"); + var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, undefined, undefined); + anonymousSymbol.type = defaultContainingObject; + synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + } + else { + synthType.syntheticType = type; + } + } + return synthType.syntheticType; + } + return type; + } function isCommonJsRequire(node) { if (!ts.isRequireCall(node, true)) { return false; @@ -30964,15 +31083,15 @@ var ts; } } } - function assignBindingElementTypes(node) { - if (ts.isBindingPattern(node.name)) { - for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) { - var element = _a[_i]; - if (!ts.isOmittedExpression(element)) { - if (element.name.kind === 71) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); - } - assignBindingElementTypes(element); + function assignBindingElementTypes(pattern) { + for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (!ts.isOmittedExpression(element)) { + if (element.name.kind === 71) { + getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + } + else { + assignBindingElementTypes(element.name); } } } @@ -30981,12 +31100,13 @@ var ts; var links = getSymbolLinks(parameter); if (!links.type) { links.type = contextualType; - var name = ts.getNameOfDeclaration(parameter.valueDeclaration); - if (links.type === emptyObjectType && - (name.kind === 174 || name.kind === 175)) { - links.type = getTypeFromBindingPattern(name); + var decl = parameter.valueDeclaration; + if (decl.name.kind !== 71) { + if (links.type === emptyObjectType) { + links.type = getTypeFromBindingPattern(decl.name); + } + assignBindingElementTypes(decl.name); } - assignBindingElementTypes(parameter.valueDeclaration); } } function createPromiseType(promisedType) { @@ -31187,14 +31307,14 @@ var ts; } function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) { ts.Debug.assert(node.kind !== 151 || ts.isObjectLiteralMethod(node)); - var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); - if (!hasGrammarError && node.kind === 186) { - checkGrammarForGenerator(node); - } if (checkMode === 1 && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } + var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); + if (!hasGrammarError && node.kind === 186) { + checkGrammarForGenerator(node); + } var links = getNodeLinks(node); var type = getTypeOfSymbol(node.symbol); if (!(links.flags & 1024)) { @@ -31264,7 +31384,7 @@ var ts; } } function checkArithmeticOperandType(operand, type, diagnostic) { - if (!isTypeAnyOrAllConstituentTypesHaveKind(type, 84)) { + if (!isTypeAssignableToKind(type, 84)) { error(operand, diagnostic); return false; } @@ -31352,8 +31472,13 @@ var ts; if (operandType === silentNeverType) { return silentNeverType; } - if (node.operator === 38 && node.operand.kind === 8) { - return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + if (node.operand.kind === 8) { + if (node.operator === 38) { + return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + } + else if (node.operator === 37) { + return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text)); + } } switch (node.operator) { case 37: @@ -31405,30 +31530,22 @@ var ts; } return false; } - function isTypeOfKind(type, kind) { - if (type.flags & kind) { + function isTypeAssignableToKind(source, kind, strict) { + if (source.flags & kind) { return true; } - if (type.flags & 65536) { - var types = type.types; - for (var _i = 0, types_18 = types; _i < types_18.length; _i++) { - var t = types_18[_i]; - if (!isTypeOfKind(t, kind)) { - return false; - } - } - return true; - } - if (type.flags & 131072) { - var types = type.types; - for (var _a = 0, types_19 = types; _a < types_19.length; _a++) { - var t = types_19[_a]; - if (isTypeOfKind(t, kind)) { - return true; - } - } + if (strict && source.flags & (1 | 1024 | 2048 | 4096)) { + return false; } - return false; + return (kind & 84 && isTypeAssignableTo(source, numberType)) || + (kind & 262178 && isTypeAssignableTo(source, stringType)) || + (kind & 136 && isTypeAssignableTo(source, booleanType)) || + (kind & 1024 && isTypeAssignableTo(source, voidType)) || + (kind & 8192 && isTypeAssignableTo(source, neverType)) || + (kind & 4096 && isTypeAssignableTo(source, nullType)) || + (kind & 2048 && isTypeAssignableTo(source, undefinedType)) || + (kind & 512 && isTypeAssignableTo(source, esSymbolType)) || + (kind & 16777216 && isTypeAssignableTo(source, nonPrimitiveType)); } function isConstEnumObjectType(type) { return getObjectFlags(type) & 16 && type.symbol && isConstEnumSymbol(type.symbol); @@ -31440,7 +31557,7 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (isTypeOfKind(leftType, 8190)) { + if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190)) { error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } if (!(isTypeAny(rightType) || @@ -31457,18 +31574,18 @@ var ts; } leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); - if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, 84 | 512))) { + if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 | 512))) { error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 | 540672 | 16777216)) { + if (!isTypeAssignableToKind(rightType, 16777216 | 540672)) { error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; } function checkObjectLiteralAssignment(node, sourceType) { var properties = node.properties; - for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { - var p = properties_6[_i]; + for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) { + var p = properties_7[_i]; checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties); } return sourceType; @@ -31724,24 +31841,22 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (!isTypeOfKind(leftType, 1 | 262178) && !isTypeOfKind(rightType, 1 | 262178)) { + if (!isTypeAssignableToKind(leftType, 262178) && !isTypeAssignableToKind(rightType, 262178)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } var resultType = void 0; - if (isTypeOfKind(leftType, 84) && isTypeOfKind(rightType, 84)) { + if (isTypeAssignableToKind(leftType, 84, true) && isTypeAssignableToKind(rightType, 84, true)) { resultType = numberType; } - else { - if (isTypeOfKind(leftType, 262178) || isTypeOfKind(rightType, 262178)) { - resultType = stringType; - } - else if (isTypeAny(leftType) || isTypeAny(rightType)) { - resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; - } - if (resultType && !checkForDisallowedESSymbolOperand(operator)) { - return resultType; - } + else if (isTypeAssignableToKind(leftType, 262178, true) || isTypeAssignableToKind(rightType, 262178, true)) { + resultType = stringType; + } + else if (isTypeAny(leftType) || isTypeAny(rightType)) { + resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; + } + if (resultType && !checkForDisallowedESSymbolOperand(operator)) { + return resultType; } if (!resultType) { reportOperatorError(); @@ -31906,13 +32021,12 @@ var ts; return getBestChoiceType(type1, type2); } function checkLiteralExpression(node) { - if (node.kind === 8) { - checkGrammarNumericLiteral(node); - } switch (node.kind) { + case 13: case 9: return getFreshTypeOfLiteralType(getLiteralType(node.text)); case 8: + checkGrammarNumericLiteral(node); return getFreshTypeOfLiteralType(getLiteralType(+node.text)); case 101: return trueType; @@ -32060,6 +32174,7 @@ var ts; return checkSuperExpression(node); case 95: return nullWideningType; + case 13: case 9: case 8: case 101: @@ -32067,8 +32182,6 @@ var ts; return checkLiteralExpression(node); case 196: return checkTemplateExpression(node); - case 13: - return stringType; case 12: return globalRegExpType; case 177: @@ -32159,7 +32272,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); checkVariableLikeDeclaration(node); var func = ts.getContainingFunction(node); - if (ts.getModifierFlags(node) & 92) { + if (ts.hasModifier(node, 92)) { func = ts.getContainingFunction(node); if (!(func.kind === 152 && ts.nodeIsPresent(func.body))) { error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -32342,7 +32455,7 @@ var ts; } } else { - var isStatic = ts.getModifierFlags(member) & 32; + var isStatic = ts.hasModifier(member, 32); var names = isStatic ? staticNames : instanceNames; var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); if (memberName) { @@ -32387,7 +32500,7 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var memberNameNode = member.name; - var isStatic = ts.getModifierFlags(member) & 32; + var isStatic = ts.hasModifier(member, 32); if (isStatic && memberNameNode) { var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -32475,7 +32588,7 @@ var ts; function checkMethodDeclaration(node) { checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name); checkFunctionOrMethodDeclaration(node); - if (ts.getModifierFlags(node) & 128 && node.body) { + if (ts.hasModifier(node, 128) && node.body) { error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } @@ -32511,17 +32624,9 @@ var ts; } return ts.forEachChild(n, containsSuperCall); } - function markThisReferencesAsErrors(n) { - if (n.kind === 99) { - error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location); - } - else if (n.kind !== 186 && n.kind !== 228) { - ts.forEachChild(n, markThisReferencesAsErrors); - } - } function isInstancePropertyWithInitializer(n) { return n.kind === 149 && - !(ts.getModifierFlags(n) & 32) && + !ts.hasModifier(n, 32) && !!n.initializer; } var containingClassDecl = node.parent; @@ -32533,8 +32638,8 @@ var ts; if (classExtendsNull) { error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } - var superCallShouldBeFirst = ts.forEach(node.parent.members, isInstancePropertyWithInitializer) || - ts.forEach(node.parameters, function (p) { return ts.getModifierFlags(p) & 92; }); + var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) || + ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92); }); if (superCallShouldBeFirst) { var statements = node.body.statements; var superCallStatement = void 0; @@ -32577,10 +32682,12 @@ var ts; var otherKind = node.kind === 153 ? 154 : 153; var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if ((ts.getModifierFlags(node) & 28) !== (ts.getModifierFlags(otherAccessor) & 28)) { + var nodeFlags = ts.getModifierFlags(node); + var otherFlags = ts.getModifierFlags(otherAccessor); + if ((nodeFlags & 28) !== (otherFlags & 28)) { error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (ts.hasModifier(node, 128) !== ts.hasModifier(otherAccessor, 128)) { + if ((nodeFlags & 128) !== (otherFlags & 128)) { error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type); @@ -32634,7 +32741,14 @@ var ts; ts.forEach(node.typeArguments, checkSourceElement); if (produceDiagnostics) { var symbol = getNodeLinks(node).resolvedSymbol; - var typeParameters = symbol.flags & 524288 ? getSymbolLinks(symbol).typeParameters : type.target.localTypeParameters; + if (!symbol) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return; + } + var typeParameters = symbol.flags & 524288 && getSymbolLinks(symbol).typeParameters; + if (!typeParameters && getObjectFlags(type) & 4) { + typeParameters = type.target.localTypeParameters; + } checkTypeArgumentConstraints(typeParameters, node.typeArguments); } } @@ -32677,7 +32791,7 @@ var ts; if (isTypeAssignableTo(indexType, getIndexType(objectType))) { return type; } - if (maybeTypeOfKind(objectType, 540672) && isTypeOfKind(indexType, 84)) { + if (maybeTypeOfKind(objectType, 540672) && isTypeAssignableToKind(indexType, 84)) { var constraint = getBaseConstraintOfType(objectType); if (constraint && getIndexInfoOfType(constraint, 1)) { return type; @@ -32687,6 +32801,8 @@ var ts; return type; } function checkIndexedAccessType(node) { + checkSourceElement(node.objectType); + checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } function checkMappedType(node) { @@ -32697,7 +32813,7 @@ var ts; checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); } function isPrivateWithinAmbient(node) { - return (ts.getModifierFlags(node) & 8) && ts.isInAmbientContext(node); + return ts.hasModifier(node, 8) && ts.isInAmbientContext(node); } function getEffectiveDeclarationFlags(n, flagsToCheck) { var flags = ts.getCombinedModifierFlags(n); @@ -32784,9 +32900,9 @@ var ts; (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { var reportError = (node.kind === 151 || node.kind === 150) && - (ts.getModifierFlags(node) & 32) !== (ts.getModifierFlags(subsequentNode) & 32); + ts.hasModifier(node, 32) !== ts.hasModifier(subsequentNode, 32); if (reportError) { - var diagnostic = ts.getModifierFlags(node) & 32 ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; + var diagnostic = ts.hasModifier(node, 32) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode_1, diagnostic); } return; @@ -32802,7 +32918,7 @@ var ts; error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing); } else { - if (ts.getModifierFlags(node) & 128) { + if (ts.hasModifier(node, 128)) { error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -32812,8 +32928,8 @@ var ts; } var duplicateFunctionDeclaration = false; var multipleConstructorImplementation = false; - for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { - var current = declarations_5[_i]; + for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { + var current = declarations_4[_i]; var node = current; var inAmbientContext = ts.isInAmbientContext(node); var inAmbientContextOrInterface = node.parent.kind === 230 || node.parent.kind === 163 || inAmbientContext; @@ -32862,7 +32978,7 @@ var ts; }); } if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(ts.getModifierFlags(lastSeenNonAmbientDeclaration) & 128) && !lastSeenNonAmbientDeclaration.questionToken) { + !ts.hasModifier(lastSeenNonAmbientDeclaration, 128) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } if (hasOverloads) { @@ -33399,14 +33515,14 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 151 || member.kind === 149) { - if (!member.symbol.isReferenced && ts.getModifierFlags(member) & 8) { + if (!member.symbol.isReferenced && ts.hasModifier(member, 8)) { error(member.name, ts.Diagnostics._0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(member.symbol.escapedName)); } } else if (member.kind === 152) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; - if (!parameter.symbol.isReferenced && ts.getModifierFlags(parameter) & 8) { + if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8)) { error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(parameter.symbol.escapedName)); } } @@ -33746,7 +33862,7 @@ var ts; 128 | 64 | 32; - return (ts.getModifierFlags(left) & interestingFlags) === (ts.getModifierFlags(right) & interestingFlags); + return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); @@ -33876,7 +33992,7 @@ var ts; checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access); } } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 | 540672 | 16777216)) { + if (!isTypeAssignableToKind(rightType, 16777216 | 540672)) { error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } checkSourceElement(node.statement); @@ -34248,7 +34364,7 @@ var ts; var classDeclaration = type.symbol.valueDeclaration; for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) { var member = _a[_i]; - if (!(ts.getModifierFlags(member) & 32) && ts.hasDynamicName(member)) { + if (!ts.hasModifier(member, 32) && ts.hasDynamicName(member)) { var propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1); @@ -34345,8 +34461,8 @@ var ts; var type = getDeclaredTypeOfSymbol(symbol); if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) { var name = symbolToString(symbol); - for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { - var declaration = declarations_6[_i]; + for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { + var declaration = declarations_5[_i]; error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } @@ -34355,8 +34471,8 @@ var ts; function areTypeParametersIdentical(declarations, typeParameters) { var maxTypeArgumentCount = ts.length(typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { - var declaration = declarations_7[_i]; + for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { + var declaration = declarations_6[_i]; var numTypeParameters = ts.length(declaration.typeParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { return false; @@ -34392,7 +34508,7 @@ var ts; registerForUnusedIdentifiersCheck(node); } function checkClassDeclaration(node) { - if (!node.name && !(ts.getModifierFlags(node) & 512)) { + if (!node.name && !ts.hasModifier(node, 512)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -34485,7 +34601,7 @@ var ts; var signatures = getSignaturesOfType(type, 1); if (signatures.length) { var declaration = signatures[0].declaration; - if (declaration && ts.getModifierFlags(declaration) & 8) { + if (declaration && ts.hasModifier(declaration, 8)) { var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); @@ -34518,7 +34634,7 @@ var ts; if (derived) { if (derived === base) { var derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol); - if (baseDeclarationFlags & 128 && (!derivedClassDecl || !(ts.getModifierFlags(derivedClassDecl) & 128))) { + if (baseDeclarationFlags & 128 && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128))) { if (derivedClassDecl.kind === 199) { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } @@ -34566,8 +34682,8 @@ var ts; for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) { var base = baseTypes_2[_i]; var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); - for (var _a = 0, properties_7 = properties; _a < properties_7.length; _a++) { - var prop = properties_7[_a]; + for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) { + var prop = properties_8[_a]; var existing = seen.get(prop.escapedName); if (!existing) { seen.set(prop.escapedName, { prop: prop, containingType: base }); @@ -34821,8 +34937,8 @@ var ts; } function getFirstNonAmbientClassOrFunctionDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { - var declaration = declarations_8[_i]; + for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { + var declaration = declarations_7[_i]; if ((declaration.kind === 229 || (declaration.kind === 228 && ts.nodeIsPresent(declaration.body))) && !ts.isInAmbientContext(declaration)) { @@ -35037,7 +35153,7 @@ var ts; if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -35064,7 +35180,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (ts.getModifierFlags(node) & 1) { + if (ts.hasModifier(node, 1)) { markExportAsReferenced(node); } if (ts.isInternalModuleImportEqualsDeclaration(node)) { @@ -35092,7 +35208,7 @@ var ts; if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { @@ -35150,7 +35266,7 @@ var ts; } return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === 71) { @@ -35197,8 +35313,8 @@ var ts; return; } if (exportedDeclarationsCount > 1) { - for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { - var declaration = declarations_9[_i]; + for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { + var declaration = declarations_8[_i]; if (isNotOverload(declaration)) { diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } @@ -35476,7 +35592,7 @@ var ts; return []; } var symbols = ts.createSymbolTable(); - var memberFlags = 0; + var isStatic = false; populateSymbols(); return symbolsToArray(symbols); function populateSymbols() { @@ -35498,7 +35614,7 @@ var ts; } case 229: case 230: - if (!(memberFlags & 32)) { + if (!isStatic) { copySymbols(getSymbolOfNode(location).members, meaning & 793064); } break; @@ -35512,7 +35628,7 @@ var ts; if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } - memberFlags = ts.getModifierFlags(location); + isStatic = ts.hasModifier(location, 32); location = location.parent; } copySymbols(globals, meaning); @@ -35848,7 +35964,7 @@ var ts; } function getParentTypeOfClassElement(node) { var classSymbol = getSymbolOfNode(node.parent); - return ts.getModifierFlags(node) & 32 + return ts.hasModifier(node, 32) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -36073,13 +36189,13 @@ var ts; return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && - !(ts.getModifierFlags(parameter) & 92); + !ts.hasModifier(parameter, 92); } function isOptionalUninitializedParameterProperty(parameter) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - !!(ts.getModifierFlags(parameter) & 92); + ts.hasModifier(parameter, 92); } function getNodeCheckFlags(node) { return getNodeLinks(node).flags; @@ -36135,22 +36251,22 @@ var ts; else if (type.flags & 1) { return ts.TypeReferenceSerializationKind.ObjectType; } - else if (isTypeOfKind(type, 1024 | 6144 | 8192)) { + else if (isTypeAssignableToKind(type, 1024 | 6144 | 8192)) { return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } - else if (isTypeOfKind(type, 136)) { + else if (isTypeAssignableToKind(type, 136)) { return ts.TypeReferenceSerializationKind.BooleanType; } - else if (isTypeOfKind(type, 84)) { + else if (isTypeAssignableToKind(type, 84)) { return ts.TypeReferenceSerializationKind.NumberLikeType; } - else if (isTypeOfKind(type, 262178)) { + else if (isTypeAssignableToKind(type, 262178)) { return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } - else if (isTypeOfKind(type, 512)) { + else if (isTypeAssignableToKind(type, 512)) { return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { @@ -36615,7 +36731,7 @@ var ts; node.kind !== 154) { return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === 229 && ts.getModifierFlags(node.parent) & 128)) { + if (!(node.parent.kind === 229 && ts.hasModifier(node.parent, 128))) { return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & 32) { @@ -36811,7 +36927,7 @@ var ts; if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (ts.getModifierFlags(parameter) !== 0) { + if (ts.hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -37090,10 +37206,10 @@ var ts; else if (ts.isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(ts.getModifierFlags(accessor) & 128)) { + else if (accessor.body === undefined && !ts.hasModifier(accessor, 128)) { return grammarErrorAtPos(ts.getSourceFileOfNode(accessor), accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } - else if (accessor.body && ts.getModifierFlags(accessor) & 128) { + else if (accessor.body && ts.hasModifier(accessor, 128)) { return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { @@ -37402,7 +37518,7 @@ var ts; node.kind === 244 || node.kind === 243 || node.kind === 236 || - ts.getModifierFlags(node) & (2 | 1 | 512)) { + ts.hasModifier(node, 2 | 1 | 512)) { return false; } return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); @@ -40171,27 +40287,27 @@ var ts; function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) { var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; if (property === firstAccessor) { - var properties_8 = []; + var properties_9 = []; if (getAccessor) { var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, undefined, undefined, undefined, getAccessor.parameters, undefined, getAccessor.body); ts.setTextRange(getterFunction, getAccessor); ts.setOriginalNode(getterFunction, getAccessor); var getter = ts.createPropertyAssignment("get", getterFunction); - properties_8.push(getter); + properties_9.push(getter); } if (setAccessor) { var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, undefined, undefined, undefined, setAccessor.parameters, undefined, setAccessor.body); ts.setTextRange(setterFunction, setAccessor); ts.setOriginalNode(setterFunction, setAccessor); var setter = ts.createPropertyAssignment("set", setterFunction); - properties_8.push(setter); + properties_9.push(setter); } - properties_8.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); - properties_8.push(ts.createPropertyAssignment("configurable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue())); var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), undefined, [ receiver, createExpressionForPropertyName(property.name), - ts.createObjectLiteral(properties_8, multiLine) + ts.createObjectLiteral(properties_9, multiLine) ]), firstAccessor); return ts.aggregateTransformFlags(expression); } @@ -42119,7 +42235,8 @@ var ts; ? undefined : numElements, location), false, location); } - else if (numElements !== 1 && (flattenContext.level < 1 || numElements === 0)) { + else if (numElements !== 1 && (flattenContext.level < 1 || numElements === 0) + || ts.every(elements, ts.isOmittedExpression)) { var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } @@ -42304,7 +42421,12 @@ var ts; if (ts.hasModifier(node, 2)) { break; } - recordEmittedDeclarationInScope(node); + if (node.name) { + recordEmittedDeclarationInScope(node); + } + else { + ts.Debug.assert(node.kind === 229 || ts.hasModifier(node, 512)); + } break; } } @@ -42718,8 +42840,8 @@ var ts; && member.initializer !== undefined; } function addInitializedPropertyStatements(statements, properties, receiver) { - for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) { - var property = properties_9[_i]; + for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { + var property = properties_10[_i]; var statement = ts.createStatement(transformInitializedProperty(property, receiver)); ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); ts.setCommentRange(statement, property); @@ -42728,8 +42850,8 @@ var ts; } function generateInitializedPropertyExpressions(properties, receiver) { var expressions = []; - for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { - var property = properties_10[_i]; + for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { + var property = properties_11[_i]; var expression = transformInitializedProperty(property, receiver); expression.startsOnNewLine = true; ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); @@ -43424,24 +43546,24 @@ var ts; && moduleKind !== ts.ModuleKind.System); } function recordEmittedDeclarationInScope(node) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - if (!currentScopeFirstDeclarationsOfName) { - currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); - } - if (!currentScopeFirstDeclarationsOfName.has(name)) { - currentScopeFirstDeclarationsOfName.set(name, node); - } + if (!currentScopeFirstDeclarationsOfName) { + currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); + } + var name = declaredNameInScope(node); + if (!currentScopeFirstDeclarationsOfName.has(name)) { + currentScopeFirstDeclarationsOfName.set(name, node); } } function isFirstEmittedDeclarationInScope(node) { if (currentScopeFirstDeclarationsOfName) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - return currentScopeFirstDeclarationsOfName.get(name) === node; - } + var name = declaredNameInScope(node); + return currentScopeFirstDeclarationsOfName.get(name) === node; } - return false; + return true; + } + function declaredNameInScope(node) { + ts.Debug.assertNode(node.name, ts.isIdentifier); + return node.name.escapedText; } function addVarForEnumOrModuleDeclaration(statements, node) { var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([ @@ -43472,7 +43594,7 @@ var ts; if (!shouldEmitModuleDeclaration(node)) { return ts.createNotEmittedStatement(node); } - ts.Debug.assert(ts.isIdentifier(node.name), "TypeScript module should have an Identifier name."); + ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name."); enableSubstitutionForNamespaceExports(); var statements = []; var emitFlags = 2; @@ -44188,6 +44310,8 @@ var ts; return visitExpressionStatement(node); case 185: return visitParenthesizedExpression(node, noDestructuringValue); + case 260: + return visitCatchClause(node); default: return ts.visitEachChild(node, visitor, context); } @@ -44262,6 +44386,12 @@ var ts; function visitParenthesizedExpression(node, noDestructuringValue) { return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context); } + function visitCatchClause(node) { + if (!node.variableDeclaration) { + return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(undefined)), ts.visitNode(node.block, visitor, ts.isBlock)); + } + return ts.visitEachChild(node, visitor, context); + } function visitBinaryExpression(node, noDestructuringValue) { if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 1048576) { return ts.flattenDestructuringAssignment(node, visitor, context, 1, !noDestructuringValue); @@ -44708,7 +44838,7 @@ var ts; objectProperties = ts.createAssignHelper(context, segments); } } - var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.filter(ts.map(children, transformJsxChildToExpression), ts.isDefined), node, location); + var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } @@ -45226,7 +45356,7 @@ var ts; function shouldVisitNode(node) { return (node.transformFlags & 128) !== 0 || convertedLoopState !== undefined - || (hierarchyFacts & 4096 && ts.isStatement(node)) + || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207))) || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node)) || isTypeScriptClassWrapper(node); } @@ -45506,9 +45636,11 @@ var ts; var outer = ts.createPartiallyEmittedExpression(inner); outer.end = ts.skipTrivia(currentText, node.pos); ts.setEmitFlags(outer, 1536); - return ts.createParen(ts.createCall(outer, undefined, extendsClauseElement + var result = ts.createParen(ts.createCall(outer, undefined, extendsClauseElement ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)] : [])); + ts.addSyntheticLeadingComment(result, 3, "* @class "); + return result; } function transformClassBody(node, extendsClauseElement) { var statements = []; @@ -46093,11 +46225,12 @@ var ts; ts.setTextRange(declarationList, node); ts.setCommentRange(declarationList, node); if (node.transformFlags & 8388608 - && (ts.isBindingPattern(node.declarations[0].name) - || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { + && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { var firstDeclaration = ts.firstOrUndefined(declarations); - var lastDeclaration = ts.lastOrUndefined(declarations); - ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + if (firstDeclaration) { + var lastDeclaration = ts.lastOrUndefined(declarations); + ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + } } return declarationList; } @@ -46636,6 +46769,7 @@ var ts; function visitCatchClause(node) { var ancestorFacts = enterSubtree(4032, 0); var updated; + ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (ts.isBindingPattern(node.variableDeclaration.name)) { var temp = ts.createTempVariable(undefined); var newVariableDeclaration = ts.createVariableDeclaration(temp); @@ -48180,9 +48314,6 @@ var ts; var block = endBlock(); markLabel(block.endLabel); } - function isWithBlock(block) { - return block.kind === 1; - } function beginExceptionBlock() { var startLabel = defineLabel(); var endLabel = defineLabel(); @@ -48251,9 +48382,6 @@ var ts; emitNop(); exception.state = 3; } - function isExceptionBlock(block) { - return block.kind === 0; - } function beginScriptLoopBlock() { beginBlock({ kind: 3, @@ -48417,7 +48545,7 @@ var ts; return literal; } function createInlineBreak(label, location) { - ts.Debug.assert(label > 0, "Invalid label: " + label); + ts.Debug.assertLessThan(0, label, "Invalid label"); return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3), createLabel(label) @@ -48625,31 +48753,33 @@ var ts; for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { var block = blocks[blockIndex]; var blockAction = blockActions[blockIndex]; - if (isExceptionBlock(block)) { - if (blockAction === 0) { - if (!exceptionBlockStack) { - exceptionBlockStack = []; + switch (block.kind) { + case 0: + if (blockAction === 0) { + if (!exceptionBlockStack) { + exceptionBlockStack = []; + } + if (!statements) { + statements = []; + } + exceptionBlockStack.push(currentExceptionBlock); + currentExceptionBlock = block; } - if (!statements) { - statements = []; + else if (blockAction === 1) { + currentExceptionBlock = exceptionBlockStack.pop(); } - exceptionBlockStack.push(currentExceptionBlock); - currentExceptionBlock = block; - } - else if (blockAction === 1) { - currentExceptionBlock = exceptionBlockStack.pop(); - } - } - else if (isWithBlock(block)) { - if (blockAction === 0) { - if (!withBlockStack) { - withBlockStack = []; + break; + case 1: + if (blockAction === 0) { + if (!withBlockStack) { + withBlockStack = []; + } + withBlockStack.push(block); } - withBlockStack.push(block); - } - else if (blockAction === 1) { - withBlockStack.pop(); - } + else if (blockAction === 1) { + withBlockStack.pop(); + } + break; } } } @@ -51150,14 +51280,14 @@ var ts; writer.writeLine(); } } - function emitTrailingCommentsOfPosition(pos) { + function emitTrailingCommentsOfPosition(pos, prefixSpace) { if (disabled) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeEmitTrailingCommentsOfPosition"); } - forEachTrailingCommentToEmit(pos, emitTrailingCommentOfPosition); + forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition); if (extendedDiagnostics) { ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); } @@ -51237,15 +51367,7 @@ var ts; emitPos(commentEnd); } function isTripleSlashComment(commentPos, commentEnd) { - if (currentText.charCodeAt(commentPos + 1) === 47 && - commentPos + 2 < commentEnd && - currentText.charCodeAt(commentPos + 2) === 47) { - var textSubStr = currentText.substring(commentPos, commentEnd); - return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || - textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ? - true : false; - } - return false; + return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd); } } ts.createCommentWriter = createCommentWriter; @@ -52379,6 +52501,9 @@ var ts; return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); }); } function writeVariableStatement(node) { + if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) { + return; + } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isLet(node.declarationList)) { @@ -53757,7 +53882,9 @@ var ts; if (!(ts.getEmitFlags(node) & 131072)) { var dotRangeStart = node.expression.end; var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1; - var dotToken = { kind: 23, pos: dotRangeStart, end: dotRangeEnd }; + var dotToken = ts.createToken(23); + dotToken.pos = dotRangeStart; + dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } @@ -53869,7 +53996,9 @@ var ts; var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right); emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); + emitLeadingCommentsOfPosition(node.operatorToken.pos); writeTokenNode(node.operatorToken); + emitTrailingCommentsOfPosition(node.operatorToken.end, true); increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); decreaseIndentIf(indentBeforeOperator, indentAfterOperator); @@ -54056,8 +54185,19 @@ var ts; emitWithPrefix(" ", node.label); write(";"); } + function emitTokenWithComment(token, pos, contextNode) { + var node = contextNode && ts.getParseTreeNode(contextNode); + if (node && node.kind === contextNode.kind) { + pos = ts.skipTrivia(currentSourceFile.text, pos); + } + pos = writeToken(token, pos, contextNode); + if (node && node.kind === contextNode.kind) { + emitTrailingCommentsOfPosition(pos, true); + } + return pos; + } function emitReturnStatement(node) { - writeToken(96, node.pos, node); + emitTokenWithComment(96, node.pos, node); emitExpressionWithPrefix(" ", node.expression); write(";"); } @@ -54498,10 +54638,12 @@ var ts; function emitCatchClause(node) { var openParenPos = writeToken(74, node.pos); write(" "); - writeToken(19, openParenPos); - emit(node.variableDeclaration); - writeToken(20, node.variableDeclaration ? node.variableDeclaration.end : openParenPos); - write(" "); + if (node.variableDeclaration) { + writeToken(19, openParenPos); + emit(node.variableDeclaration); + writeToken(20, node.variableDeclaration.end); + write(" "); + } emit(node.block); } function emitPropertyAssignment(node) { @@ -55543,6 +55685,9 @@ var ts; var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; }; resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); }; } + var packageIdToSourceFile = ts.createMap(); + var sourceFileToPackageName = ts.createMap(); + var redirectTargetsSet = ts.createMap(); var filesByName = ts.createMap(); var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined; var structuralIsReused = tryReuseStructureFromOldProgram(); @@ -55599,6 +55744,8 @@ var ts; isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker, getSourceFileFromReference: getSourceFileFromReference, + sourceFileToPackageName: sourceFileToPackageName, + redirectTargetsSet: redirectTargetsSet, }; verifyCompilerOptions(); ts.performance.mark("afterProgram"); @@ -55742,17 +55889,46 @@ var ts; var filePaths = []; var modifiedSourceFiles = []; oldProgram.structureIsReused = 2; - for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) { - var oldSourceFile = _a[_i]; + var oldSourceFiles = oldProgram.getSourceFiles(); + var seenPackageNames = ts.createMap(); + for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { + var oldSourceFile = oldSourceFiles_1[_i]; var newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target) : host.getSourceFile(oldSourceFile.fileName, options.target); if (!newSourceFile) { return oldProgram.structureIsReused = 0; } + ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); + var fileChanged = void 0; + if (oldSourceFile.redirectInfo) { + if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { + return oldProgram.structureIsReused = 0; + } + fileChanged = false; + newSourceFile = oldSourceFile; + } + else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) { + if (newSourceFile !== oldSourceFile) { + return oldProgram.structureIsReused = 0; + } + fileChanged = false; + } + else { + fileChanged = newSourceFile !== oldSourceFile; + } newSourceFile.path = oldSourceFile.path; filePaths.push(newSourceFile.path); - if (oldSourceFile !== newSourceFile) { + var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); + if (packageName !== undefined) { + var prevKind = seenPackageNames.get(packageName); + var newKind = fileChanged ? 1 : 0; + if ((prevKind !== undefined && newKind === 1) || prevKind === 1) { + return oldProgram.structureIsReused = 0; + } + seenPackageNames.set(packageName, newKind); + } + if (fileChanged) { if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { oldProgram.structureIsReused = 1; } @@ -55780,8 +55956,8 @@ var ts; return oldProgram.structureIsReused; } modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; }); - for (var _b = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _b < modifiedSourceFiles_1.length; _b++) { - var _c = modifiedSourceFiles_1[_b], oldSourceFile = _c.oldFile, newSourceFile = _c.newFile; + for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) { + var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile; var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { var moduleNames = ts.map(ts.concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral); @@ -55815,8 +55991,8 @@ var ts; if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) { return oldProgram.structureIsReused = 1; } - for (var _d = 0, _e = oldProgram.getMissingFilePaths(); _d < _e.length; _d++) { - var p = _e[_d]; + for (var _c = 0, _d = oldProgram.getMissingFilePaths(); _c < _d.length; _c++) { + var p = _d[_c]; filesByName.set(p, undefined); } for (var i = 0; i < newSourceFiles.length; i++) { @@ -55824,11 +56000,13 @@ var ts; } files = newSourceFiles; fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics(); - for (var _f = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _f < modifiedSourceFiles_2.length; _f++) { - var modifiedFile = modifiedSourceFiles_2[_f]; + for (var _e = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _e < modifiedSourceFiles_2.length; _e++) { + var modifiedFile = modifiedSourceFiles_2[_e]; fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile); } resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives(); + sourceFileToPackageName = oldProgram.sourceFileToPackageName; + redirectTargetsSet = oldProgram.redirectTargetsSet; return oldProgram.structureIsReused = 2; } function getEmitHost(writeFileCallback) { @@ -56307,7 +56485,7 @@ var ts; } } function processSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd) { - getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd); }, function (diagnostic) { + getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, undefined); }, function (diagnostic) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; @@ -56324,7 +56502,24 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } } - function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd) { + function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) { + var redirect = Object.create(redirectTarget); + redirect.fileName = fileName; + redirect.path = path; + redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected }; + Object.defineProperties(redirect, { + id: { + get: function () { return this.redirectInfo.redirectTarget.id; }, + set: function (value) { this.redirectInfo.redirectTarget.id = value; }, + }, + symbol: { + get: function () { return this.redirectInfo.redirectTarget.symbol; }, + set: function (value) { this.redirectInfo.redirectTarget.symbol = value; }, + }, + }); + return redirect; + } + function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) { if (filesByName.has(path)) { var file_1 = filesByName.get(path); if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { @@ -56355,6 +56550,22 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); + if (packageId) { + var packageIdKey = packageId.name + "@" + packageId.version; + var fileFromPackageId = packageIdToSourceFile.get(packageIdKey); + if (fileFromPackageId) { + var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path); + redirectTargetsSet.set(fileFromPackageId.path, true); + filesByName.set(path, dupFile); + sourceFileToPackageName.set(path, packageId.name); + files.push(dupFile); + return dupFile; + } + else if (file) { + packageIdToSourceFile.set(packageIdKey, file); + sourceFileToPackageName.set(path, packageId.name); + } + } filesByName.set(path, file); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); @@ -56476,7 +56687,7 @@ var ts; else if (shouldAddFile) { var path = toPath(resolvedFileName); var pos = ts.skipTrivia(file.text, file.imports[i].pos); - findSourceFile(resolvedFileName, path, false, file, pos, file.imports[i].end); + findSourceFile(resolvedFileName, path, false, file, pos, file.imports[i].end, resolution.packageId); } if (isFromNodeModulesSearch) { currentNodeModulesDepth--; @@ -57155,6 +57366,12 @@ var ts; category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "preserveSymlinks", + type: "boolean", + category: ts.Diagnostics.Module_Resolution_Options, + description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, + }, { name: "sourceRoot", type: "string", @@ -57766,7 +57983,7 @@ var ts; var text = valueExpression.text; if (option && typeof option.type !== "string") { var customOption = option; - if (!customOption.type.has(text)) { + if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } @@ -58017,12 +58234,10 @@ var ts; } } else { - var specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; var outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"]; if (outDir) { - specs.push(outDir); + excludeSpecs = [outDir]; } - excludeSpecs = specs; } if (fileNames === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; @@ -58273,7 +58488,7 @@ var ts; return value; } else if (typeof option.type !== "string") { - return option.type.get(value); + return option.type.get(typeof value === "string" ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } @@ -58348,23 +58563,13 @@ var ts; }; } function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { - var validSpecs = []; - for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) { - var spec = specs_1[_i]; - if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidMultipleRecursionPatterns.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else { - validSpecs.push(spec); + return specs.filter(function (spec) { + var diag = specToDiagnostic(spec, allowTrailingRecursion); + if (diag !== undefined) { + errors.push(createDiagnostic(diag, spec)); } - } - return validSpecs; + return diag === undefined; + }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { @@ -58382,6 +58587,17 @@ var ts; return ts.createCompilerDiagnostic(message, spec); } } + function specToDiagnostic(spec, allowTrailingRecursion) { + if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + else if (invalidMultipleRecursionPatterns.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; + } + else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + } function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) { var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude"); var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); @@ -59004,6 +59220,7 @@ var ts; return; } })(ts || (ts = {})); +ts.setStackTraceLimit(); if (ts.Debug.isDebugging) { ts.Debug.enableDebugInfo(); } diff --git a/lib/tsserver.js b/lib/tsserver.js index e5ab892428567..b9bdd21b2d95e 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -513,6 +513,7 @@ var ts; TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined"; TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral"; TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType"; + TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope"; })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {})); var SymbolFormatFlags; (function (SymbolFormatFlags) { @@ -759,6 +760,12 @@ var ts; InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault"; InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault"; })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {})); + var Ternary; + (function (Ternary) { + Ternary[Ternary["False"] = 0] = "False"; + Ternary[Ternary["Maybe"] = 1] = "Maybe"; + Ternary[Ternary["True"] = -1] = "True"; + })(Ternary = ts.Ternary || (ts.Ternary = {})); var SpecialPropertyAssignmentKind; (function (SpecialPropertyAssignmentKind) { SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["None"] = 0] = "None"; @@ -1156,15 +1163,9 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { - var Ternary; - (function (Ternary) { - Ternary[Ternary["False"] = 0] = "False"; - Ternary[Ternary["Maybe"] = 1] = "Maybe"; - Ternary[Ternary["True"] = -1] = "True"; - })(Ternary = ts.Ternary || (ts.Ternary = {})); ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; ts.localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0; function createDictionaryObject() { @@ -1452,10 +1453,9 @@ var ts; ts.removeWhere = removeWhere; function filterMutate(array, f) { var outIndex = 0; - for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { - var item = array_3[_i]; - if (f(item)) { - array[outIndex] = item; + for (var i = 0; i < array.length; i++) { + if (f(array[i], i, array)) { + array[outIndex] = array[i]; outIndex++; } } @@ -1501,8 +1501,8 @@ var ts; var result; if (array) { result = []; - for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { - var v = array_4[_i]; + for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { + var v = array_3[_i]; if (v) { if (isArray(v)) { addRange(result, v); @@ -1572,11 +1572,13 @@ var ts; ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; - for (var i = 0; i < array.length; i++) { - var item = array[i]; - var mapped = mapFn(item, i); - if (mapped !== undefined) { - result.push(mapped); + if (array) { + for (var i = 0; i < array.length; i++) { + var item = array[i]; + var mapped = mapFn(item, i); + if (mapped !== undefined) { + result.push(mapped); + } } } return result; @@ -1644,8 +1646,8 @@ var ts; function some(array, predicate) { if (array) { if (predicate) { - for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { - var v = array_5[_i]; + for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { + var v = array_4[_i]; if (predicate(v)) { return true; } @@ -1670,8 +1672,8 @@ var ts; var result; if (array) { result = []; - loop: for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { - var item = array_6[_i]; + loop: for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { + var item = array_5[_i]; for (var _a = 0, result_1 = result; _a < result_1.length; _a++) { var res = result_1[_a]; if (areEqual ? areEqual(res, item) : res === item) { @@ -1759,8 +1761,8 @@ var ts; ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; - for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { - var v = array_7[_i]; + for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { + var v = array_6[_i]; result += v[prop]; } return result; @@ -2020,8 +2022,8 @@ var ts; ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); - for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { - var value = array_8[_i]; + for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { + var value = array_7[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; @@ -2181,11 +2183,11 @@ var ts; ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { var end = start + length; - Debug.assert(start >= 0, "start must be non-negative, is " + start); - Debug.assert(length >= 0, "length must be non-negative, is " + length); + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); if (file) { - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + Debug.assertLessThanOrEqual(start, file.text.length); + Debug.assertLessThanOrEqual(end, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { @@ -2669,8 +2671,28 @@ var ts; ts.fileExtensionIsOneOf = fileExtensionIsOneOf; var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42, 63]; - var singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; - var singleAsteriskRegexFragmentOther = "[^/]*"; + ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; + var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; + var filesMatcher = { + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } + }; + var directoriesMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } + }; + var excludeMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } + }; + var wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher + }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { @@ -2685,18 +2707,16 @@ var ts; if (specs === undefined || specs.length === 0) { return undefined; } - var replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther; - var singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther; - var doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; return flatMap(specs, function (spec) { - return spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); + return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } function isImplicitGlob(lastPathComponent) { return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; - function getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter) { + function getSubPatternFromSpec(spec, basePath, usage, _a) { + var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; @@ -2728,16 +2748,24 @@ var ts; subpattern += ts.directorySeparator; } if (usage !== "exclude") { + var componentPattern = ""; if (component.charCodeAt(0) === 42) { - subpattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63) { - subpattern += "[^./]"; + componentPattern += "[^./]"; component = component.substr(1); } + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } hasWrittenComponent = true; } @@ -2747,12 +2775,6 @@ var ts; } return subpattern; } - function replaceWildCardCharacterFiles(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentFiles); - } - function replaceWildCardCharacterOther(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentOther); - } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } @@ -2889,14 +2911,7 @@ var ts; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } - var extensions = allSupportedExtensions.slice(0); - for (var _i = 0, extraFileExtensions_1 = extraFileExtensions; _i < extraFileExtensions_1.length; _i++) { - var extInfo = extraFileExtensions_1[_i]; - if (extensions.indexOf(extInfo.extension) === -1) { - extensions.push(extInfo.extension); - } - } - return extensions; + return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; }))); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { @@ -3038,12 +3053,37 @@ var ts; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + verboseDebugInfo(); + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; + function assertEqual(a, b, msg, msg2) { + if (a !== b) { + var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; + fail("Expected " + a + " === " + b + ". " + message); + } + } + Debug.assertEqual = assertEqual; + function assertLessThan(a, b, msg) { + if (a >= b) { + fail("Expected " + a + " < " + b + ". " + (msg || "")); + } + } + Debug.assertLessThan = assertLessThan; + function assertLessThanOrEqual(a, b) { + if (a > b) { + fail("Expected " + a + " <= " + b); + } + } + Debug.assertLessThanOrEqual = assertLessThanOrEqual; + function assertGreaterThanOrEqual(a, b) { + if (a < b) { + fail("Expected " + a + " >= " + b); + } + } + Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); @@ -3178,6 +3218,10 @@ var ts; Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; + function isAnySupportedFileExtension(path) { + return tryGetExtensionFromPath(path) !== undefined; + } + ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } @@ -3189,6 +3233,12 @@ var ts; })(ts || (ts = {})); var ts; (function (ts) { + function setStackTraceLimit() { + if (Error.stackTraceLimit < 100) { + Error.stackTraceLimit = 100; + } + } + ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; @@ -3238,7 +3288,7 @@ var ts; watcher.referenceCount += 1; return; } - watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); + watcher = _fs.watch(dirPath || ".", { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; @@ -4064,6 +4114,7 @@ var ts; Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), + Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), @@ -4251,6 +4302,7 @@ var ts; Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), + Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), @@ -4504,6 +4556,8 @@ var ts; Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), + Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), }; })(ts || (ts = {})); var ts; @@ -4516,6 +4570,12 @@ var ts; return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; + function withPackageId(packageId, r) { + return r && { path: r.path, extension: r.ext, packageId: packageId }; + } + function noPackageId(r) { + return withPackageId(undefined, r); + } var Extensions; (function (Extensions) { Extensions[Extensions["TypeScript"] = 0] = "TypeScript"; @@ -4531,12 +4591,11 @@ var ts; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { - resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport }, + resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } - function tryReadPackageJsonFields(readTypes, packageJsonPath, baseDirectory, state) { - var jsonContent = readJson(packageJsonPath, state.host); + function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { @@ -4630,7 +4689,9 @@ var ts; } var resolvedTypeReferenceDirective; if (resolved) { - resolved = realpath(resolved, host, traceEnabled); + if (!options.preserveSymlinks) { + resolved = realpath(resolved, host, traceEnabled); + } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary); } @@ -4931,7 +4992,7 @@ var ts; if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, false, state); if (path_1 !== undefined) { - return { path: path_1, extension: extension }; + return { path: path_1, extension: extension, packageId: undefined }; } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); @@ -4952,7 +5013,7 @@ var ts; function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, undefined, true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { - throw new Error("Could not resolve JS module " + moduleName + " starting at " + initialDir + ". Looked in: " + failedLookupLocations.join(", ")); + throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } @@ -4978,7 +5039,13 @@ var ts; trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); - return resolved_1 && { value: resolved_1.value && { resolved: { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }, isExternalLibraryImport: true } }; + if (!resolved_1) + return undefined; + var resolvedValue = resolved_1.value; + if (!compilerOptions.preserveSymlinks) { + resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); + } + return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); @@ -5013,7 +5080,7 @@ var ts; } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return resolvedFromFile; + return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { @@ -5031,6 +5098,9 @@ var ts; return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; + function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { + return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + } function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); if (resolvedByAddingExtension) { @@ -5060,9 +5130,9 @@ var ts; case Extensions.JavaScript: return tryExtension(".js") || tryExtension(".jsx"); } - function tryExtension(extension) { - var path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); - return path && { path: path, extension: extension }; + function tryExtension(ext) { + var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + return path && { path: path, ext: ext }; } } function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) { @@ -5085,12 +5155,20 @@ var ts; function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); + var packageId; if (considerPackageJson) { var packageJsonPath = pathToPackageJson(candidate); if (directoryExists && state.host.fileExists(packageJsonPath)) { - var fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); + } + var jsonContent = readJson(packageJsonPath, state.host); + if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") { + packageId = { name: jsonContent.name, version: jsonContent.version }; + } + var fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { - return fromPackageJson; + return withPackageId(packageId, fromPackageJson); } } else { @@ -5100,13 +5178,10 @@ var ts; failedLookupLocations.push(packageJsonPath); } } - return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return withPackageId(packageId, loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state)); } - function loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); - } - var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { + var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } @@ -5122,11 +5197,15 @@ var ts; } } var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; - return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + if (result) { + ts.Debug.assert(result.packageId === undefined); + return { path: result.path, ext: result.extension }; + } } function resolvedIfExtensionMatches(extensions, path) { - var extension = ts.tryGetExtensionFromPath(path); - return extension !== undefined && extensionIsOk(extensions, extension) ? { path: path, extension: extension } : undefined; + var ext = ts.tryGetExtensionFromPath(path); + return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } function extensionIsOk(extensions, extension) { switch (extensions) { @@ -5143,7 +5222,7 @@ var ts; } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || + return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { @@ -5217,7 +5296,7 @@ var ts; if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { @@ -5228,7 +5307,7 @@ var ts; var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, false, failedLookupLocations); function tryResolve(extensions) { - var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); + var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -5240,7 +5319,7 @@ var ts; return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, false, state)); }); if (resolved_3) { return resolved_3; @@ -5251,7 +5330,7 @@ var ts; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, false, state)); } } } @@ -5302,19 +5381,6 @@ var ts; return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; - function findDeclaration(symbol, predicate) { - var declarations = symbol.declarations; - if (declarations) { - for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { - var declaration = declarations_2[_i]; - if (predicate(declaration)) { - return declaration; - } - } - } - return undefined; - } - ts.findDeclaration = findDeclaration; var stringWriter = createSingleLineStringWriter(); var stringWriterAcquired = false; function createSingleLineStringWriter() { @@ -5377,9 +5443,13 @@ var ts; function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && - oldResolution.resolvedFileName === newResolution.resolvedFileName; + oldResolution.resolvedFileName === newResolution.resolvedFileName && + packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; + function packageIdIsEqual(a, b) { + return a === b || a && b && a.name === b.name && a.version === b.version; + } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } @@ -5444,14 +5514,6 @@ var ts; return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; - function getStartPosOfNode(node) { - return node.pos; - } - ts.getStartPosOfNode = getStartPosOfNode; - function isDefined(value) { - return value !== undefined; - } - ts.isDefined = isDefined; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); @@ -5482,6 +5544,25 @@ var ts; return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; + function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { + if (text.charCodeAt(commentPos + 1) === 47 && + commentPos + 2 < commentEnd && + text.charCodeAt(commentPos + 2) === 47) { + var textSubStr = text.substring(commentPos, commentEnd); + return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || + textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || + textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || + textSubStr.match(defaultLibReferenceRegEx) ? + true : false; + } + return false; + } + ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; + function isPinnedComment(text, comment) { + return text.charCodeAt(comment.pos + 1) === 42 && + text.charCodeAt(comment.pos + 2) === 33; + } + ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { if (nodeIsMissing(node)) { return node.pos; @@ -5538,15 +5619,20 @@ var ts; var escapeText = getEmitFlags(node) & 16777216 ? escapeString : escapeNonAsciiString; switch (node.kind) { case 9: - return '"' + escapeText(node.text) + '"'; + if (node.singleQuote) { + return "'" + escapeText(node.text, 39) + "'"; + } + else { + return '"' + escapeText(node.text, 34) + '"'; + } case 13: - return "`" + escapeText(node.text) + "`"; + return "`" + escapeText(node.text, 96) + "`"; case 14: - return "`" + escapeText(node.text) + "${"; + return "`" + escapeText(node.text, 96) + "${"; case 15: - return "}" + escapeText(node.text) + "${"; + return "}" + escapeText(node.text, 96) + "${"; case 16: - return "}" + escapeText(node.text) + "`"; + return "}" + escapeText(node.text, 96) + "`"; case 8: return node.text; } @@ -5801,10 +5887,6 @@ var ts; return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos); } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; - function getLeadingCommentRangesOfNodeFromText(node, text) { - return ts.getLeadingCommentRanges(text, node.pos); - } - ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 146 || node.kind === 145 || @@ -5812,7 +5894,7 @@ var ts; node.kind === 187 || node.kind === 185) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); + ts.getLeadingCommentRanges(text, node.pos); return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 && text.charCodeAt(comment.pos + 2) === 42 && @@ -5821,8 +5903,9 @@ var ts; } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; + var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; + var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (158 <= node.kind && node.kind <= 173) { return true; @@ -6049,21 +6132,11 @@ var ts; } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { - while (true) { - node = node.parent; - if (!node || ts.isFunctionLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { - while (true) { - node = node.parent; - if (!node || ts.isClassLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { @@ -6873,14 +6946,14 @@ var ts; ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*/gim; + var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim"); if (simpleReferenceRegEx.test(comment)) { if (isNoDefaultLibRegEx.test(comment)) { return { isNoDefaultLib: true }; } else { var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment); - var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); var match = refMatchResult || refLibResult; if (match) { var pos = commentRange.pos + match[1].length + match[2].length; @@ -7069,10 +7142,6 @@ var ts; return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; - function getOriginalSourceFiles(sourceFiles) { - return ts.sameMap(sourceFiles, getOriginalSourceFile); - } - ts.getOriginalSourceFiles = getOriginalSourceFiles; var Associativity; (function (Associativity) { Associativity[Associativity["Left"] = 0] = "Left"; @@ -7311,7 +7380,9 @@ var ts; } } ts.createDiagnosticCollection = createDiagnosticCollection; - var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", @@ -7322,11 +7393,16 @@ var ts; "\n": "\\n", "\\": "\\\\", "\"": "\\\"", + "\'": "\\\'", + "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" }); - function escapeString(s) { + function escapeString(s, quoteChar) { + var escapedCharsRegExp = quoteChar === 96 ? backtickQuoteEscapedCharsRegExp : + quoteChar === 39 ? singleQuoteEscapedCharsRegExp : + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } ts.escapeString = escapeString; @@ -7344,8 +7420,8 @@ var ts; return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; - function escapeNonAsciiString(s) { - s = escapeString(s); + function escapeNonAsciiString(s, quoteChar) { + s = escapeString(s, quoteChar); return nonAsciiCharacters.test(s) ? s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) : s; @@ -7686,7 +7762,7 @@ var ts; var currentDetachedCommentInfo; if (removeComments) { if (node.pos === 0) { - leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment); + leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { @@ -7718,9 +7794,8 @@ var ts; } } return currentDetachedCommentInfo; - function isPinnedComment(comment) { - return text.charCodeAt(comment.pos + 1) === 42 && - text.charCodeAt(comment.pos + 2) === 33; + function isPinnedCommentLocal(comment) { + return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; @@ -7791,9 +7866,13 @@ var ts; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { - return (getModifierFlags(node) & flags) !== 0; + return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; + function getSelectedModifierFlags(node, flags) { + return getModifierFlags(node) & flags; + } + ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912) { return node.modifierFlagsCache & ~536870912; @@ -7869,21 +7948,6 @@ var ts; return false; } ts.isDestructuringAssignment = isDestructuringAssignment; - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 71) { - return true; - } - else if (ts.isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } - } function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } @@ -7996,72 +8060,6 @@ var ts; return carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; - function isSimpleExpression(node) { - return isSimpleExpressionWorker(node, 0); - } - ts.isSimpleExpression = isSimpleExpression; - function isSimpleExpressionWorker(node, depth) { - if (depth <= 5) { - var kind = node.kind; - if (kind === 9 - || kind === 8 - || kind === 12 - || kind === 13 - || kind === 71 - || kind === 99 - || kind === 97 - || kind === 101 - || kind === 86 - || kind === 95) { - return true; - } - else if (kind === 179) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 180) { - return isSimpleExpressionWorker(node.expression, depth + 1) - && isSimpleExpressionWorker(node.argumentExpression, depth + 1); - } - else if (kind === 192 - || kind === 193) { - return isSimpleExpressionWorker(node.operand, depth + 1); - } - else if (kind === 194) { - return node.operatorToken.kind !== 40 - && isSimpleExpressionWorker(node.left, depth + 1) - && isSimpleExpressionWorker(node.right, depth + 1); - } - else if (kind === 195) { - return isSimpleExpressionWorker(node.condition, depth + 1) - && isSimpleExpressionWorker(node.whenTrue, depth + 1) - && isSimpleExpressionWorker(node.whenFalse, depth + 1); - } - else if (kind === 190 - || kind === 189 - || kind === 188) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 177) { - return node.elements.length === 0; - } - else if (kind === 178) { - return node.properties.length === 0; - } - else if (kind === 181) { - if (!isSimpleExpressionWorker(node.expression, depth + 1)) { - return false; - } - for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { - var argument = _a[_i]; - if (!isSimpleExpressionWorker(argument, depth + 1)) { - return false; - } - } - return true; - } - } - return false; - } function formatEnum(value, enumObject, isFlags) { if (value === void 0) { value = 0; } var members = getEnumMembers(enumObject); @@ -8130,18 +8128,6 @@ var ts; return formatEnum(flags, ts.ObjectFlags, true); } ts.formatObjectFlags = formatObjectFlags; - function getRangePos(range) { - return range ? range.pos : -1; - } - ts.getRangePos = getRangePos; - function getRangeEnd(range) { - return range ? range.end : -1; - } - ts.getRangeEnd = getRangeEnd; - function movePos(pos, value) { - return ts.positionIsSynthesized(pos) ? -1 : pos + value; - } - ts.movePos = movePos; function createRange(pos, end) { return { pos: pos, end: end }; } @@ -8170,14 +8156,6 @@ var ts; return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; - function collapseRangeToStart(range) { - return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos); - } - ts.collapseRangeToStart = collapseRangeToStart; - function collapseRangeToEnd(range) { - return isCollapsedRange(range) ? range : moveRangePos(range, range.end); - } - ts.collapseRangeToEnd = collapseRangeToEnd; function createTokenRange(pos, token) { return createRange(pos, pos + ts.tokenToString(token).length); } @@ -8230,22 +8208,6 @@ var ts; function isInitializedVariable(node) { return node.initializer !== undefined; } - function isMergedWithClass(node) { - if (node.symbol) { - for (var _i = 0, _a = node.symbol.declarations; _i < _a.length; _i++) { - var declaration = _a[_i]; - if (declaration.kind === 229 && declaration !== node) { - return true; - } - } - } - return false; - } - ts.isMergedWithClass = isMergedWithClass; - function isFirstDeclarationOfKind(node, kind) { - return node.symbol && getDeclarationOfKind(node.symbol, kind) === node; - } - ts.isFirstDeclarationOfKind = isFirstDeclarationOfKind; function isWatchSet(options) { return options.watch && options.hasOwnProperty("watch"); } @@ -8446,6 +8408,20 @@ var ts; return ts.hasModifier(node, 92) && node.parent.kind === 152 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function isEmptyBindingPattern(node) { + if (ts.isBindingPattern(node)) { + return ts.every(node.elements, isEmptyBindingElement); + } + return false; + } + ts.isEmptyBindingPattern = isEmptyBindingPattern; + function isEmptyBindingElement(node) { + if (ts.isOmittedExpression(node)) { + return true; + } + return isEmptyBindingPattern(node.name); + } + ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 176 || ts.isBindingPattern(node))) { node = node.parent; @@ -9526,6 +9502,18 @@ var ts; return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; + function isUnaryExpressionWithWrite(expr) { + switch (expr.kind) { + case 193: + return true; + case 192: + return expr.operator === 43 || + expr.operator === 44; + default: + return false; + } + } + ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; function isExpressionKind(kind) { return kind === 195 || kind === 197 @@ -9710,9 +9698,19 @@ var ts; var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) - || kind === 207; + || isBlockStatement(node); } ts.isStatement = isStatement; + function isBlockStatement(node) { + if (node.kind !== 207) + return false; + if (node.parent !== undefined) { + if (node.parent.kind === 224 || node.parent.kind === 260) { + return false; + } + } + return !ts.isFunctionBlock(node); + } function isModuleReference(node) { var kind = node.kind; return kind === 248 @@ -13217,11 +13215,31 @@ var ts; var node = parseTokenNode(); return token() === 23 ? undefined : node; } - function parseLiteralTypeNode() { + function parseLiteralTypeNode(negative) { var node = createNode(173); - node.literal = parseSimpleUnaryExpression(); - finishNode(node); - return node; + var unaryMinusExpression; + if (negative) { + unaryMinusExpression = createNode(192); + unaryMinusExpression.operator = 38; + nextToken(); + } + var expression; + switch (token()) { + case 9: + case 8: + expression = parseLiteralLikeNode(token()); + break; + case 101: + case 86: + expression = parseTokenNode(); + } + if (negative) { + unaryMinusExpression.operand = expression; + finishNode(unaryMinusExpression); + expression = unaryMinusExpression; + } + node.literal = expression; + return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8; @@ -13253,7 +13271,7 @@ var ts; case 86: return parseLiteralTypeNode(); case 38: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference(); + return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(true) : parseTypeReference(); case 105: case 95: return parseTokenNode(); @@ -13302,6 +13320,7 @@ var ts; case 101: case 86: case 134: + case 39: return true; case 38: return lookAhead(nextTokenIsNumericLiteral); @@ -13620,7 +13639,7 @@ var ts; if (!arrowFunction) { return undefined; } - var isAsync = !!(ts.getModifierFlags(arrowFunction) & 256); + var isAsync = ts.hasModifier(arrowFunction, 256); var lastToken = token(); arrowFunction.equalsGreaterThanToken = parseExpectedToken(36, false, ts.Diagnostics._0_expected, "=>"); arrowFunction.body = (lastToken === 36 || lastToken === 17) @@ -13736,7 +13755,7 @@ var ts; function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNode(187); node.modifiers = parseModifiersForArrowFunction(); - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; fillSignature(56, isAsync | (allowAmbiguity ? 0 : 8), node); if (!node.parameters) { return undefined; @@ -14469,7 +14488,7 @@ var ts; parseExpected(89); node.asteriskToken = parseOptionalToken(39); var isGenerator = node.asteriskToken ? 1 : 0; - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : @@ -14694,10 +14713,13 @@ var ts; function parseCatchClause() { var result = createNode(260); parseExpected(74); - if (parseExpected(19)) { + if (parseOptional(19)) { result.variableDeclaration = parseVariableDeclaration(); + parseExpected(20); + } + else { + result.variableDeclaration = undefined; } - parseExpected(20); result.block = parseBlock(false); return finishNode(result); } @@ -16429,8 +16451,8 @@ var ts; array._children = undefined; array.pos += delta; array.end += delta; - for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { - var node = array_9[_i]; + for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { + var node = array_8[_i]; visitNode(node); } } @@ -16502,8 +16524,8 @@ var ts; array.intersectsChange = true; array._children = undefined; adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (var _i = 0, array_10 = array; _i < array_10.length; _i++) { - var node = array_10[_i]; + for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { + var node = array_9[_i]; visitNode(node); } return; @@ -17275,40 +17297,23 @@ var ts; return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: flags, - expression: expression, - antecedent: antecedent - }; + return { flags: flags, expression: expression, antecedent: antecedent }; } function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) { if (!isNarrowingExpression(switchStatement.expression)) { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: 128, - switchStatement: switchStatement, - clauseStart: clauseStart, - clauseEnd: clauseEnd, - antecedent: antecedent - }; + return { flags: 128, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent }; } function createFlowAssignment(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 16, - antecedent: antecedent, - node: node - }; + return { flags: 16, antecedent: antecedent, node: node }; } function createFlowArrayMutation(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 256, - antecedent: antecedent, - node: node - }; + var res = { flags: 256, antecedent: antecedent, node: node }; + return res; } function finishFlowLabel(flow) { var antecedents = flow.antecedents; @@ -18776,7 +18781,6 @@ var ts; } function computeParameter(node, subtreeFlags) { var transformFlags = subtreeFlags; - var modifierFlags = ts.getModifierFlags(node); var name = node.name; var initializer = node.initializer; var dotDotDotToken = node.dotDotDotToken; @@ -18786,7 +18790,7 @@ var ts; || ts.isThisIdentifier(name)) { transformFlags |= 3; } - if (modifierFlags & 92) { + if (ts.hasModifier(node, 92)) { transformFlags |= 3 | 262144; } if (subtreeFlags & 1048576) { @@ -18815,8 +18819,7 @@ var ts; } function computeClassDeclaration(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); - if (modifierFlags & 2) { + if (ts.hasModifier(node, 2)) { transformFlags = 3; } else { @@ -18862,7 +18865,10 @@ var ts; } function computeCatchClause(node, subtreeFlags) { var transformFlags = subtreeFlags; - if (node.variableDeclaration && ts.isBindingPattern(node.variableDeclaration.name)) { + if (!node.variableDeclaration) { + transformFlags |= 8; + } + else if (ts.isBindingPattern(node.variableDeclaration.name)) { transformFlags |= 192; } node.transformFlags = transformFlags | 536870912; @@ -19026,9 +19032,8 @@ var ts; } function computeVariableStatement(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); var declarationListTransformFlags = node.declarationList.transformFlags; - if (modifierFlags & 2) { + if (ts.hasModifier(node, 2)) { transformFlags = 3; } else { @@ -19519,11 +19524,10 @@ var ts; getSuggestionForNonexistentProperty: function (node, type) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentProperty(node, type)); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning)); }, getBaseConstraintOfType: getBaseConstraintOfType, - getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, - resolveNameAtLocation: function (location, name, meaning) { - location = ts.getParseTreeNode(location); - return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, undefined, ts.escapeLeadingUnderscores(name)); + resolveName: function (name, location, meaning) { + return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, undefined, undefined); }, + getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, }; var tupleTypes = []; var unionTypes = ts.createMap(); @@ -20036,13 +20040,13 @@ var ts; current.parent.kind === 149 && current.parent.initializer === current; if (initializerOfProperty) { - if (ts.getModifierFlags(current.parent) & 32) { + if (ts.hasModifier(current.parent, 32)) { if (declaration.kind === 151) { return true; } } else { - var isDeclarationInstanceProperty = declaration.kind === 149 && !(ts.getModifierFlags(declaration) & 32); + var isDeclarationInstanceProperty = declaration.kind === 149 && !ts.hasModifier(declaration, 32); if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } @@ -20122,7 +20126,7 @@ var ts; break; case 149: case 148: - if (ts.isClassLike(location.parent) && !(ts.getModifierFlags(location) & 32)) { + if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32)) { var ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & 107455)) { @@ -20139,7 +20143,7 @@ var ts; result = undefined; break; } - if (lastLocation && ts.getModifierFlags(lastLocation) & 32) { + if (lastLocation && ts.hasModifier(lastLocation, 32)) { error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters); return undefined; } @@ -20199,7 +20203,7 @@ var ts; lastLocation = location; location = location.parent; } - if (result && nameNotFoundMessage && noUnusedIdentifiers) { + if (result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) { result.isReferenced = true; } if (!result) { @@ -20280,7 +20284,7 @@ var ts; error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol)); return true; } - if (location === container && !(ts.getModifierFlags(location) & 32)) { + if (location === container && !ts.hasModifier(location, 32)) { var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -21020,6 +21024,10 @@ var ts; } return false; } + function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) { + var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064, false); + return access.accessibility === 0; + } function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) { if (symbol && enclosingDeclaration && !(symbol.flags & 262144)) { var initialSymbol = symbol; @@ -21075,7 +21083,7 @@ var ts; if (!isDeclarationVisible(declaration)) { var anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(ts.getModifierFlags(anyImportSyntax) & 1) && + !ts.hasModifier(anyImportSyntax, 1) && isDeclarationVisible(anyImportSyntax.parent)) { if (shouldComputeAliasToMakeVisible) { getNodeLinks(declaration).isVisible = true; @@ -21273,8 +21281,7 @@ var ts; var name = symbolToName(type.symbol, context, 793064, false); return ts.createTypeReferenceNode(name, undefined); } - if (!inTypeAlias && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, 793064, false).accessibility === 0) { + if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { var name = symbolToTypeReferenceName(type.aliasSymbol); var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return ts.createTypeReferenceNode(name, typeArgumentNodes); @@ -21349,8 +21356,8 @@ var ts; return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192) && + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16) && (symbol.parent || ts.forEach(symbol.declarations, function (declaration) { @@ -21362,10 +21369,8 @@ var ts; } } function createTypeNodeFromObjectType(type) { - if (type.objectFlags & 32) { - if (getConstraintTypeFromMappedType(type).flags & (16384 | 262144)) { - return createMappedTypeNodeFromType(type); - } + if (isGenericMappedType(type)) { + return createMappedTypeNodeFromType(type); } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -21893,7 +21898,7 @@ var ts; buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064, 0, nextFlags); } else if (!(flags & 1024) && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, 793064, false).accessibility === 0) { + ((flags & 65536) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { var typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags); } @@ -22037,9 +22042,7 @@ var ts; if (!symbolStack) { symbolStack = []; } - var isConstructorObject = type.flags & 32768 && - getObjectFlags(type) & 16 && - type.symbol && type.symbol.flags & 32; + var isConstructorObject = type.objectFlags & 16 && type.symbol && type.symbol.flags & 32; if (isConstructorObject) { writeLiteralType(type, flags); } @@ -22054,16 +22057,16 @@ var ts; writeLiteralType(type, flags); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192) && + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16) && (symbol.parent || - ts.forEach(symbol.declarations, function (declaration) { + ts.some(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 || declaration.parent.kind === 234; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { return !!(flags & 4) || - (ts.contains(symbolStack, symbol)); + ts.contains(symbolStack, symbol); } } } @@ -22100,11 +22103,9 @@ var ts; return false; } function writeLiteralType(type, flags) { - if (type.objectFlags & 32) { - if (getConstraintTypeFromMappedType(type).flags & (16384 | 262144)) { - writeMappedType(type); - return; - } + if (isGenericMappedType(type)) { + writeMappedType(type); + return; } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -22472,7 +22473,7 @@ var ts; case 154: case 151: case 150: - if (ts.getModifierFlags(node) & (8 | 16)) { + if (ts.hasModifier(node, 8 | 16)) { return false; } case 152: @@ -23149,8 +23150,8 @@ var ts; } } function appendTypeParameters(typeParameters, declarations) { - for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { - var declaration = declarations_3[_i]; + for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { + var declaration = declarations_2[_i]; var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); if (!typeParameters) { typeParameters = [tp]; @@ -23419,7 +23420,9 @@ var ts; if (!pushTypeResolution(symbol, 2)) { return unknownType; } - var declaration = ts.findDeclaration(symbol, function (d) { return d.kind === 283 || d.kind === 231; }); + var declaration = ts.find(symbol.declarations, function (d) { + return d.kind === 283 || d.kind === 231; + }); var type = getTypeFromTypeNode(declaration.kind === 283 ? declaration.typeExpression : declaration.type); if (popTypeResolution()) { var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -24018,8 +24021,7 @@ var ts; return getObjectFlags(type) & 32 && !!type.declaration.questionToken; } function isGenericMappedType(type) { - return getObjectFlags(type) & 32 && - maybeTypeOfKind(getConstraintTypeFromMappedType(type), 540672 | 262144); + return getObjectFlags(type) & 32 && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type) { if (!type.members) { @@ -24119,6 +24121,10 @@ var ts; return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } function getConstraintOfIndexedAccess(type) { + var transformed = getTransformedIndexedAccessType(type); + if (transformed) { + return transformed; + } var baseObjectType = getBaseConstraintOfType(type.objectType); var baseIndexType = getBaseConstraintOfType(type.indexType); return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; @@ -24181,11 +24187,18 @@ var ts; return stringType; } if (t.flags & 524288) { + var transformed = getTransformedIndexedAccessType(t); + if (transformed) { + return getBaseConstraint(transformed); + } var baseObjectType = getBaseConstraint(t.objectType); var baseIndexType = getBaseConstraint(t.indexType); var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (isGenericMappedType(t)) { + return emptyObjectType; + } return t; } } @@ -24733,7 +24746,7 @@ var ts; function getIndexInfoOfSymbol(symbol, kind) { var declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, (ts.getModifierFlags(declaration) & 64) !== 0, declaration); + return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64), declaration); } return undefined; } @@ -25001,8 +25014,8 @@ var ts; function getTypeOfGlobalSymbol(symbol, arity) { function getTypeDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { - var declaration = declarations_4[_i]; + for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { + var declaration = declarations_3[_i]; switch (declaration.kind) { case 229: case 230: @@ -25459,11 +25472,11 @@ var ts; return getTypeOfSymbol(prop); } } - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 262178 | 84 | 512)) { + if (!(indexType.flags & 6144) && isTypeAssignableToKind(indexType, 262178 | 84 | 512)) { if (isTypeAny(objectType)) { return anyType; } - var indexInfo = isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84) && getIndexInfoOfType(objectType, 1) || + var indexInfo = isTypeAssignableToKind(indexType, 84) && getIndexInfoOfType(objectType, 1) || getIndexInfoOfType(objectType, 0) || undefined; if (indexInfo) { @@ -25501,25 +25514,69 @@ var ts; return anyType; } function getIndexedAccessForMappedType(type, indexType, accessNode) { - var accessExpression = accessNode && accessNode.kind === 180 ? accessNode : undefined; - if (accessExpression && ts.isAssignmentTarget(accessExpression) && type.declaration.readonlyToken) { - error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); - return unknownType; + if (accessNode) { + if (!isTypeAssignableTo(indexType, getIndexType(type))) { + error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(type)); + return unknownType; + } + if (accessNode.kind === 180 && ts.isAssignmentTarget(accessNode) && type.declaration.readonlyToken) { + error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); + return unknownType; + } } var mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]); var templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; return instantiateType(getTemplateTypeFromMappedType(type), templateMapper); } + function isGenericObjectType(type) { + return type.flags & 540672 ? true : + getObjectFlags(type) & 32 ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : + type.flags & 196608 ? ts.forEach(type.types, isGenericObjectType) : + false; + } + function isGenericIndexType(type) { + return type.flags & (540672 | 262144) ? true : + type.flags & 196608 ? ts.forEach(type.types, isGenericIndexType) : + false; + } + function isStringIndexOnlyType(type) { + if (type.flags & 32768 && !isGenericMappedType(type)) { + var t = resolveStructuredTypeMembers(type); + return t.properties.length === 0 && + t.callSignatures.length === 0 && t.constructSignatures.length === 0 && + t.stringIndexInfo && !t.numberIndexInfo; + } + return false; + } + function getTransformedIndexedAccessType(type) { + var objectType = type.objectType; + if (objectType.flags & 131072 && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) { + var regularTypes = []; + var stringIndexTypes = []; + for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, 0)); + } + else { + regularTypes.push(t); + } + } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + return undefined; + } function getIndexedAccessType(objectType, indexType, accessNode) { - if (maybeTypeOfKind(indexType, 540672 | 262144) || - maybeTypeOfKind(objectType, 540672) && !(accessNode && accessNode.kind === 180) || - isGenericMappedType(objectType)) { + if (isGenericMappedType(objectType)) { + return getIndexedAccessForMappedType(objectType, indexType, accessNode); + } + if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180) && isGenericObjectType(objectType)) { if (objectType.flags & 1) { return objectType; } - if (isGenericMappedType(objectType)) { - return getIndexedAccessForMappedType(objectType, indexType, accessNode); - } var id = objectType.id + "," + indexType.id; var type = indexedAccessTypes.get(id); if (!type) { @@ -25718,7 +25775,7 @@ var ts; var container = ts.getThisContainer(node, false); var parent = container && container.parent; if (parent && (ts.isClassLike(parent) || parent.kind === 230)) { - if (!(ts.getModifierFlags(container) & 32) && + if (!ts.hasModifier(container, 32) && (container.kind !== 152 || ts.isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } @@ -25865,7 +25922,7 @@ var ts; } function cloneTypeMapper(mapper) { return mapper && isInferenceContext(mapper) ? - createInferenceContext(mapper.signature, mapper.flags | 2, mapper.inferences) : + createInferenceContext(mapper.signature, mapper.flags | 2, mapper.compareTypes, mapper.inferences) : mapper; } function identityMapper(type) { @@ -26129,11 +26186,13 @@ var ts; if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) { return true; } - if (node.kind === 187) { - return false; + if (node.kind !== 187) { + var parameter = ts.firstOrUndefined(node.parameters); + if (!(parameter && ts.parameterIsThisKeyword(parameter))) { + return true; + } } - var parameter = ts.firstOrUndefined(node.parameters); - return !(parameter && ts.parameterIsThisKeyword(parameter)); + return node.body.kind === 207 ? false : isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func) { return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); @@ -26196,7 +26255,7 @@ var ts; return 0; } if (source.typeParameters) { - source = instantiateSignatureInContextOf(source, target); + source = instantiateSignatureInContextOf(source, target, undefined, compareTypes); } var result = -1; var sourceThisType = getThisTypeOfSignature(source); @@ -26245,7 +26304,7 @@ var ts; var sourceReturnType = getReturnTypeOfSignature(source); if (target.typePredicate) { if (source.typePredicate) { - result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes); + result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes); } else if (ts.isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { @@ -26261,7 +26320,7 @@ var ts; } return result; } - function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) { + function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) { if (source.kind !== target.kind) { if (reportErrors) { errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); @@ -26270,11 +26329,13 @@ var ts; return 0; } if (source.kind === 1) { - var sourceIdentifierPredicate = source; - var targetIdentifierPredicate = target; - if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + var sourcePredicate = source; + var targetPredicate = target; + var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0); + var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0); + if (sourceIndex !== targetIndex) { if (reportErrors) { - errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0; @@ -26533,11 +26594,21 @@ var ts; !(target.flags & 65536) && !isIntersectionConstituent && source !== globalObjectType && - getPropertiesOfType(source).length > 0 && + (getPropertiesOfType(source).length > 0 || + getSignaturesOfType(source, 0).length > 0 || + getSignaturesOfType(source, 1).length > 0) && isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { - reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + var calls = getSignaturesOfType(source, 0); + var constructs = getSignaturesOfType(source, 1); + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, false)) { + reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target)); + } + else { + reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + } } return 0; } @@ -27158,6 +27229,9 @@ var ts; if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } + if (isGenericMappedType(source)) { + return kind === 0 && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); + } if (isObjectLiteralType(source)) { var related = -1; if (kind === 0) { @@ -27191,8 +27265,8 @@ var ts; if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } - var sourceAccessibility = ts.getModifierFlags(sourceSignature.declaration) & 24; - var targetAccessibility = ts.getModifierFlags(targetSignature.declaration) & 24; + var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24); + var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24); if (targetAccessibility === 8) { return true; } @@ -27244,7 +27318,7 @@ var ts; var symbol = type.symbol; if (symbol && symbol.flags & 32) { var declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && ts.getModifierFlags(declaration) & 128) { + if (declaration && ts.hasModifier(declaration, 128)) { return true; } } @@ -27630,13 +27704,14 @@ var ts; callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } } - function createInferenceContext(signature, flags, baseInferences) { + function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; + context.compareTypes = compareTypes || compareTypesAssignable; return context; function mapper(t) { for (var i = 0; i < inferences.length; i++) { @@ -27724,6 +27799,19 @@ var ts; return inference.candidates && getUnionType(inference.candidates, true); } } + function isPossiblyAssignableTo(source, target) { + var properties = getPropertiesOfObjectType(target); + for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { + var targetProp = properties_5[_i]; + if (!(targetProp.flags & (16777216 | 4194304))) { + var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); + if (!sourceProp) { + return false; + } + } + } + return true; + } function inferTypes(inferences, originalSource, originalTarget, priority) { if (priority === void 0) { priority = 0; } var symbolStack; @@ -27884,15 +27972,17 @@ var ts; return; } } - inferFromProperties(source, target); - inferFromSignatures(source, target, 0); - inferFromSignatures(source, target, 1); - inferFromIndexTypes(source, target); + if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) { + inferFromProperties(source, target); + inferFromSignatures(source, target, 0); + inferFromSignatures(source, target, 1); + inferFromIndexTypes(source, target); + } } function inferFromProperties(source, target) { var properties = getPropertiesOfObjectType(target); - for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { - var targetProp = properties_5[_i]; + for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { + var targetProp = properties_6[_i]; var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); if (sourceProp) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); @@ -27991,7 +28081,7 @@ var ts; var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); if (constraint) { var instantiatedConstraint = instantiateType(constraint, context); - if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } @@ -28039,16 +28129,6 @@ var ts; } return undefined; } - function getLeftmostIdentifierOrThis(node) { - switch (node.kind) { - case 71: - case 99: - return node; - case 179: - return getLeftmostIdentifierOrThis(node.expression); - } - return undefined; - } function getBindingElementNameText(element) { if (element.parent.kind === 174) { var name = element.propertyName || element.name; @@ -28540,7 +28620,7 @@ var ts; parent.parent.operatorToken.kind === 58 && parent.parent.left === parent && !ts.isAssignmentTarget(parent.parent) && - isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression(parent.argumentExpression), 84 | 2048); + isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84); return isLengthPushOrUnshift || isElementAssignment; } function maybeTypePredicateCall(node) { @@ -28686,7 +28766,7 @@ var ts; } else { var indexType = getTypeOfExpression(node.left.argumentExpression); - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 | 2048)) { + if (isTypeAssignableToKind(indexType, 84)) { evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right); } } @@ -29372,7 +29452,7 @@ var ts; break; case 149: case 148: - if (ts.getModifierFlags(container) & 32) { + if (ts.hasModifier(container, 32)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); } break; @@ -29463,14 +29543,14 @@ var ts; if (!isCallExpression && container.kind === 152) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if ((ts.getModifierFlags(container) & 32) || isCallExpression) { + if (ts.hasModifier(container, 32) || isCallExpression) { nodeCheckFlag = 512; } else { nodeCheckFlag = 256; } getNodeLinks(node).flags |= nodeCheckFlag; - if (container.kind === 151 && ts.getModifierFlags(container) & 256) { + if (container.kind === 151 && ts.hasModifier(container, 256)) { if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= 4096; } @@ -29515,7 +29595,7 @@ var ts; } else { if (ts.isClassLike(container.parent) || container.parent.kind === 178) { - if (ts.getModifierFlags(container) & 32) { + if (ts.hasModifier(container, 32)) { return container.kind === 151 || container.kind === 150 || container.kind === 153 || @@ -30041,10 +30121,7 @@ var ts; } } function isNumericComputedName(name) { - return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), 84); - } - function isTypeAnyOrAllConstituentTypesHaveKind(type, kind) { - return isTypeAny(type) || isTypeOfKind(type, kind); + return isTypeAssignableToKind(checkComputedPropertyName(name), 84); } function isInfinityOrNaNString(name) { return name === "Infinity" || name === "-Infinity" || name === "NaN"; @@ -30056,7 +30133,9 @@ var ts; var links = getNodeLinks(node.expression); if (!links.resolvedType) { links.resolvedType = checkExpression(node.expression); - if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 84 | 262178 | 512)) { + if (links.resolvedType.flags & 6144 || + !isTypeAssignableToKind(links.resolvedType, 262178 | 84 | 512) && + !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -30541,9 +30620,7 @@ var ts; return undefined; } function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) { - if (!elementType) { - elementType = checkExpression(openingLikeElement.tagName); - } + if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); } if (elementType.flags & 65536) { var types = elementType.types; return getUnionType(types.map(function (type) { @@ -30638,11 +30715,12 @@ var ts; } function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) { var links = getNodeLinks(node); - if (!links.resolvedJsxElementAttributesType) { + var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { var elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); } - return links.resolvedJsxElementAttributesType; + return links[linkLocation]; } function getAllAttributesTypeFromJsxOpeningLikeElement(node) { if (isJsxIntrinsicIdentifier(node.tagName)) { @@ -30998,7 +31076,7 @@ var ts; if (prop && noUnusedIdentifiers && (prop.flags & 106500) && - prop.valueDeclaration && (ts.getModifierFlags(prop.valueDeclaration) & 8)) { + prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8)) { if (ts.getCheckFlags(prop) & 1) { getSymbolLinks(prop).target.isReferenced = true; } @@ -31269,8 +31347,8 @@ var ts; } return undefined; } - function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper) { - var context = createInferenceContext(signature, 1); + function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) { + var context = createInferenceContext(signature, 1, compareTypes); forEachMatchingParameterType(contextualSignature, signature, function (source, target) { inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); }); @@ -31500,7 +31578,7 @@ var ts; return getLiteralType(element.name.text); case 144: var nameType = checkComputedPropertyName(element.name); - if (isTypeOfKind(nameType, 512)) { + if (isTypeAssignableToKind(nameType, 512)) { return nameType; } else { @@ -31593,9 +31671,10 @@ var ts; return resolveErrorCall(node); } var args = getEffectiveCallArguments(node); + var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; var excludeArgument; var excludeCount = 0; - if (!isDecorator) { + if (!isDecorator && !isSingleNonGenericCandidate) { for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { if (isContextSensitive(args[i])) { if (!excludeArgument) { @@ -31687,6 +31766,17 @@ var ts; if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; + if (isSingleNonGenericCandidate) { + var candidate = candidates[0]; + if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + return undefined; + } + if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, false)) { + candidateForArgumentError = candidate; + return undefined; + } + return candidate; + } for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { var originalCandidate = candidates[candidateIndex]; if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { @@ -31817,7 +31907,7 @@ var ts; return resolveErrorCall(node); } var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && ts.getModifierFlags(valueDecl) & 128) { + if (valueDecl && ts.hasModifier(valueDecl, 128)) { error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -31853,8 +31943,8 @@ var ts; return true; } var declaration = signature.declaration; - var modifiers = ts.getModifierFlags(declaration); - if (!(modifiers & 24)) { + var modifiers = ts.getSelectedModifierFlags(declaration, 24); + if (!modifiers) { return true; } var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); @@ -32057,11 +32147,33 @@ var ts; if (moduleSymbol) { var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); } } return createPromiseReturnType(node, anyType); } + function getTypeWithSyntheticDefaultImportType(type, symbol) { + if (allowSyntheticDefaultImports && type && type !== unknownType) { + var synthType = type; + if (!synthType.syntheticType) { + if (!getPropertyOfType(type, "default")) { + var memberTable = ts.createSymbolTable(); + var newSymbol = createSymbol(2097152, "default"); + newSymbol.target = resolveSymbol(symbol); + memberTable.set("default", newSymbol); + var anonymousSymbol = createSymbol(2048, "__type"); + var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, undefined, undefined); + anonymousSymbol.type = defaultContainingObject; + synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + } + else { + synthType.syntheticType = type; + } + } + return synthType.syntheticType; + } + return type; + } function isCommonJsRequire(node) { if (!ts.isRequireCall(node, true)) { return false; @@ -32180,15 +32292,15 @@ var ts; } } } - function assignBindingElementTypes(node) { - if (ts.isBindingPattern(node.name)) { - for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) { - var element = _a[_i]; - if (!ts.isOmittedExpression(element)) { - if (element.name.kind === 71) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); - } - assignBindingElementTypes(element); + function assignBindingElementTypes(pattern) { + for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (!ts.isOmittedExpression(element)) { + if (element.name.kind === 71) { + getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + } + else { + assignBindingElementTypes(element.name); } } } @@ -32197,12 +32309,13 @@ var ts; var links = getSymbolLinks(parameter); if (!links.type) { links.type = contextualType; - var name = ts.getNameOfDeclaration(parameter.valueDeclaration); - if (links.type === emptyObjectType && - (name.kind === 174 || name.kind === 175)) { - links.type = getTypeFromBindingPattern(name); + var decl = parameter.valueDeclaration; + if (decl.name.kind !== 71) { + if (links.type === emptyObjectType) { + links.type = getTypeFromBindingPattern(decl.name); + } + assignBindingElementTypes(decl.name); } - assignBindingElementTypes(parameter.valueDeclaration); } } function createPromiseType(promisedType) { @@ -32403,14 +32516,14 @@ var ts; } function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) { ts.Debug.assert(node.kind !== 151 || ts.isObjectLiteralMethod(node)); - var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); - if (!hasGrammarError && node.kind === 186) { - checkGrammarForGenerator(node); - } if (checkMode === 1 && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } + var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); + if (!hasGrammarError && node.kind === 186) { + checkGrammarForGenerator(node); + } var links = getNodeLinks(node); var type = getTypeOfSymbol(node.symbol); if (!(links.flags & 1024)) { @@ -32480,7 +32593,7 @@ var ts; } } function checkArithmeticOperandType(operand, type, diagnostic) { - if (!isTypeAnyOrAllConstituentTypesHaveKind(type, 84)) { + if (!isTypeAssignableToKind(type, 84)) { error(operand, diagnostic); return false; } @@ -32568,8 +32681,13 @@ var ts; if (operandType === silentNeverType) { return silentNeverType; } - if (node.operator === 38 && node.operand.kind === 8) { - return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + if (node.operand.kind === 8) { + if (node.operator === 38) { + return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + } + else if (node.operator === 37) { + return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text)); + } } switch (node.operator) { case 37: @@ -32621,30 +32739,22 @@ var ts; } return false; } - function isTypeOfKind(type, kind) { - if (type.flags & kind) { + function isTypeAssignableToKind(source, kind, strict) { + if (source.flags & kind) { return true; } - if (type.flags & 65536) { - var types = type.types; - for (var _i = 0, types_18 = types; _i < types_18.length; _i++) { - var t = types_18[_i]; - if (!isTypeOfKind(t, kind)) { - return false; - } - } - return true; - } - if (type.flags & 131072) { - var types = type.types; - for (var _a = 0, types_19 = types; _a < types_19.length; _a++) { - var t = types_19[_a]; - if (isTypeOfKind(t, kind)) { - return true; - } - } + if (strict && source.flags & (1 | 1024 | 2048 | 4096)) { + return false; } - return false; + return (kind & 84 && isTypeAssignableTo(source, numberType)) || + (kind & 262178 && isTypeAssignableTo(source, stringType)) || + (kind & 136 && isTypeAssignableTo(source, booleanType)) || + (kind & 1024 && isTypeAssignableTo(source, voidType)) || + (kind & 8192 && isTypeAssignableTo(source, neverType)) || + (kind & 4096 && isTypeAssignableTo(source, nullType)) || + (kind & 2048 && isTypeAssignableTo(source, undefinedType)) || + (kind & 512 && isTypeAssignableTo(source, esSymbolType)) || + (kind & 16777216 && isTypeAssignableTo(source, nonPrimitiveType)); } function isConstEnumObjectType(type) { return getObjectFlags(type) & 16 && type.symbol && isConstEnumSymbol(type.symbol); @@ -32656,7 +32766,7 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (isTypeOfKind(leftType, 8190)) { + if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190)) { error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } if (!(isTypeAny(rightType) || @@ -32673,18 +32783,18 @@ var ts; } leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); - if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, 84 | 512))) { + if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 | 512))) { error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 | 540672 | 16777216)) { + if (!isTypeAssignableToKind(rightType, 16777216 | 540672)) { error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; } function checkObjectLiteralAssignment(node, sourceType) { var properties = node.properties; - for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { - var p = properties_6[_i]; + for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) { + var p = properties_7[_i]; checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties); } return sourceType; @@ -32940,24 +33050,22 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (!isTypeOfKind(leftType, 1 | 262178) && !isTypeOfKind(rightType, 1 | 262178)) { + if (!isTypeAssignableToKind(leftType, 262178) && !isTypeAssignableToKind(rightType, 262178)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } var resultType = void 0; - if (isTypeOfKind(leftType, 84) && isTypeOfKind(rightType, 84)) { + if (isTypeAssignableToKind(leftType, 84, true) && isTypeAssignableToKind(rightType, 84, true)) { resultType = numberType; } - else { - if (isTypeOfKind(leftType, 262178) || isTypeOfKind(rightType, 262178)) { - resultType = stringType; - } - else if (isTypeAny(leftType) || isTypeAny(rightType)) { - resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; - } - if (resultType && !checkForDisallowedESSymbolOperand(operator)) { - return resultType; - } + else if (isTypeAssignableToKind(leftType, 262178, true) || isTypeAssignableToKind(rightType, 262178, true)) { + resultType = stringType; + } + else if (isTypeAny(leftType) || isTypeAny(rightType)) { + resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; + } + if (resultType && !checkForDisallowedESSymbolOperand(operator)) { + return resultType; } if (!resultType) { reportOperatorError(); @@ -33122,13 +33230,12 @@ var ts; return getBestChoiceType(type1, type2); } function checkLiteralExpression(node) { - if (node.kind === 8) { - checkGrammarNumericLiteral(node); - } switch (node.kind) { + case 13: case 9: return getFreshTypeOfLiteralType(getLiteralType(node.text)); case 8: + checkGrammarNumericLiteral(node); return getFreshTypeOfLiteralType(getLiteralType(+node.text)); case 101: return trueType; @@ -33276,6 +33383,7 @@ var ts; return checkSuperExpression(node); case 95: return nullWideningType; + case 13: case 9: case 8: case 101: @@ -33283,8 +33391,6 @@ var ts; return checkLiteralExpression(node); case 196: return checkTemplateExpression(node); - case 13: - return stringType; case 12: return globalRegExpType; case 177: @@ -33375,7 +33481,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); checkVariableLikeDeclaration(node); var func = ts.getContainingFunction(node); - if (ts.getModifierFlags(node) & 92) { + if (ts.hasModifier(node, 92)) { func = ts.getContainingFunction(node); if (!(func.kind === 152 && ts.nodeIsPresent(func.body))) { error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -33565,7 +33671,7 @@ var ts; } } else { - var isStatic = ts.getModifierFlags(member) & 32; + var isStatic = ts.hasModifier(member, 32); var names = isStatic ? staticNames : instanceNames; var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); if (memberName) { @@ -33610,7 +33716,7 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var memberNameNode = member.name; - var isStatic = ts.getModifierFlags(member) & 32; + var isStatic = ts.hasModifier(member, 32); if (isStatic && memberNameNode) { var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -33698,7 +33804,7 @@ var ts; function checkMethodDeclaration(node) { checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name); checkFunctionOrMethodDeclaration(node); - if (ts.getModifierFlags(node) & 128 && node.body) { + if (ts.hasModifier(node, 128) && node.body) { error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } @@ -33734,17 +33840,9 @@ var ts; } return ts.forEachChild(n, containsSuperCall); } - function markThisReferencesAsErrors(n) { - if (n.kind === 99) { - error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location); - } - else if (n.kind !== 186 && n.kind !== 228) { - ts.forEachChild(n, markThisReferencesAsErrors); - } - } function isInstancePropertyWithInitializer(n) { return n.kind === 149 && - !(ts.getModifierFlags(n) & 32) && + !ts.hasModifier(n, 32) && !!n.initializer; } var containingClassDecl = node.parent; @@ -33756,8 +33854,8 @@ var ts; if (classExtendsNull) { error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } - var superCallShouldBeFirst = ts.forEach(node.parent.members, isInstancePropertyWithInitializer) || - ts.forEach(node.parameters, function (p) { return ts.getModifierFlags(p) & 92; }); + var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) || + ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92); }); if (superCallShouldBeFirst) { var statements = node.body.statements; var superCallStatement = void 0; @@ -33800,10 +33898,12 @@ var ts; var otherKind = node.kind === 153 ? 154 : 153; var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if ((ts.getModifierFlags(node) & 28) !== (ts.getModifierFlags(otherAccessor) & 28)) { + var nodeFlags = ts.getModifierFlags(node); + var otherFlags = ts.getModifierFlags(otherAccessor); + if ((nodeFlags & 28) !== (otherFlags & 28)) { error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (ts.hasModifier(node, 128) !== ts.hasModifier(otherAccessor, 128)) { + if ((nodeFlags & 128) !== (otherFlags & 128)) { error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type); @@ -33857,7 +33957,14 @@ var ts; ts.forEach(node.typeArguments, checkSourceElement); if (produceDiagnostics) { var symbol = getNodeLinks(node).resolvedSymbol; - var typeParameters = symbol.flags & 524288 ? getSymbolLinks(symbol).typeParameters : type.target.localTypeParameters; + if (!symbol) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return; + } + var typeParameters = symbol.flags & 524288 && getSymbolLinks(symbol).typeParameters; + if (!typeParameters && getObjectFlags(type) & 4) { + typeParameters = type.target.localTypeParameters; + } checkTypeArgumentConstraints(typeParameters, node.typeArguments); } } @@ -33900,7 +34007,7 @@ var ts; if (isTypeAssignableTo(indexType, getIndexType(objectType))) { return type; } - if (maybeTypeOfKind(objectType, 540672) && isTypeOfKind(indexType, 84)) { + if (maybeTypeOfKind(objectType, 540672) && isTypeAssignableToKind(indexType, 84)) { var constraint = getBaseConstraintOfType(objectType); if (constraint && getIndexInfoOfType(constraint, 1)) { return type; @@ -33910,6 +34017,8 @@ var ts; return type; } function checkIndexedAccessType(node) { + checkSourceElement(node.objectType); + checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } function checkMappedType(node) { @@ -33920,7 +34029,7 @@ var ts; checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); } function isPrivateWithinAmbient(node) { - return (ts.getModifierFlags(node) & 8) && ts.isInAmbientContext(node); + return ts.hasModifier(node, 8) && ts.isInAmbientContext(node); } function getEffectiveDeclarationFlags(n, flagsToCheck) { var flags = ts.getCombinedModifierFlags(n); @@ -34007,9 +34116,9 @@ var ts; (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { var reportError = (node.kind === 151 || node.kind === 150) && - (ts.getModifierFlags(node) & 32) !== (ts.getModifierFlags(subsequentNode) & 32); + ts.hasModifier(node, 32) !== ts.hasModifier(subsequentNode, 32); if (reportError) { - var diagnostic = ts.getModifierFlags(node) & 32 ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; + var diagnostic = ts.hasModifier(node, 32) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode_1, diagnostic); } return; @@ -34025,7 +34134,7 @@ var ts; error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing); } else { - if (ts.getModifierFlags(node) & 128) { + if (ts.hasModifier(node, 128)) { error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -34035,8 +34144,8 @@ var ts; } var duplicateFunctionDeclaration = false; var multipleConstructorImplementation = false; - for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { - var current = declarations_5[_i]; + for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { + var current = declarations_4[_i]; var node = current; var inAmbientContext = ts.isInAmbientContext(node); var inAmbientContextOrInterface = node.parent.kind === 230 || node.parent.kind === 163 || inAmbientContext; @@ -34085,7 +34194,7 @@ var ts; }); } if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(ts.getModifierFlags(lastSeenNonAmbientDeclaration) & 128) && !lastSeenNonAmbientDeclaration.questionToken) { + !ts.hasModifier(lastSeenNonAmbientDeclaration, 128) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } if (hasOverloads) { @@ -34629,14 +34738,14 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 151 || member.kind === 149) { - if (!member.symbol.isReferenced && ts.getModifierFlags(member) & 8) { + if (!member.symbol.isReferenced && ts.hasModifier(member, 8)) { error(member.name, ts.Diagnostics._0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(member.symbol.escapedName)); } } else if (member.kind === 152) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; - if (!parameter.symbol.isReferenced && ts.getModifierFlags(parameter) & 8) { + if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8)) { error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(parameter.symbol.escapedName)); } } @@ -34976,7 +35085,7 @@ var ts; 128 | 64 | 32; - return (ts.getModifierFlags(left) & interestingFlags) === (ts.getModifierFlags(right) & interestingFlags); + return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); @@ -35106,7 +35215,7 @@ var ts; checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access); } } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 | 540672 | 16777216)) { + if (!isTypeAssignableToKind(rightType, 16777216 | 540672)) { error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } checkSourceElement(node.statement); @@ -35478,7 +35587,7 @@ var ts; var classDeclaration = type.symbol.valueDeclaration; for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) { var member = _a[_i]; - if (!(ts.getModifierFlags(member) & 32) && ts.hasDynamicName(member)) { + if (!ts.hasModifier(member, 32) && ts.hasDynamicName(member)) { var propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1); @@ -35575,8 +35684,8 @@ var ts; var type = getDeclaredTypeOfSymbol(symbol); if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) { var name = symbolToString(symbol); - for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { - var declaration = declarations_6[_i]; + for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { + var declaration = declarations_5[_i]; error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } @@ -35585,8 +35694,8 @@ var ts; function areTypeParametersIdentical(declarations, typeParameters) { var maxTypeArgumentCount = ts.length(typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { - var declaration = declarations_7[_i]; + for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { + var declaration = declarations_6[_i]; var numTypeParameters = ts.length(declaration.typeParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { return false; @@ -35622,7 +35731,7 @@ var ts; registerForUnusedIdentifiersCheck(node); } function checkClassDeclaration(node) { - if (!node.name && !(ts.getModifierFlags(node) & 512)) { + if (!node.name && !ts.hasModifier(node, 512)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -35715,7 +35824,7 @@ var ts; var signatures = getSignaturesOfType(type, 1); if (signatures.length) { var declaration = signatures[0].declaration; - if (declaration && ts.getModifierFlags(declaration) & 8) { + if (declaration && ts.hasModifier(declaration, 8)) { var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); @@ -35748,7 +35857,7 @@ var ts; if (derived) { if (derived === base) { var derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol); - if (baseDeclarationFlags & 128 && (!derivedClassDecl || !(ts.getModifierFlags(derivedClassDecl) & 128))) { + if (baseDeclarationFlags & 128 && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128))) { if (derivedClassDecl.kind === 199) { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } @@ -35796,8 +35905,8 @@ var ts; for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) { var base = baseTypes_2[_i]; var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); - for (var _a = 0, properties_7 = properties; _a < properties_7.length; _a++) { - var prop = properties_7[_a]; + for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) { + var prop = properties_8[_a]; var existing = seen.get(prop.escapedName); if (!existing) { seen.set(prop.escapedName, { prop: prop, containingType: base }); @@ -36051,8 +36160,8 @@ var ts; } function getFirstNonAmbientClassOrFunctionDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { - var declaration = declarations_8[_i]; + for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { + var declaration = declarations_7[_i]; if ((declaration.kind === 229 || (declaration.kind === 228 && ts.nodeIsPresent(declaration.body))) && !ts.isInAmbientContext(declaration)) { @@ -36267,7 +36376,7 @@ var ts; if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -36294,7 +36403,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (ts.getModifierFlags(node) & 1) { + if (ts.hasModifier(node, 1)) { markExportAsReferenced(node); } if (ts.isInternalModuleImportEqualsDeclaration(node)) { @@ -36322,7 +36431,7 @@ var ts; if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { @@ -36380,7 +36489,7 @@ var ts; } return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === 71) { @@ -36427,8 +36536,8 @@ var ts; return; } if (exportedDeclarationsCount > 1) { - for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { - var declaration = declarations_9[_i]; + for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { + var declaration = declarations_8[_i]; if (isNotOverload(declaration)) { diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } @@ -36706,7 +36815,7 @@ var ts; return []; } var symbols = ts.createSymbolTable(); - var memberFlags = 0; + var isStatic = false; populateSymbols(); return symbolsToArray(symbols); function populateSymbols() { @@ -36728,7 +36837,7 @@ var ts; } case 229: case 230: - if (!(memberFlags & 32)) { + if (!isStatic) { copySymbols(getSymbolOfNode(location).members, meaning & 793064); } break; @@ -36742,7 +36851,7 @@ var ts; if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } - memberFlags = ts.getModifierFlags(location); + isStatic = ts.hasModifier(location, 32); location = location.parent; } copySymbols(globals, meaning); @@ -37078,7 +37187,7 @@ var ts; } function getParentTypeOfClassElement(node) { var classSymbol = getSymbolOfNode(node.parent); - return ts.getModifierFlags(node) & 32 + return ts.hasModifier(node, 32) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -37303,13 +37412,13 @@ var ts; return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && - !(ts.getModifierFlags(parameter) & 92); + !ts.hasModifier(parameter, 92); } function isOptionalUninitializedParameterProperty(parameter) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - !!(ts.getModifierFlags(parameter) & 92); + ts.hasModifier(parameter, 92); } function getNodeCheckFlags(node) { return getNodeLinks(node).flags; @@ -37365,22 +37474,22 @@ var ts; else if (type.flags & 1) { return ts.TypeReferenceSerializationKind.ObjectType; } - else if (isTypeOfKind(type, 1024 | 6144 | 8192)) { + else if (isTypeAssignableToKind(type, 1024 | 6144 | 8192)) { return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } - else if (isTypeOfKind(type, 136)) { + else if (isTypeAssignableToKind(type, 136)) { return ts.TypeReferenceSerializationKind.BooleanType; } - else if (isTypeOfKind(type, 84)) { + else if (isTypeAssignableToKind(type, 84)) { return ts.TypeReferenceSerializationKind.NumberLikeType; } - else if (isTypeOfKind(type, 262178)) { + else if (isTypeAssignableToKind(type, 262178)) { return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } - else if (isTypeOfKind(type, 512)) { + else if (isTypeAssignableToKind(type, 512)) { return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { @@ -37845,7 +37954,7 @@ var ts; node.kind !== 154) { return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === 229 && ts.getModifierFlags(node.parent) & 128)) { + if (!(node.parent.kind === 229 && ts.hasModifier(node.parent, 128))) { return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & 32) { @@ -38041,7 +38150,7 @@ var ts; if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (ts.getModifierFlags(parameter) !== 0) { + if (ts.hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -38320,10 +38429,10 @@ var ts; else if (ts.isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(ts.getModifierFlags(accessor) & 128)) { + else if (accessor.body === undefined && !ts.hasModifier(accessor, 128)) { return grammarErrorAtPos(ts.getSourceFileOfNode(accessor), accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } - else if (accessor.body && ts.getModifierFlags(accessor) & 128) { + else if (accessor.body && ts.hasModifier(accessor, 128)) { return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { @@ -38632,7 +38741,7 @@ var ts; node.kind === 244 || node.kind === 243 || node.kind === 236 || - ts.getModifierFlags(node) & (2 | 1 | 512)) { + ts.hasModifier(node, 2 | 1 | 512)) { return false; } return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); @@ -41401,27 +41510,27 @@ var ts; function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) { var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; if (property === firstAccessor) { - var properties_8 = []; + var properties_9 = []; if (getAccessor) { var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, undefined, undefined, undefined, getAccessor.parameters, undefined, getAccessor.body); ts.setTextRange(getterFunction, getAccessor); ts.setOriginalNode(getterFunction, getAccessor); var getter = ts.createPropertyAssignment("get", getterFunction); - properties_8.push(getter); + properties_9.push(getter); } if (setAccessor) { var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, undefined, undefined, undefined, setAccessor.parameters, undefined, setAccessor.body); ts.setTextRange(setterFunction, setAccessor); ts.setOriginalNode(setterFunction, setAccessor); var setter = ts.createPropertyAssignment("set", setterFunction); - properties_8.push(setter); + properties_9.push(setter); } - properties_8.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); - properties_8.push(ts.createPropertyAssignment("configurable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue())); var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), undefined, [ receiver, createExpressionForPropertyName(property.name), - ts.createObjectLiteral(properties_8, multiLine) + ts.createObjectLiteral(properties_9, multiLine) ]), firstAccessor); return ts.aggregateTransformFlags(expression); } @@ -43361,7 +43470,8 @@ var ts; ? undefined : numElements, location), false, location); } - else if (numElements !== 1 && (flattenContext.level < 1 || numElements === 0)) { + else if (numElements !== 1 && (flattenContext.level < 1 || numElements === 0) + || ts.every(elements, ts.isOmittedExpression)) { var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } @@ -43568,7 +43678,12 @@ var ts; if (ts.hasModifier(node, 2)) { break; } - recordEmittedDeclarationInScope(node); + if (node.name) { + recordEmittedDeclarationInScope(node); + } + else { + ts.Debug.assert(node.kind === 229 || ts.hasModifier(node, 512)); + } break; } } @@ -43982,8 +44097,8 @@ var ts; && member.initializer !== undefined; } function addInitializedPropertyStatements(statements, properties, receiver) { - for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) { - var property = properties_9[_i]; + for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { + var property = properties_10[_i]; var statement = ts.createStatement(transformInitializedProperty(property, receiver)); ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); ts.setCommentRange(statement, property); @@ -43992,8 +44107,8 @@ var ts; } function generateInitializedPropertyExpressions(properties, receiver) { var expressions = []; - for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { - var property = properties_10[_i]; + for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { + var property = properties_11[_i]; var expression = transformInitializedProperty(property, receiver); expression.startsOnNewLine = true; ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); @@ -44688,24 +44803,24 @@ var ts; && moduleKind !== ts.ModuleKind.System); } function recordEmittedDeclarationInScope(node) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - if (!currentScopeFirstDeclarationsOfName) { - currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); - } - if (!currentScopeFirstDeclarationsOfName.has(name)) { - currentScopeFirstDeclarationsOfName.set(name, node); - } + if (!currentScopeFirstDeclarationsOfName) { + currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); + } + var name = declaredNameInScope(node); + if (!currentScopeFirstDeclarationsOfName.has(name)) { + currentScopeFirstDeclarationsOfName.set(name, node); } } function isFirstEmittedDeclarationInScope(node) { if (currentScopeFirstDeclarationsOfName) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - return currentScopeFirstDeclarationsOfName.get(name) === node; - } + var name = declaredNameInScope(node); + return currentScopeFirstDeclarationsOfName.get(name) === node; } - return false; + return true; + } + function declaredNameInScope(node) { + ts.Debug.assertNode(node.name, ts.isIdentifier); + return node.name.escapedText; } function addVarForEnumOrModuleDeclaration(statements, node) { var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([ @@ -44736,7 +44851,7 @@ var ts; if (!shouldEmitModuleDeclaration(node)) { return ts.createNotEmittedStatement(node); } - ts.Debug.assert(ts.isIdentifier(node.name), "TypeScript module should have an Identifier name."); + ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name."); enableSubstitutionForNamespaceExports(); var statements = []; var emitFlags = 2; @@ -45460,6 +45575,8 @@ var ts; return visitExpressionStatement(node); case 185: return visitParenthesizedExpression(node, noDestructuringValue); + case 260: + return visitCatchClause(node); default: return ts.visitEachChild(node, visitor, context); } @@ -45534,6 +45651,12 @@ var ts; function visitParenthesizedExpression(node, noDestructuringValue) { return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context); } + function visitCatchClause(node) { + if (!node.variableDeclaration) { + return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(undefined)), ts.visitNode(node.block, visitor, ts.isBlock)); + } + return ts.visitEachChild(node, visitor, context); + } function visitBinaryExpression(node, noDestructuringValue) { if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 1048576) { return ts.flattenDestructuringAssignment(node, visitor, context, 1, !noDestructuringValue); @@ -45980,7 +46103,7 @@ var ts; objectProperties = ts.createAssignHelper(context, segments); } } - var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.filter(ts.map(children, transformJsxChildToExpression), ts.isDefined), node, location); + var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } @@ -46567,7 +46690,7 @@ var ts; function shouldVisitNode(node) { return (node.transformFlags & 128) !== 0 || convertedLoopState !== undefined - || (hierarchyFacts & 4096 && ts.isStatement(node)) + || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207))) || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node)) || isTypeScriptClassWrapper(node); } @@ -46847,9 +46970,11 @@ var ts; var outer = ts.createPartiallyEmittedExpression(inner); outer.end = ts.skipTrivia(currentText, node.pos); ts.setEmitFlags(outer, 1536); - return ts.createParen(ts.createCall(outer, undefined, extendsClauseElement + var result = ts.createParen(ts.createCall(outer, undefined, extendsClauseElement ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)] : [])); + ts.addSyntheticLeadingComment(result, 3, "* @class "); + return result; } function transformClassBody(node, extendsClauseElement) { var statements = []; @@ -47434,11 +47559,12 @@ var ts; ts.setTextRange(declarationList, node); ts.setCommentRange(declarationList, node); if (node.transformFlags & 8388608 - && (ts.isBindingPattern(node.declarations[0].name) - || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { + && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { var firstDeclaration = ts.firstOrUndefined(declarations); - var lastDeclaration = ts.lastOrUndefined(declarations); - ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + if (firstDeclaration) { + var lastDeclaration = ts.lastOrUndefined(declarations); + ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + } } return declarationList; } @@ -47977,6 +48103,7 @@ var ts; function visitCatchClause(node) { var ancestorFacts = enterSubtree(4032, 0); var updated; + ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (ts.isBindingPattern(node.variableDeclaration.name)) { var temp = ts.createTempVariable(undefined); var newVariableDeclaration = ts.createVariableDeclaration(temp); @@ -49496,9 +49623,6 @@ var ts; var block = endBlock(); markLabel(block.endLabel); } - function isWithBlock(block) { - return block.kind === 1; - } function beginExceptionBlock() { var startLabel = defineLabel(); var endLabel = defineLabel(); @@ -49567,9 +49691,6 @@ var ts; emitNop(); exception.state = 3; } - function isExceptionBlock(block) { - return block.kind === 0; - } function beginScriptLoopBlock() { beginBlock({ kind: 3, @@ -49733,7 +49854,7 @@ var ts; return literal; } function createInlineBreak(label, location) { - ts.Debug.assert(label > 0, "Invalid label: " + label); + ts.Debug.assertLessThan(0, label, "Invalid label"); return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3), createLabel(label) @@ -49941,31 +50062,33 @@ var ts; for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { var block = blocks[blockIndex]; var blockAction = blockActions[blockIndex]; - if (isExceptionBlock(block)) { - if (blockAction === 0) { - if (!exceptionBlockStack) { - exceptionBlockStack = []; + switch (block.kind) { + case 0: + if (blockAction === 0) { + if (!exceptionBlockStack) { + exceptionBlockStack = []; + } + if (!statements) { + statements = []; + } + exceptionBlockStack.push(currentExceptionBlock); + currentExceptionBlock = block; } - if (!statements) { - statements = []; + else if (blockAction === 1) { + currentExceptionBlock = exceptionBlockStack.pop(); } - exceptionBlockStack.push(currentExceptionBlock); - currentExceptionBlock = block; - } - else if (blockAction === 1) { - currentExceptionBlock = exceptionBlockStack.pop(); - } - } - else if (isWithBlock(block)) { - if (blockAction === 0) { - if (!withBlockStack) { - withBlockStack = []; + break; + case 1: + if (blockAction === 0) { + if (!withBlockStack) { + withBlockStack = []; + } + withBlockStack.push(block); } - withBlockStack.push(block); - } - else if (blockAction === 1) { - withBlockStack.pop(); - } + else if (blockAction === 1) { + withBlockStack.pop(); + } + break; } } } @@ -53156,6 +53279,9 @@ var ts; return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); }); } function writeVariableStatement(node) { + if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) { + return; + } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isLet(node.declarationList)) { @@ -54121,14 +54247,14 @@ var ts; writer.writeLine(); } } - function emitTrailingCommentsOfPosition(pos) { + function emitTrailingCommentsOfPosition(pos, prefixSpace) { if (disabled) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeEmitTrailingCommentsOfPosition"); } - forEachTrailingCommentToEmit(pos, emitTrailingCommentOfPosition); + forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition); if (extendedDiagnostics) { ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); } @@ -54208,15 +54334,7 @@ var ts; emitPos(commentEnd); } function isTripleSlashComment(commentPos, commentEnd) { - if (currentText.charCodeAt(commentPos + 1) === 47 && - commentPos + 2 < commentEnd && - currentText.charCodeAt(commentPos + 2) === 47) { - var textSubStr = currentText.substring(commentPos, commentEnd); - return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || - textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ? - true : false; - } - return false; + return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd); } } ts.createCommentWriter = createCommentWriter; @@ -55155,7 +55273,9 @@ var ts; if (!(ts.getEmitFlags(node) & 131072)) { var dotRangeStart = node.expression.end; var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1; - var dotToken = { kind: 23, pos: dotRangeStart, end: dotRangeEnd }; + var dotToken = ts.createToken(23); + dotToken.pos = dotRangeStart; + dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } @@ -55267,7 +55387,9 @@ var ts; var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right); emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); + emitLeadingCommentsOfPosition(node.operatorToken.pos); writeTokenNode(node.operatorToken); + emitTrailingCommentsOfPosition(node.operatorToken.end, true); increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); decreaseIndentIf(indentBeforeOperator, indentAfterOperator); @@ -55454,8 +55576,19 @@ var ts; emitWithPrefix(" ", node.label); write(";"); } + function emitTokenWithComment(token, pos, contextNode) { + var node = contextNode && ts.getParseTreeNode(contextNode); + if (node && node.kind === contextNode.kind) { + pos = ts.skipTrivia(currentSourceFile.text, pos); + } + pos = writeToken(token, pos, contextNode); + if (node && node.kind === contextNode.kind) { + emitTrailingCommentsOfPosition(pos, true); + } + return pos; + } function emitReturnStatement(node) { - writeToken(96, node.pos, node); + emitTokenWithComment(96, node.pos, node); emitExpressionWithPrefix(" ", node.expression); write(";"); } @@ -55896,10 +56029,12 @@ var ts; function emitCatchClause(node) { var openParenPos = writeToken(74, node.pos); write(" "); - writeToken(19, openParenPos); - emit(node.variableDeclaration); - writeToken(20, node.variableDeclaration ? node.variableDeclaration.end : openParenPos); - write(" "); + if (node.variableDeclaration) { + writeToken(19, openParenPos); + emit(node.variableDeclaration); + writeToken(20, node.variableDeclaration.end); + write(" "); + } emit(node.block); } function emitPropertyAssignment(node) { @@ -57011,6 +57146,9 @@ var ts; var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; }; resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); }; } + var packageIdToSourceFile = ts.createMap(); + var sourceFileToPackageName = ts.createMap(); + var redirectTargetsSet = ts.createMap(); var filesByName = ts.createMap(); var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined; var structuralIsReused = tryReuseStructureFromOldProgram(); @@ -57067,6 +57205,8 @@ var ts; isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker, getSourceFileFromReference: getSourceFileFromReference, + sourceFileToPackageName: sourceFileToPackageName, + redirectTargetsSet: redirectTargetsSet, }; verifyCompilerOptions(); ts.performance.mark("afterProgram"); @@ -57210,17 +57350,51 @@ var ts; var filePaths = []; var modifiedSourceFiles = []; oldProgram.structureIsReused = 2; - for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) { - var oldSourceFile = _a[_i]; + var oldSourceFiles = oldProgram.getSourceFiles(); + var SeenPackageName; + (function (SeenPackageName) { + SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists"; + SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified"; + })(SeenPackageName || (SeenPackageName = {})); + var seenPackageNames = ts.createMap(); + for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { + var oldSourceFile = oldSourceFiles_1[_i]; var newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target) : host.getSourceFile(oldSourceFile.fileName, options.target); if (!newSourceFile) { return oldProgram.structureIsReused = 0; } + ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); + var fileChanged = void 0; + if (oldSourceFile.redirectInfo) { + if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { + return oldProgram.structureIsReused = 0; + } + fileChanged = false; + newSourceFile = oldSourceFile; + } + else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) { + if (newSourceFile !== oldSourceFile) { + return oldProgram.structureIsReused = 0; + } + fileChanged = false; + } + else { + fileChanged = newSourceFile !== oldSourceFile; + } newSourceFile.path = oldSourceFile.path; filePaths.push(newSourceFile.path); - if (oldSourceFile !== newSourceFile) { + var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); + if (packageName !== undefined) { + var prevKind = seenPackageNames.get(packageName); + var newKind = fileChanged ? 1 : 0; + if ((prevKind !== undefined && newKind === 1) || prevKind === 1) { + return oldProgram.structureIsReused = 0; + } + seenPackageNames.set(packageName, newKind); + } + if (fileChanged) { if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { oldProgram.structureIsReused = 1; } @@ -57248,8 +57422,8 @@ var ts; return oldProgram.structureIsReused; } modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; }); - for (var _b = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _b < modifiedSourceFiles_1.length; _b++) { - var _c = modifiedSourceFiles_1[_b], oldSourceFile = _c.oldFile, newSourceFile = _c.newFile; + for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) { + var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile; var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { var moduleNames = ts.map(ts.concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral); @@ -57283,8 +57457,8 @@ var ts; if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) { return oldProgram.structureIsReused = 1; } - for (var _d = 0, _e = oldProgram.getMissingFilePaths(); _d < _e.length; _d++) { - var p = _e[_d]; + for (var _c = 0, _d = oldProgram.getMissingFilePaths(); _c < _d.length; _c++) { + var p = _d[_c]; filesByName.set(p, undefined); } for (var i = 0; i < newSourceFiles.length; i++) { @@ -57292,11 +57466,13 @@ var ts; } files = newSourceFiles; fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics(); - for (var _f = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _f < modifiedSourceFiles_2.length; _f++) { - var modifiedFile = modifiedSourceFiles_2[_f]; + for (var _e = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _e < modifiedSourceFiles_2.length; _e++) { + var modifiedFile = modifiedSourceFiles_2[_e]; fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile); } resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives(); + sourceFileToPackageName = oldProgram.sourceFileToPackageName; + redirectTargetsSet = oldProgram.redirectTargetsSet; return oldProgram.structureIsReused = 2; } function getEmitHost(writeFileCallback) { @@ -57775,7 +57951,7 @@ var ts; } } function processSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd) { - getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd); }, function (diagnostic) { + getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, undefined); }, function (diagnostic) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; @@ -57792,7 +57968,24 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } } - function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd) { + function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) { + var redirect = Object.create(redirectTarget); + redirect.fileName = fileName; + redirect.path = path; + redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected }; + Object.defineProperties(redirect, { + id: { + get: function () { return this.redirectInfo.redirectTarget.id; }, + set: function (value) { this.redirectInfo.redirectTarget.id = value; }, + }, + symbol: { + get: function () { return this.redirectInfo.redirectTarget.symbol; }, + set: function (value) { this.redirectInfo.redirectTarget.symbol = value; }, + }, + }); + return redirect; + } + function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) { if (filesByName.has(path)) { var file_1 = filesByName.get(path); if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { @@ -57823,6 +58016,22 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); + if (packageId) { + var packageIdKey = packageId.name + "@" + packageId.version; + var fileFromPackageId = packageIdToSourceFile.get(packageIdKey); + if (fileFromPackageId) { + var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path); + redirectTargetsSet.set(fileFromPackageId.path, true); + filesByName.set(path, dupFile); + sourceFileToPackageName.set(path, packageId.name); + files.push(dupFile); + return dupFile; + } + else if (file) { + packageIdToSourceFile.set(packageIdKey, file); + sourceFileToPackageName.set(path, packageId.name); + } + } filesByName.set(path, file); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); @@ -57944,7 +58153,7 @@ var ts; else if (shouldAddFile) { var path = toPath(resolvedFileName); var pos = ts.skipTrivia(file.text, file.imports[i].pos); - findSourceFile(resolvedFileName, path, false, file, pos, file.imports[i].end); + findSourceFile(resolvedFileName, path, false, file, pos, file.imports[i].end, resolution.packageId); } if (isFromNodeModulesSearch) { currentNodeModulesDepth--; @@ -58623,6 +58832,12 @@ var ts; category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "preserveSymlinks", + type: "boolean", + category: ts.Diagnostics.Module_Resolution_Options, + description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, + }, { name: "sourceRoot", type: "string", @@ -59234,7 +59449,7 @@ var ts; var text = valueExpression.text; if (option && typeof option.type !== "string") { var customOption = option; - if (!customOption.type.has(text)) { + if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } @@ -59485,12 +59700,10 @@ var ts; } } else { - var specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; var outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"]; if (outDir) { - specs.push(outDir); + excludeSpecs = [outDir]; } - excludeSpecs = specs; } if (fileNames === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; @@ -59741,7 +59954,7 @@ var ts; return value; } else if (typeof option.type !== "string") { - return option.type.get(value); + return option.type.get(typeof value === "string" ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } @@ -59816,23 +60029,13 @@ var ts; }; } function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { - var validSpecs = []; - for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) { - var spec = specs_1[_i]; - if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidMultipleRecursionPatterns.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); + return specs.filter(function (spec) { + var diag = specToDiagnostic(spec, allowTrailingRecursion); + if (diag !== undefined) { + errors.push(createDiagnostic(diag, spec)); } - else { - validSpecs.push(spec); - } - } - return validSpecs; + return diag === undefined; + }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { @@ -59850,6 +60053,17 @@ var ts; return ts.createCompilerDiagnostic(message, spec); } } + function specToDiagnostic(spec, allowTrailingRecursion) { + if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + else if (invalidMultipleRecursionPatterns.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; + } + else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + } function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) { var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude"); var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); @@ -61220,6 +61434,7 @@ var ts; } ts.symbolToDisplayParts = symbolToDisplayParts; function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) { + flags |= 65536; return mapToDisplayParts(function (writer) { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); @@ -61925,11 +62140,11 @@ var ts; templateStack.pop(); } else { - ts.Debug.assert(token === 15, "Should have been a template middle. Was " + token); + ts.Debug.assertEqual(token, 15, "Should have been a template middle."); } } else { - ts.Debug.assert(lastTemplateStackToken === 17, "Should have been an open brace. Was: " + token); + ts.Debug.assertEqual(lastTemplateStackToken, 17, "Should have been an open brace"); templateStack.pop(); } } @@ -63587,7 +63802,7 @@ var ts; var typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); if (!typeForObject) return false; - typeMembers = typeChecker.getPropertiesOfType(typeForObject); + typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24); }); existingMembers = objectLikeContainer.elements; } } @@ -63964,8 +64179,8 @@ var ts; addPropertySymbols(implementingTypeSymbols, 24); return result; function addPropertySymbols(properties, inValidModifierFlags) { - for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { - var property = properties_11[_i]; + for (var _i = 0, properties_12 = properties; _i < properties_12.length; _i++) { + var property = properties_12[_i]; if (isValidProperty(property, inValidModifierFlags)) { result.push(property); } @@ -65655,11 +65870,15 @@ var ts; } function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) { var bindingElement = getObjectBindingElementWithoutPropertyName(symbol); - if (bindingElement) { - var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent); - return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text); + if (!bindingElement) + return undefined; + var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent); + var propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text); + if (propSymbol && propSymbol.flags & 98304) { + ts.Debug.assert(!!(propSymbol.flags & 33554432)); + return propSymbol.target; } - return undefined; + return propSymbol; } function getSymbolScope(symbol) { var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration; @@ -65679,12 +65898,13 @@ var ts; if (getObjectBindingElementWithoutPropertyName(symbol)) { return undefined; } - if (parent && !((parent.flags & 1536) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) { + var exposedByParent = parent && !(symbol.flags & 262144); + if (exposedByParent && !((parent.flags & 1536) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) { return undefined; } var scope; - for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) { - var declaration = declarations_10[_i]; + for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { + var declaration = declarations_9[_i]; var container = ts.getContainerNode(declaration); if (scope && scope !== container) { return undefined; @@ -65694,7 +65914,7 @@ var ts; } scope = container; } - return parent ? scope.getSourceFile() : scope; + return exposedByParent ? scope.getSourceFile() : scope; } function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) { if (container === void 0) { container = sourceFile; } @@ -66371,8 +66591,8 @@ var ts; var lastIterationMeaning = void 0; do { lastIterationMeaning = meaning; - for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { - var declaration = declarations_11[_i]; + for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) { + var declaration = declarations_10[_i]; var declarationMeaning = ts.getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; @@ -66517,6 +66737,16 @@ var ts; var shorthandContainerName_1 = typeChecker.symbolToString(symbol.parent, node); return ts.map(shorthandDeclarations, function (declaration) { return createDefinitionInfo(declaration, shorthandSymbolKind_1, shorthandSymbolName_1, shorthandContainerName_1); }); } + if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) && + (node === (node.parent.propertyName || node.parent.name))) { + var type = typeChecker.getTypeAtLocation(node.parent.parent); + if (type) { + var propSymbols = ts.getPropertySymbolsFromType(type, node); + if (propSymbols) { + return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); }); + } + } + } var element = ts.getContainingObjectLiteralElement(node); if (element && typeChecker.getContextualType(element.parent)) { return ts.flatMap(ts.getPropertySymbolsFromContextualType(typeChecker, element), function (propertySymbol) { @@ -66933,7 +67163,7 @@ var ts; "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console" ]; - var nodeCoreModules = ts.arrayToMap(JsTyping.nodeCoreModuleList, function (x) { return x; }); + var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList); function loadSafeList(host, safeListPath) { var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); }); return ts.createMapFromTemplate(result.config); @@ -67093,8 +67323,8 @@ var ts; if (!matches) { return; } - for (var _i = 0, declarations_12 = declarations; _i < declarations_12.length; _i++) { - var declaration = declarations_12[_i]; + for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { + var declaration = declarations_11[_i]; if (patternMatcher.patternContainsDots) { var containers = getContainers(declaration); if (!containers) { @@ -68741,8 +68971,8 @@ var ts; var nameToDeclarations = sourceFile.getNamedDeclarations(); var declarations = nameToDeclarations.get(name.text); if (declarations) { - for (var _b = 0, declarations_13 = declarations; _b < declarations_13.length; _b++) { - var declaration = declarations_13[_b]; + for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) { + var declaration = declarations_12[_b]; var symbol = declaration.symbol; if (symbol) { var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration); @@ -68775,7 +69005,9 @@ var ts; } var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 : 1; var argumentCount = getArgumentCount(list); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var argumentsSpan = getApplicableSpanForArguments(list, sourceFile); return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount }; } @@ -68853,7 +69085,9 @@ var ts; var argumentCount = tagExpression.template.kind === 13 ? 1 : tagExpression.template.templateSpans.length + 1; - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } return { kind: 2, invocation: tagExpression, @@ -68950,7 +69184,9 @@ var ts; tags: candidateSignature.getJsDocTags() }; }); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var selectedItemIndex = candidates.indexOf(resolvedSignature); ts.Debug.assert(selectedItemIndex !== -1); return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount }; @@ -69165,7 +69401,7 @@ var ts; else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304)) || (location.kind === 123 && location.parent.kind === 152)) { var functionDeclaration_1 = location.parent; - var locationIsSymbolDeclaration = ts.findDeclaration(symbol, function (declaration) { + var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) { return declaration === (location.kind === 123 ? functionDeclaration_1.parent : functionDeclaration_1); }); if (locationIsSymbolDeclaration) { @@ -69509,11 +69745,11 @@ var ts; getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; }, writeFile: function (name, text) { if (ts.fileExtensionIs(name, ".map")) { - ts.Debug.assert(sourceMapText === undefined, "Unexpected multiple source map outputs for the file '" + name + "'"); + ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); sourceMapText = text; } else { - ts.Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: '" + name + "'"); + ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); outputText = text; } }, @@ -70132,6 +70368,7 @@ var ts; this.NoSpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(25, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 8)); this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2)); this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2)); + this.SpaceBetweenOpenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19, 19), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2)); this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19, 20), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8)); this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8)); this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8)); @@ -70203,7 +70440,7 @@ var ts; this.SpaceAfterComma, this.NoSpaceAfterComma, this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword, this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl, - this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, + this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace, this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail, @@ -72050,6 +72287,12 @@ var ts; } return false; } + var ChangeKind; + (function (ChangeKind) { + ChangeKind[ChangeKind["Remove"] = 0] = "Remove"; + ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode"; + ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes"; + })(ChangeKind || (ChangeKind = {})); function getSeparatorCharacter(separator) { return ts.tokenToString(separator.kind); } @@ -72074,7 +72317,7 @@ var ts; } textChanges.getAdjustedStartPosition = getAdjustedStartPosition; function getAdjustedEndPosition(sourceFile, node, options) { - if (options.useNonAdjustedEndPosition) { + if (options.useNonAdjustedEndPosition || ts.isExpression(node)) { return node.getEnd(); } var end = node.getEnd(); @@ -72094,6 +72337,9 @@ var ts; } return s; } + function getNewlineKind(context) { + return context.newLineCharacter === "\n" ? 1 : 0; + } var ChangeTracker = (function () { function ChangeTracker(newLine, rulesProvider, validator) { this.newLine = newLine; @@ -72103,24 +72349,24 @@ var ts; this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine }); } ChangeTracker.fromCodeFixContext = function (context) { - return new ChangeTracker(context.newLineCharacter === "\n" ? 1 : 0, context.rulesProvider); + return new ChangeTracker(getNewlineKind(context), context.rulesProvider); + }; + ChangeTracker.prototype.deleteRange = function (sourceFile, range) { + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range }); + return this; }; ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, node, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); - return this; - }; - ChangeTracker.prototype.deleteRange = function (sourceFile, range) { - this.changes.push({ sourceFile: sourceFile, range: range }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) { @@ -72156,33 +72402,68 @@ var ts; }; ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, range: range, options: options, node: newNode }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode }); return this; }; ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); }; ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); + }; + ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, + sourceFile: sourceFile, + options: options, + node: newNode, + range: { pos: startPosition, end: endPosition } + }); return this; }; + ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithMultipleNodes, + sourceFile: sourceFile, + options: options, + nodes: newNodes, + range: { pos: startPosition, end: endPosition } + }); + return this; + }; + ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) { + return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options); + }; + ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); return this; }; ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: startPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options); }; ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) { if (options === void 0) { options = {}; } @@ -72192,6 +72473,7 @@ var ts; after.kind === 150) { if (sourceFile.text.charCodeAt(after.end - 1) !== 59) { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: {}, range: { pos: after.end, end: after.end }, @@ -72200,8 +72482,7 @@ var ts; } } var endPosition = getAdjustedEndPosition(sourceFile, after, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: endPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options); }; ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode) { var containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile); @@ -72229,10 +72510,10 @@ var ts; startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile); } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) }, node: newNode, - useIndentationFromFile: true, options: { prefix: prefix, suffix: "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile)) @@ -72259,6 +72540,7 @@ var ts; } if (multilineList) { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: ts.createToken(separator), @@ -72270,6 +72552,7 @@ var ts; insertPos--; } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: insertPos, end: insertPos }, node: newNode, @@ -72278,6 +72561,7 @@ var ts; } else { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: newNode, @@ -72317,30 +72601,43 @@ var ts; return ts.createTextSpanFromBounds(change.range.pos, change.range.end); }; ChangeTracker.prototype.computeNewText = function (change, sourceFile) { - if (!change.node) { + var _this = this; + if (change.kind === ChangeKind.Remove) { return ""; } var options = change.options || {}; - var nonFormattedText = getNonformattedText(change.node, sourceFile, this.newLine); + var text; + var pos = change.range.pos; + var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; + if (change.kind === ChangeKind.ReplaceWithMultipleNodes) { + var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); }); + text = parts.join(change.options.nodeSeparator); + } + else { + ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode"); + text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options); + } + text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, ""); + return (options.prefix || "") + text + (options.suffix || ""); + }; + ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) { + var nonformattedText = getNonformattedText(node, sourceFile, this.newLine); if (this.validator) { - this.validator(nonFormattedText); + this.validator(nonformattedText); } var formatOptions = this.rulesProvider.getFormatOptions(); - var pos = change.range.pos; var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; - var initialIndentation = change.options.indentation !== undefined - ? change.options.indentation - : change.useIndentationFromFile - ? ts.formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix === this.newLineCharacter)) + var initialIndentation = options.indentation !== undefined + ? options.indentation + : (options.useIndentationFromFile !== false) + ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) : 0; - var delta = change.options.delta !== undefined - ? change.options.delta - : ts.formatting.SmartIndenter.shouldIndentChildNode(change.node) - ? formatOptions.indentSize + var delta = options.delta !== undefined + ? options.delta + : ts.formatting.SmartIndenter.shouldIndentChildNode(node) + ? (formatOptions.indentSize || 0) : 0; - var text = applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, this.rulesProvider); - text = posStartsLine || change.options.indentation !== undefined ? text : text.replace(/^\s+/, ""); - return (options.prefix || "") + text + (options.suffix || ""); + return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); }; ChangeTracker.normalize = function (changes) { var normalized = ts.stableSort(changes, function (a, b) { return a.range.pos - b.range.pos; }); @@ -73319,7 +73616,7 @@ var ts; symbolName = name; } else if (ts.isJsxOpeningLikeElement(token.parent) && token.parent.tagName === token) { - symbol = checker.getAliasedSymbol(checker.resolveNameAtLocation(token, checker.getJsxNamespace(), 107455)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), token.parent.tagName, 107455)); symbolName = symbol.name; } else { @@ -73403,8 +73700,8 @@ var ts; var namespaceImportDeclaration; var namedImportDeclaration; var existingModuleSpecifier; - for (var _i = 0, declarations_14 = declarations; _i < declarations_14.length; _i++) { - var declaration = declarations_14[_i]; + for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) { + var declaration = declarations_13[_i]; if (declaration.kind === 238) { var namedBindings = declaration.importClause && declaration.importClause.namedBindings; if (namedBindings && namedBindings.kind === 240) { @@ -73478,14 +73775,53 @@ var ts; : isNamespaceImport ? ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(symbolName))) : ts.createImportClause(undefined, ts.createNamedImports([ts.createImportSpecifier(undefined, ts.createIdentifier(symbolName))])); - var importDecl = ts.createImportDeclaration(undefined, undefined, importClause, ts.createLiteral(moduleSpecifierWithoutQuotes)); + var moduleSpecifierLiteral = ts.createLiteral(moduleSpecifierWithoutQuotes); + moduleSpecifierLiteral.singleQuote = getSingleQuoteStyleFromExistingImports(); + var importDecl = ts.createImportDeclaration(undefined, undefined, importClause, moduleSpecifierLiteral); if (!lastImportDeclaration) { - changeTracker.insertNodeAt(sourceFile, sourceFile.getStart(), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); + changeTracker.insertNodeAt(sourceFile, getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); } else { changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: context.newLineCharacter }); } return createCodeAction(ts.Diagnostics.Import_0_from_1, [symbolName, "\"" + moduleSpecifierWithoutQuotes + "\""], changeTracker.getChanges(), "NewImport", moduleSpecifierWithoutQuotes); + function getSourceFileImportLocation(node) { + var text = node.text; + var ranges = ts.getLeadingCommentRanges(text, 0); + if (!ranges) + return 0; + var position = 0; + if (ranges.length && ranges[0].kind === 3 && ts.isPinnedComment(text, ranges[0])) { + position = ranges[0].end + 1; + ranges = ranges.slice(1); + } + for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) { + var range = ranges_1[_i]; + if (range.kind === 2 && ts.isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { + position = range.end + 1; + continue; + } + break; + } + return position; + } + function getSingleQuoteStyleFromExistingImports() { + var firstModuleSpecifier = ts.forEach(sourceFile.statements, function (node) { + if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) { + if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { + return node.moduleSpecifier; + } + } + else if (ts.isImportEqualsDeclaration(node)) { + if (ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) { + return node.moduleReference.expression; + } + } + }); + if (firstModuleSpecifier) { + return sourceFile.text.charCodeAt(firstModuleSpecifier.getStart()) === 39; + } + } function getModuleSpecifierForNewImport() { var fileName = sourceFile.fileName; var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName; @@ -73615,7 +73951,8 @@ var ts; (function (States) { States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; States[States["NodeModules"] = 1] = "NodeModules"; - States[States["PackageContent"] = 2] = "PackageContent"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; })(States || (States = {})); var partStart = 0; var partEnd = 0; @@ -73632,15 +73969,21 @@ var ts; } break; case 1: - packageRootIndex = partEnd; - state = 2; - break; case 2: + if (state === 1 && fullPath.charAt(partStart + 1) === "@") { + state = 2; + } + else { + packageRootIndex = partEnd; + state = 3; + } + break; + case 3: if (fullPath.indexOf("/node_modules/", partStart) === partStart) { state = 1; } else { - state = 2; + state = 3; } break; } @@ -73930,206 +74273,1032 @@ var ts; (function (ts) { var refactor; (function (refactor) { - var actionName = "convert"; - var convertFunctionToES6Class = { - name: "Convert to ES2015 class", - description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, - getEditsForAction: getEditsForAction, - getAvailableActions: getAvailableActions - }; - refactor.registerRefactor(convertFunctionToES6Class); - function getAvailableActions(context) { - if (!ts.isInJavaScriptFile(context.file)) { - return undefined; - } - var start = context.startPosition; - var node = ts.getTokenAtPosition(context.file, start, false); - var checker = context.program.getTypeChecker(); - var symbol = checker.getSymbolAtLocation(node); - if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { - symbol = symbol.valueDeclaration.initializer.symbol; + var convertFunctionToES6Class; + (function (convertFunctionToES6Class_1) { + var actionName = "convert"; + var convertFunctionToES6Class = { + name: "Convert to ES2015 class", + description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, + getEditsForAction: getEditsForAction, + getAvailableActions: getAvailableActions + }; + refactor.registerRefactor(convertFunctionToES6Class); + function getAvailableActions(context) { + if (!ts.isInJavaScriptFile(context.file)) { + return undefined; + } + var start = context.startPosition; + var node = ts.getTokenAtPosition(context.file, start, false); + var checker = context.program.getTypeChecker(); + var symbol = checker.getSymbolAtLocation(node); + if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = symbol.valueDeclaration.initializer.symbol; + } + if (symbol && (symbol.flags & 16) && symbol.members && (symbol.members.size > 0)) { + return [ + { + name: convertFunctionToES6Class.name, + description: convertFunctionToES6Class.description, + actions: [ + { + description: convertFunctionToES6Class.description, + name: actionName + } + ] + } + ]; + } } - if (symbol && (symbol.flags & 16) && symbol.members && (symbol.members.size > 0)) { - return [ - { - name: convertFunctionToES6Class.name, - description: convertFunctionToES6Class.description, - actions: [ - { - description: convertFunctionToES6Class.description, - name: actionName + function getEditsForAction(context, action) { + if (actionName !== action) { + return undefined; + } + var start = context.startPosition; + var sourceFile = context.file; + var checker = context.program.getTypeChecker(); + var token = ts.getTokenAtPosition(sourceFile, start, false); + var ctorSymbol = checker.getSymbolAtLocation(token); + var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; + var deletedNodes = []; + var deletes = []; + if (!(ctorSymbol.flags & (16 | 3))) { + return undefined; + } + var ctorDeclaration = ctorSymbol.valueDeclaration; + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + var precedingNode; + var newClassDeclaration; + switch (ctorDeclaration.kind) { + case 228: + precedingNode = ctorDeclaration; + deleteNode(ctorDeclaration); + newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); + break; + case 226: + precedingNode = ctorDeclaration.parent.parent; + if (ctorDeclaration.parent.declarations.length === 1) { + deleteNode(precedingNode); + } + else { + deleteNode(ctorDeclaration, true); + } + newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); + break; + } + if (!newClassDeclaration) { + return undefined; + } + changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); + for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { + var deleteCallback = deletes_1[_i]; + deleteCallback(); + } + return { + edits: changeTracker.getChanges() + }; + function deleteNode(node, inList) { + if (inList === void 0) { inList = false; } + if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { + return; + } + deletedNodes.push(node); + if (inList) { + deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + } + else { + deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + } + } + function createClassElementsFromSymbol(symbol) { + var memberElements = []; + if (symbol.members) { + symbol.members.forEach(function (member) { + var memberElement = createClassElement(member, undefined); + if (memberElement) { + memberElements.push(memberElement); } - ] + }); } - ]; - } - } - function getEditsForAction(context, action) { - if (actionName !== action) { - return undefined; + if (symbol.exports) { + symbol.exports.forEach(function (member) { + var memberElement = createClassElement(member, [ts.createToken(115)]); + if (memberElement) { + memberElements.push(memberElement); + } + }); + } + return memberElements; + function shouldConvertDeclaration(_target, source) { + return ts.isFunctionLike(source); + } + function createClassElement(symbol, modifiers) { + if (!(symbol.flags & 4)) { + return; + } + var memberDeclaration = symbol.valueDeclaration; + var assignmentBinaryExpression = memberDeclaration.parent; + if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { + return; + } + var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 + ? assignmentBinaryExpression.parent : assignmentBinaryExpression; + deleteNode(nodeToDelete); + if (!assignmentBinaryExpression.right) { + return ts.createProperty([], modifiers, symbol.name, undefined, undefined, undefined); + } + switch (assignmentBinaryExpression.right.kind) { + case 186: { + var functionExpression = assignmentBinaryExpression.right; + var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, functionExpression.parameters, undefined, functionExpression.body); + copyComments(assignmentBinaryExpression, method); + return method; + } + case 187: { + var arrowFunction = assignmentBinaryExpression.right; + var arrowFunctionBody = arrowFunction.body; + var bodyBlock = void 0; + if (arrowFunctionBody.kind === 207) { + bodyBlock = arrowFunctionBody; + } + else { + var expression = arrowFunctionBody; + bodyBlock = ts.createBlock([ts.createReturn(expression)]); + } + var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, arrowFunction.parameters, undefined, bodyBlock); + copyComments(assignmentBinaryExpression, method); + return method; + } + default: { + if (ts.isSourceFileJavaScript(sourceFile)) { + return; + } + var prop = ts.createProperty(undefined, modifiers, memberDeclaration.name, undefined, undefined, assignmentBinaryExpression.right); + copyComments(assignmentBinaryExpression.parent, prop); + return prop; + } + } + } + } + function copyComments(sourceNode, targetNode) { + ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { + if (kind === 3) { + pos += 2; + end -= 2; + } + else { + pos += 2; + } + ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); + }); + } + function createClassFromVariableDeclaration(node) { + var initializer = node.initializer; + if (!initializer || initializer.kind !== 186) { + return undefined; + } + if (node.name.kind !== 71) { + return undefined; + } + var memberElements = createClassElementsFromSymbol(initializer.symbol); + if (initializer.body) { + memberElements.unshift(ts.createConstructor(undefined, undefined, initializer.parameters, initializer.body)); + } + var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); + return cls; + } + function createClassFromFunctionDeclaration(node) { + var memberElements = createClassElementsFromSymbol(ctorSymbol); + if (node.body) { + memberElements.unshift(ts.createConstructor(undefined, undefined, node.parameters, node.body)); + } + var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); + return cls; + } } - var start = context.startPosition; - var sourceFile = context.file; - var checker = context.program.getTypeChecker(); - var token = ts.getTokenAtPosition(sourceFile, start, false); - var ctorSymbol = checker.getSymbolAtLocation(token); - var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; - var deletedNodes = []; - var deletes = []; - if (!(ctorSymbol.flags & (16 | 3))) { - return undefined; + })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {})); + })(refactor = ts.refactor || (ts.refactor = {})); +})(ts || (ts = {})); +var ts; +(function (ts) { + var refactor; + (function (refactor) { + var extractMethod; + (function (extractMethod_1) { + var extractMethod = { + name: "Extract Method", + description: ts.Diagnostics.Extract_function.message, + getAvailableActions: getAvailableActions, + getEditsForAction: getEditsForAction, + }; + refactor.registerRefactor(extractMethod); + function getAvailableActions(context) { + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: context.endPosition - context.startPosition }); + var targetRange = rangeToExtract.targetRange; + if (targetRange === undefined) { + return undefined; + } + var extractions = getPossibleExtractions(targetRange, context); + if (extractions === undefined) { + return undefined; + } + var actions = []; + var usedNames = ts.createMap(); + var i = 0; + for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { + var extr = extractions_1[_i]; + if (extr.errors && extr.errors.length) { + continue; + } + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + if (!usedNames.has(description)) { + usedNames.set(description, true); + actions.push({ + description: description, + name: "scope_" + i + }); + } + i++; + } + if (actions.length === 0) { + return undefined; + } + return [{ + name: extractMethod.name, + description: extractMethod.description, + inlineable: true, + actions: actions + }]; } - var ctorDeclaration = ctorSymbol.valueDeclaration; - var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); - var precedingNode; - var newClassDeclaration; - switch (ctorDeclaration.kind) { - case 228: - precedingNode = ctorDeclaration; - deleteNode(ctorDeclaration); - newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); - break; - case 226: - precedingNode = ctorDeclaration.parent.parent; - if (ctorDeclaration.parent.declarations.length === 1) { - deleteNode(precedingNode); + function getEditsForAction(context, actionName) { + var length = context.endPosition === undefined ? 0 : context.endPosition - context.startPosition; + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: length }); + var targetRange = rangeToExtract.targetRange; + var parsedIndexMatch = /^scope_(\d+)$/.exec(actionName); + ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); + var index = +parsedIndexMatch[1]; + ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); + var extractions = getPossibleExtractions(targetRange, context, index); + ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); + return ({ edits: extractions[0].changes }); + } + var Messages; + (function (Messages) { + function createMessage(message) { + return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message }; + } + Messages.CannotExtractFunction = createMessage("Cannot extract function."); + Messages.StatementOrExpressionExpected = createMessage("Statement or expression expected."); + Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements."); + Messages.CannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement."); + Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); + Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); + Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); + Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); + Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); + Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); + Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); + Messages.CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); + })(Messages || (Messages = {})); + var RangeFacts; + (function (RangeFacts) { + RangeFacts[RangeFacts["None"] = 0] = "None"; + RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn"; + RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator"; + RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; + RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; + RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; + })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + function getRangeToExtract(sourceFile, span) { + var length = span.length || 0; + var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, false), sourceFile, span); + var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span); + var declarations = []; + var rangeFacts = RangeFacts.None; + if (!start || !end) { + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractFunction)] }; + } + if (start.parent !== end.parent) { + var startParent = ts.skipParentheses(start.parent); + var endParent = ts.skipParentheses(end.parent); + if (ts.isBinaryExpression(startParent) && ts.isBinaryExpression(endParent) && ts.isNodeDescendantOf(startParent, endParent)) { + start = end = endParent; } else { - deleteNode(ctorDeclaration, true); + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); } - newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); - break; + } + if (start !== end) { + if (!isBlockLike(start.parent)) { + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); + } + var statements = []; + for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) { + var statement = _a[_i]; + if (statement === start || statements.length) { + var errors = checkNode(statement); + if (errors) { + return { errors: errors }; + } + statements.push(statement); + } + if (statement === end) { + break; + } + } + return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } }; + } + else { + var errors = checkRootNode(start) || checkNode(start); + if (errors) { + return { errors: errors }; + } + var range = ts.isStatement(start) + ? [start] + : start.parent && start.parent.kind === 210 + ? [start.parent] + : start; + return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + } + function createErrorResult(sourceFile, start, length, message) { + return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; + } + function checkRootNode(node) { + if (ts.isIdentifier(node)) { + return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; + } + return undefined; + } + function checkForStaticContext(nodeToCheck, containingClass) { + var current = nodeToCheck; + while (current !== containingClass) { + if (current.kind === 149) { + if (ts.hasModifier(current, 32)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 146) { + var ctorOrMethod = ts.getContainingFunction(current); + if (ctorOrMethod.kind === 152) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 151) { + if (ts.hasModifier(current, 32)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + } + current = current.parent; + } + } + function checkNode(nodeToCheck) { + var PermittedJumps; + (function (PermittedJumps) { + PermittedJumps[PermittedJumps["None"] = 0] = "None"; + PermittedJumps[PermittedJumps["Break"] = 1] = "Break"; + PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue"; + PermittedJumps[PermittedJumps["Return"] = 4] = "Return"; + })(PermittedJumps || (PermittedJumps = {})); + if (!ts.isStatement(nodeToCheck) && !(ts.isExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)]; + } + if (ts.isInAmbientContext(nodeToCheck)) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)]; + } + var containingClass = ts.getContainingClass(nodeToCheck); + if (containingClass) { + checkForStaticContext(nodeToCheck, containingClass); + } + var errors; + var permittedJumps = 4; + var seenLabels; + visit(nodeToCheck); + return errors; + function visit(node) { + if (errors) { + return true; + } + if (ts.isDeclaration(node)) { + var declaringNode = (node.kind === 226) ? node.parent.parent : node; + if (ts.hasModifier(declaringNode, 1)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + return true; + } + declarations.push(node.symbol); + } + switch (node.kind) { + case 238: + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + case 97: + if (node.parent.kind === 181) { + var containingClass_1 = ts.getContainingClass(node); + if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + } + } + else { + rangeFacts |= RangeFacts.UsesThis; + } + break; + } + if (!node || ts.isFunctionLike(node) || ts.isClassLike(node)) { + switch (node.kind) { + case 228: + case 229: + if (node.parent.kind === 265 && node.parent.externalModuleIndicator === undefined) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope)); + } + break; + } + return false; + } + var savedPermittedJumps = permittedJumps; + if (node.parent) { + switch (node.parent.kind) { + case 211: + if (node.parent.thenStatement === node || node.parent.elseStatement === node) { + permittedJumps = 0; + } + break; + case 224: + if (node.parent.tryBlock === node) { + permittedJumps = 0; + } + else if (node.parent.finallyBlock === node) { + permittedJumps = 4; + } + break; + case 260: + if (node.parent.block === node) { + permittedJumps = 0; + } + break; + case 257: + if (node.expression !== node) { + permittedJumps |= 1; + } + break; + default: + if (ts.isIterationStatement(node.parent, false)) { + if (node.parent.statement === node) { + permittedJumps |= 1 | 2; + } + } + break; + } + } + switch (node.kind) { + case 169: + case 99: + rangeFacts |= RangeFacts.UsesThis; + break; + case 222: + { + var label = node.label; + (seenLabels || (seenLabels = [])).push(label.escapedText); + ts.forEachChild(node, visit); + seenLabels.pop(); + break; + } + case 218: + case 217: + { + var label = node.label; + if (label) { + if (!ts.contains(seenLabels, label.escapedText)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); + } + } + else { + if (!(permittedJumps & (218 ? 1 : 2))) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements)); + } + } + break; + } + case 191: + rangeFacts |= RangeFacts.IsAsyncFunction; + break; + case 197: + rangeFacts |= RangeFacts.IsGenerator; + break; + case 219: + if (permittedJumps & 4) { + rangeFacts |= RangeFacts.HasReturn; + } + else { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement)); + } + break; + default: + ts.forEachChild(node, visit); + break; + } + permittedJumps = savedPermittedJumps; + } + } } - if (!newClassDeclaration) { - return undefined; + extractMethod_1.getRangeToExtract = getRangeToExtract; + function isValidExtractionTarget(node) { + return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); } - changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); - for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { - var deleteCallback = deletes_1[_i]; - deleteCallback(); + function collectEnclosingScopes(range) { + var current = isReadonlyArray(range.range) ? ts.firstOrUndefined(range.range) : range.range; + if (range.facts & RangeFacts.UsesThis) { + var containingClass = ts.getContainingClass(current); + if (containingClass) { + return [containingClass]; + } + } + var start = current; + var scopes = undefined; + while (current) { + if (current !== start && isValidExtractionTarget(current)) { + (scopes = scopes || []).push(current); + } + if (current && current.parent && current.parent.kind === 146) { + current = ts.findAncestor(current, function (parent) { return ts.isFunctionLike(parent); }).parent; + } + else { + current = current.parent; + } + } + return scopes; } - return { - edits: changeTracker.getChanges() - }; - function deleteNode(node, inList) { - if (inList === void 0) { inList = false; } - if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { - return; + extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; + function getPossibleExtractions(targetRange, context, requestedChangesIndex) { + if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + var sourceFile = context.file; + if (targetRange === undefined) { + return undefined; } - deletedNodes.push(node); - if (inList) { - deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + var scopes = collectEnclosingScopes(targetRange); + if (scopes === undefined) { + return undefined; + } + var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); + var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; + context.cancellationToken.throwIfCancellationRequested(); + if (requestedChangesIndex !== undefined) { + if (errorsPerScope[requestedChangesIndex].length) { + return undefined; + } + return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; } else { - deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + return scopes.map(function (scope, i) { + var errors = errorsPerScope[i]; + if (errors.length) { + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + errors: errors + }; + } + return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; + }); + } + } + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getDescriptionForScope(scope) { + if (ts.isFunctionLike(scope)) { + switch (scope.kind) { + case 152: + return "constructor"; + case 186: + return scope.name + ? "function expression " + scope.name.getText() + : "anonymous function expression"; + case 228: + return "function " + scope.name.getText(); + case 187: + return "arrow function"; + case 151: + return "method " + scope.name.getText(); + case 153: + return "get " + scope.name.getText(); + case 154: + return "set " + scope.name.getText(); + } + } + else if (isModuleBlock(scope)) { + return "namespace " + scope.parent.name.getText(); + } + else if (ts.isClassLike(scope)) { + return scope.kind === 229 + ? "class " + scope.name.text + : scope.name.text + ? "class expression " + scope.name.text + : "anonymous class expression"; + } + else if (ts.isSourceFile(scope)) { + return "file '" + scope.fileName + "'"; + } + else { + return "unknown"; + } + } + function getUniqueName(isNameOkay) { + var functionNameText = "newFunction"; + if (isNameOkay(functionNameText)) { + return functionNameText; + } + var i = 1; + while (!isNameOkay(functionNameText = "newFunction_" + i)) { + i++; } + return functionNameText; } - function createClassElementsFromSymbol(symbol) { - var memberElements = []; - if (symbol.members) { - symbol.members.forEach(function (member) { - var memberElement = createClassElement(member, undefined); - if (memberElement) { - memberElements.push(memberElement); + function extractFunctionInScope(node, scope, _a, range, context) { + var usagesInScope = _a.usages, substitutions = _a.substitutions; + var checker = context.program.getTypeChecker(); + var file = scope.getSourceFile(); + var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var isJS = ts.isInJavaScriptFile(scope); + var functionName = ts.createIdentifier(functionNameText); + var functionReference = ts.createIdentifier(functionNameText); + var returnType = undefined; + var parameters = []; + var callArguments = []; + var writes; + usagesInScope.forEach(function (usage, name) { + var typeNode = undefined; + if (!isJS) { + var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); + type = checker.getBaseTypeOfLiteralType(type); + typeNode = checker.typeToTypeNode(type, node, ts.NodeBuilderFlags.NoTruncation); + } + var paramDecl = ts.createParameter(undefined, undefined, undefined, name, undefined, typeNode); + parameters.push(paramDecl); + if (usage.usage === 2) { + (writes || (writes = [])).push(usage); + } + callArguments.push(ts.createIdentifier(name)); + }); + if (ts.isExpression(node) && !isJS) { + var contextualType = checker.getContextualType(node); + returnType = checker.typeToTypeNode(contextualType); + } + var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var newFunction; + if (ts.isClassLike(scope)) { + var modifiers = isJS ? [] : [ts.createToken(112)]; + if (range.facts & RangeFacts.InStaticRegion) { + modifiers.push(ts.createToken(115)); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + modifiers.push(ts.createToken(120)); + } + newFunction = ts.createMethod(undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, [], parameters, returnType, body); + } + else { + newFunction = ts.createFunctionDeclaration(undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, [], parameters, returnType, body); + } + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); + var newNodes = []; + var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, undefined, callArguments); + if (range.facts & RangeFacts.IsGenerator) { + call = ts.createYield(ts.createToken(39), call); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + call = ts.createAwait(call); + } + if (writes) { + if (returnValueProperty) { + newNodes.push(ts.createVariableStatement(undefined, [ts.createVariableDeclaration(returnValueProperty, ts.createKeywordTypeNode(119))])); + } + var assignments = getPropertyAssignmentsForWrites(writes); + if (returnValueProperty) { + assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty)); + } + if (assignments.length === 1) { + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); + } + else { + newNodes.push(ts.createStatement(ts.createBinary(assignments[0].name, 58, call))); + } + } + else { + newNodes.push(ts.createStatement(ts.createBinary(ts.createObjectLiteral(assignments), 58, call))); + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); } + } + } + else { + if (range.facts & RangeFacts.HasReturn) { + newNodes.push(ts.createReturn(call)); + } + else if (isReadonlyArray(range.range)) { + newNodes.push(ts.createStatement(call)); + } + else { + newNodes.push(call); + } + } + if (isReadonlyArray(range.range)) { + changeTracker.replaceNodesWithNodes(context.file, range.range, newNodes, { + nodeSeparator: context.newLineCharacter, + suffix: context.newLineCharacter }); } - if (symbol.exports) { - symbol.exports.forEach(function (member) { - var memberElement = createClassElement(member, [ts.createToken(115)]); - if (memberElement) { - memberElements.push(memberElement); + else { + changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); + } + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + changes: changeTracker.getChanges() + }; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); + } + function generateReturnValueProperty() { + return "__return"; + } + function transformFunctionBody(body) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + return { body: ts.createBlock(body.statements, true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); + } + } + return { body: ts.createBlock(rewrittenStatements, true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = generateReturnValueProperty(); + } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); + } + else { + return ts.createReturn(ts.createObjectLiteral(assignments)); + } + } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } + } + } + } + extractMethod_1.extractFunctionInScope = extractFunctionInScope; + function isModuleBlock(n) { + return n.kind === 234; + } + function isReadonlyArray(v) { + return ts.isArray(v); + } + function getEnclosingTextRange(targetRange, sourceFile) { + return isReadonlyArray(targetRange.range) + ? { pos: targetRange.range[0].getStart(sourceFile), end: targetRange.range[targetRange.range.length - 1].getEnd() } + : targetRange.range; + } + var Usage; + (function (Usage) { + Usage[Usage["Read"] = 1] = "Read"; + Usage[Usage["Write"] = 2] = "Write"; + })(Usage || (Usage = {})); + function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker) { + var usagesPerScope = []; + var substitutionsPerScope = []; + var errorsPerScope = []; + var visibleDeclarationsInExtractedRange = []; + for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) { + var _ = scopes_1[_i]; + usagesPerScope.push({ usages: ts.createMap(), substitutions: ts.createMap() }); + substitutionsPerScope.push(ts.createMap()); + errorsPerScope.push([]); + } + var seenUsages = ts.createMap(); + var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range; + var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] : ts.getEnclosingBlockScopeContainer(scopes[0]); + collectUsages(target); + var _loop_8 = function (i) { + var hasWrite = false; + var readonlyClassPropertyWrite = undefined; + usagesPerScope[i].usages.forEach(function (value) { + if (value.usage === 2) { + hasWrite = true; + if (value.symbol.flags & 106500 && + value.symbol.valueDeclaration && + ts.hasModifier(value.symbol.valueDeclaration, 64)) { + readonlyClassPropertyWrite = value.symbol.valueDeclaration; + } } }); + if (hasWrite && !isReadonlyArray(targetRange.range) && ts.isExpression(targetRange.range)) { + errorsPerScope[i].push(ts.createDiagnosticForNode(targetRange.range, Messages.CannotCombineWritesAndReturns)); + } + else if (readonlyClassPropertyWrite && i > 0) { + errorsPerScope[i].push(ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotCombineWritesAndReturns)); + } + }; + for (var i = 0; i < scopes.length; i++) { + _loop_8(i); } - return memberElements; - function shouldConvertDeclaration(_target, source) { - return ts.isFunctionLike(source); + if (visibleDeclarationsInExtractedRange.length) { + ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); } - function createClassElement(symbol, modifiers) { - if (!(symbol.flags & 4)) { - return; + return { target: target, usagesPerScope: usagesPerScope, errorsPerScope: errorsPerScope }; + function collectUsages(node, valueUsage) { + if (valueUsage === void 0) { valueUsage = 1; } + if (ts.isDeclaration(node) && node.symbol) { + visibleDeclarationsInExtractedRange.push(node.symbol); } - var memberDeclaration = symbol.valueDeclaration; - var assignmentBinaryExpression = memberDeclaration.parent; - if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { - return; + if (ts.isAssignmentExpression(node)) { + collectUsages(node.left, 2); + collectUsages(node.right); + } + else if (ts.isUnaryExpressionWithWrite(node)) { + collectUsages(node.operand, 2); + } + else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) { + ts.forEachChild(node, collectUsages); + } + else if (ts.isIdentifier(node)) { + if (!node.parent) { + return; + } + if (ts.isQualifiedName(node.parent) && node !== node.parent.left) { + return; + } + if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { + return; + } + recordUsage(node, valueUsage, ts.isPartOfTypeNode(node)); + } + else { + ts.forEachChild(node, collectUsages); } - var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 - ? assignmentBinaryExpression.parent : assignmentBinaryExpression; - deleteNode(nodeToDelete); - if (!assignmentBinaryExpression.right) { - return ts.createProperty([], modifiers, symbol.name, undefined, undefined, undefined); - } - switch (assignmentBinaryExpression.right.kind) { - case 186: { - var functionExpression = assignmentBinaryExpression.right; - var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, functionExpression.parameters, undefined, functionExpression.body); - copyComments(assignmentBinaryExpression, method); - return method; - } - case 187: { - var arrowFunction = assignmentBinaryExpression.right; - var arrowFunctionBody = arrowFunction.body; - var bodyBlock = void 0; - if (arrowFunctionBody.kind === 207) { - bodyBlock = arrowFunctionBody; + } + function recordUsage(n, usage, isTypeNode) { + var symbolId = recordUsagebySymbol(n, usage, isTypeNode); + if (symbolId) { + for (var i = 0; i < scopes.length; i++) { + var substitition = substitutionsPerScope[i].get(symbolId); + if (substitition) { + usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitition); } - else { - var expression = arrowFunctionBody; - bodyBlock = ts.createBlock([ts.createReturn(expression)]); + } + } + } + function recordUsagebySymbol(identifier, usage, isTypeName) { + var symbol = checker.getSymbolAtLocation(identifier); + if (!symbol) { + return undefined; + } + var symbolId = ts.getSymbolId(symbol).toString(); + var lastUsage = seenUsages.get(symbolId); + if (lastUsage && lastUsage >= usage) { + return symbolId; + } + seenUsages.set(symbolId, usage); + if (lastUsage) { + for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) { + var perScope = usagesPerScope_1[_i]; + var prevEntry = perScope.usages.get(identifier.text); + if (prevEntry) { + perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } - var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, arrowFunction.parameters, undefined, bodyBlock); - copyComments(assignmentBinaryExpression, method); - return method; } - default: { - if (ts.isSourceFileJavaScript(sourceFile)) { - return; + return symbolId; + } + var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; }); + if (!declInFile) { + return undefined; + } + if (ts.rangeContainsRange(enclosingTextRange, declInFile)) { + return undefined; + } + if (targetRange.facts & RangeFacts.IsGenerator && usage === 2) { + for (var _a = 0, errorsPerScope_1 = errorsPerScope; _a < errorsPerScope_1.length; _a++) { + var errors = errorsPerScope_1[_a]; + errors.push(ts.createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators)); + } + } + for (var i = 0; i < scopes.length; i++) { + var scope = scopes[i]; + var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + if (resolvedSymbol === symbol) { + continue; + } + if (!substitutionsPerScope[i].has(symbolId)) { + var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName); + if (substitution) { + substitutionsPerScope[i].set(symbolId, substitution); + } + else if (isTypeName) { + errorsPerScope[i].push(ts.createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope)); + } + else { + usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } - var prop = ts.createProperty(undefined, modifiers, memberDeclaration.name, undefined, undefined, assignmentBinaryExpression.right); - copyComments(assignmentBinaryExpression.parent, prop); - return prop; } } + return symbolId; } - } - function copyComments(sourceNode, targetNode) { - ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { - if (kind === 3) { - pos += 2; - end -= 2; + function checkForUsedDeclarations(node) { + if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) { + return; + } + var sym = checker.getSymbolAtLocation(node); + if (sym && visibleDeclarationsInExtractedRange.some(function (d) { return d === sym; })) { + for (var _i = 0, errorsPerScope_2 = errorsPerScope; _i < errorsPerScope_2.length; _i++) { + var scope = errorsPerScope_2[_i]; + scope.push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + } + return true; } else { - pos += 2; + ts.forEachChild(node, checkForUsedDeclarations); } - ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); - }); + } + function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) { + if (!symbol) { + return undefined; + } + if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) { + return ts.createIdentifier(symbol.name); + } + var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); + if (prefix === undefined) { + return undefined; + } + return isTypeNode ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name)) : ts.createPropertyAccess(prefix, symbol.name); + } } - function createClassFromVariableDeclaration(node) { - var initializer = node.initializer; - if (!initializer || initializer.kind !== 186) { + function getParentNodeInSpan(node, file, span) { + if (!node) return undefined; + while (node.parent) { + if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { + return node; + } + node = node.parent; } - if (node.name.kind !== 71) { - return undefined; + } + function spanContainsNode(span, node, file) { + return ts.textSpanContainsPosition(span, node.getStart(file)) && + node.getEnd() <= ts.textSpanEnd(span); + } + function isExtractableExpression(node) { + switch (node.parent.kind) { + case 264: + return false; } - var memberElements = createClassElementsFromSymbol(initializer.symbol); - if (initializer.body) { - memberElements.unshift(ts.createConstructor(undefined, undefined, initializer.parameters, initializer.body)); + switch (node.kind) { + case 9: + return node.parent.kind !== 238 && + node.parent.kind !== 242; + case 198: + case 174: + case 176: + return false; + case 71: + return node.parent.kind !== 176 && + node.parent.kind !== 242 && + node.parent.kind !== 246; } - var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); - return cls; + return true; } - function createClassFromFunctionDeclaration(node) { - var memberElements = createClassElementsFromSymbol(ctorSymbol); - if (node.body) { - memberElements.unshift(ts.createConstructor(undefined, undefined, node.parameters, node.body)); + function isBlockLike(node) { + switch (node.kind) { + case 207: + case 265: + case 234: + case 257: + return true; + default: + return false; } - var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); - return cls; } - } + })(extractMethod = refactor.extractMethod || (refactor.extractMethod = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); var ts; @@ -74986,8 +76155,8 @@ var ts; if (program) { var oldSourceFiles = program.getSourceFiles(); var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings); - for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { - var oldSourceFile = oldSourceFiles_1[_i]; + for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) { + var oldSourceFile = oldSourceFiles_2[_i]; if (!newProgram.getSourceFile(oldSourceFile.fileName) || shouldCreateNewSourceFiles) { documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey); } @@ -75009,7 +76178,7 @@ var ts; if (!shouldCreateNewSourceFiles) { var oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) { - ts.Debug.assert(hostFileInformation.scriptKind === oldSourceFile.scriptKind, "Registered script kind (" + oldSourceFile.scriptKind + ") should match new script kind (" + hostFileInformation.scriptKind + ") for file: " + path); + ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path); return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind); } } @@ -75615,12 +76784,16 @@ var ts; function getPropertySymbolsFromContextualType(typeChecker, node) { var objectLiteral = node.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(node.name)); - if (name && contextualType) { + return getPropertySymbolsFromType(contextualType, node.name); + } + ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + function getPropertySymbolsFromType(type, propName) { + var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName)); + if (name && type) { var result_10 = []; - var symbol = contextualType.getProperty(name); - if (contextualType.flags & 65536) { - ts.forEach(contextualType.types, function (t) { + var symbol = type.getProperty(name); + if (type.flags & 65536) { + ts.forEach(type.types, function (t) { var symbol = t.getProperty(name); if (symbol) { result_10.push(symbol); @@ -75635,7 +76808,7 @@ var ts; } return undefined; } - ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + ts.getPropertySymbolsFromType = getPropertySymbolsFromType; function isArgumentOfElementAccessExpression(node) { return node && node.parent && @@ -76470,42 +77643,6 @@ var ts; return []; } server.createSortedArray = createSortedArray; - function toSortedArray(arr, comparer) { - arr.sort(comparer); - return arr; - } - server.toSortedArray = toSortedArray; - function enumerateInsertsAndDeletes(newItems, oldItems, inserted, deleted, compare) { - compare = compare || ts.compareValues; - var newIndex = 0; - var oldIndex = 0; - var newLen = newItems.length; - var oldLen = oldItems.length; - while (newIndex < newLen && oldIndex < oldLen) { - var newItem = newItems[newIndex]; - var oldItem = oldItems[oldIndex]; - var compareResult = compare(newItem, oldItem); - if (compareResult === -1) { - inserted(newItem); - newIndex++; - } - else if (compareResult === 1) { - deleted(oldItem); - oldIndex++; - } - else { - newIndex++; - oldIndex++; - } - } - while (newIndex < newLen) { - inserted(newItems[newIndex++]); - } - while (oldIndex < oldLen) { - deleted(oldItems[oldIndex++]); - } - } - server.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes; var ThrottledOperations = (function () { function ThrottledOperations(host) { this.host = host; @@ -76550,6 +77687,11 @@ var ts; return GcTimer; }()); server.GcTimer = GcTimer; + })(server = ts.server || (ts.server = {})); +})(ts || (ts = {})); +(function (ts) { + var server; + (function (server) { function insertSorted(array, insert, compare) { if (array.length === 0) { array.push(insert); @@ -76575,6 +77717,51 @@ var ts; } } server.removeSorted = removeSorted; + function toSortedArray(arr, comparer) { + arr.sort(comparer); + return arr; + } + server.toSortedArray = toSortedArray; + function toDeduplicatedSortedArray(arr) { + arr.sort(); + ts.filterMutate(arr, isNonDuplicateInSortedArray); + return arr; + } + server.toDeduplicatedSortedArray = toDeduplicatedSortedArray; + function isNonDuplicateInSortedArray(value, index, array) { + return index === 0 || value !== array[index - 1]; + } + function enumerateInsertsAndDeletes(newItems, oldItems, inserted, deleted, compare) { + compare = compare || ts.compareValues; + var newIndex = 0; + var oldIndex = 0; + var newLen = newItems.length; + var oldLen = oldItems.length; + while (newIndex < newLen && oldIndex < oldLen) { + var newItem = newItems[newIndex]; + var oldItem = oldItems[oldIndex]; + var compareResult = compare(newItem, oldItem); + if (compareResult === -1) { + inserted(newItem); + newIndex++; + } + else if (compareResult === 1) { + deleted(oldItem); + oldIndex++; + } + else { + newIndex++; + oldIndex++; + } + } + while (newIndex < newLen) { + inserted(newItems[newIndex++]); + } + while (oldIndex < oldLen) { + deleted(oldItems[oldIndex++]); + } + } + server.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); var ts; @@ -76713,7 +77900,7 @@ var ts; } TextStorage.prototype.getVersion = function () { return this.svc - ? "SVC-" + this.svcVersion + "-" + this.svc.getSnapshot().version + ? "SVC-" + this.svcVersion + "-" + this.svc.getSnapshotVersion() : "Text-" + this.textVersion; }; TextStorage.prototype.hasScriptVersionCache = function () { @@ -76751,7 +77938,7 @@ var ts; : ts.ScriptSnapshot.fromString(this.getOrLoadText()); }; TextStorage.prototype.getLineInfo = function (line) { - return this.switchToScriptVersionCache().getSnapshot().index.lineNumberToInfo(line); + return this.switchToScriptVersionCache().getLineInfo(line); }; TextStorage.prototype.lineToTextSpan = function (line) { if (!this.svc) { @@ -76760,23 +77947,20 @@ var ts; var end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length; return ts.createTextSpanFromBounds(start, end); } - var index = this.svc.getSnapshot().index; - var _a = index.lineNumberToInfo(line + 1), lineText = _a.lineText, absolutePosition = _a.absolutePosition; - var len = lineText !== undefined ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition; - return ts.createTextSpan(absolutePosition, len); + return this.svc.lineToTextSpan(line); }; TextStorage.prototype.lineOffsetToPosition = function (line, offset) { if (!this.svc) { return ts.computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text); } - return this.svc.getSnapshot().index.absolutePositionOfStartOfLine(line) + (offset - 1); + return this.svc.lineOffsetToPosition(line, offset); }; TextStorage.prototype.positionToLineOffset = function (position) { if (!this.svc) { var _a = ts.computeLineAndCharacterOfPosition(this.getLineMap(), position), line = _a.line, character = _a.character; return { line: line + 1, offset: character + 1 }; } - return this.svc.getSnapshot().index.positionToLineOffset(position); + return this.svc.positionToLineOffset(position); }; TextStorage.prototype.getFileText = function (tempFileName) { return this.host.readFile(tempFileName || this.fileName) || ""; @@ -77685,7 +78869,8 @@ var ts; log("Loading " + moduleName + " from " + initialDir + " (resolved to " + resolvedPath + ")"); var result = host.require(resolvedPath, moduleName); if (result.error) { - log("Failed to load module: " + JSON.stringify(result.error)); + var err = result.error.stack || result.error.message || JSON.stringify(result.error); + log("Failed to load module '" + moduleName + "': " + err); return undefined; } return result.module; @@ -77815,7 +79000,7 @@ var ts; return ts.map(this.program.getSourceFiles(), function (sourceFile) { var scriptInfo = _this.projectService.getScriptInfoForPath(sourceFile.path); if (!scriptInfo) { - ts.Debug.assert(false, "scriptInfo for a file '" + sourceFile.fileName + "' is missing."); + ts.Debug.fail("scriptInfo for a file '" + sourceFile.fileName + "' is missing."); } return scriptInfo; }); @@ -77977,7 +79162,7 @@ var ts; var sourceFile = _b[_a]; this.extractUnresolvedImportsFromSourceFile(sourceFile, result); } - this.lastCachedUnresolvedImportsList = server.toSortedArray(result); + this.lastCachedUnresolvedImportsList = server.toDeduplicatedSortedArray(result); } unresolvedImports = this.lastCachedUnresolvedImportsList; var cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, unresolvedImports, hasChanges); @@ -78029,7 +79214,7 @@ var ts; fileWatcher.close(); } }); - var _loop_8 = function (missingFilePath) { + var _loop_9 = function (missingFilePath) { if (!this_1.missingFilesMap.has(missingFilePath)) { var fileWatcher_1 = this_1.projectService.host.watchFile(missingFilePath, function (_filename, eventKind) { if (eventKind === ts.FileWatcherEventKind.Created && _this.missingFilesMap.has(missingFilePath)) { @@ -78045,7 +79230,7 @@ var ts; var this_1 = this; for (var _b = 0, missingFilePaths_1 = missingFilePaths; _b < missingFilePaths_1.length; _b++) { var missingFilePath = missingFilePaths_1[_b]; - _loop_8(missingFilePath); + _loop_9(missingFilePath); } } var oldExternalFiles = this.externalFiles || server.emptyArray; @@ -78209,10 +79394,11 @@ var ts; server.Project = Project; var InferredProject = (function (_super) { __extends(InferredProject, _super); - function InferredProject(projectService, documentRegistry, compilerOptions) { + function InferredProject(projectService, documentRegistry, compilerOptions, projectRootPath) { var _this = _super.call(this, InferredProject.newName(), ProjectKind.Inferred, projectService, documentRegistry, undefined, true, compilerOptions, false) || this; _this._isJsInferredProject = false; _this.directoriesWatchedForTsconfig = []; + _this.projectRootPath = projectRootPath; return _this; } InferredProject.prototype.toggleJsInferredProject = function (isJsInferredProject) { @@ -78316,7 +79502,7 @@ var ts; } } if (this.projectService.globalPlugins) { - var _loop_9 = function (globalPluginName) { + var _loop_10 = function (globalPluginName) { if (options.plugins && options.plugins.some(function (p) { return p.name === globalPluginName; })) return "continue"; this_2.enablePlugin({ name: globalPluginName, global: true }, searchPaths); @@ -78324,7 +79510,7 @@ var ts; var this_2 = this; for (var _b = 0, _c = this.projectService.globalPlugins; _b < _c.length; _b++) { var globalPluginName = _c[_b]; - _loop_9(globalPluginName); + _loop_10(globalPluginName); } } }; @@ -78447,10 +79633,12 @@ var ts; } this.typeRootsWatchers = undefined; } - this.directoriesWatchedForWildcards.forEach(function (watcher) { - watcher.close(); - }); - this.directoriesWatchedForWildcards = undefined; + if (this.directoriesWatchedForWildcards) { + this.directoriesWatchedForWildcards.forEach(function (watcher) { + watcher.close(); + }); + this.directoriesWatchedForWildcards = undefined; + } this.stopWatchingDirectory(); }; ConfiguredProject.prototype.addOpenRef = function () { @@ -78680,6 +79868,7 @@ var ts; this.inferredProjects = []; this.configuredProjects = []; this.openFiles = []; + this.compilerOptionsForInferredProjectsPerProjectRoot = ts.createMap(); this.projectToSizeMap = ts.createMap(); this.safelist = defaultTypeSafeList; this.seenProjects = ts.createMap(); @@ -78687,6 +79876,7 @@ var ts; this.logger = opts.logger; this.cancellationToken = opts.cancellationToken; this.useSingleInferredProject = opts.useSingleInferredProject; + this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot; this.typingsInstaller = opts.typingsInstaller || server.nullTypingsInstaller; this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = opts.eventHandler; @@ -78719,10 +79909,11 @@ var ts; if (!this.eventHandler) { return; } - this.eventHandler({ + var event = { eventName: server.ProjectLanguageServiceStateEvent, data: { project: project, languageServiceEnabled: languageServiceEnabled } - }); + }; + this.eventHandler(event); }; ProjectService.prototype.updateTypingsForProject = function (response) { var project = this.findProject(response.projectName); @@ -78739,16 +79930,28 @@ var ts; } project.updateGraph(); }; - ProjectService.prototype.setCompilerOptionsForInferredProjects = function (projectCompilerOptions) { - this.compilerOptionsForInferredProjects = convertCompilerOptions(projectCompilerOptions); - this.compilerOptionsForInferredProjects.allowNonTsExtensions = true; - this.compileOnSaveForInferredProjects = projectCompilerOptions.compileOnSave; + ProjectService.prototype.setCompilerOptionsForInferredProjects = function (projectCompilerOptions, projectRootPath) { + ts.Debug.assert(projectRootPath === undefined || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled"); + var compilerOptions = convertCompilerOptions(projectCompilerOptions); + compilerOptions.allowNonTsExtensions = true; + if (projectRootPath) { + this.compilerOptionsForInferredProjectsPerProjectRoot.set(projectRootPath, compilerOptions); + } + else { + this.compilerOptionsForInferredProjects = compilerOptions; + } + var updatedProjects = []; for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { - var proj = _a[_i]; - proj.setCompilerOptions(this.compilerOptionsForInferredProjects); - proj.compileOnSaveEnabled = projectCompilerOptions.compileOnSave; + var project = _a[_i]; + if (projectRootPath ? + project.projectRootPath === projectRootPath : + !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { + project.setCompilerOptions(compilerOptions); + project.compileOnSaveEnabled = compilerOptions.compileOnSave; + updatedProjects.push(project); + } } - this.updateProjectGraphs(this.inferredProjects); + this.updateProjectGraphs(updatedProjects); }; ProjectService.prototype.stopWatchingDirectory = function (directory) { this.directoryWatchers.stopWatchingDirectory(directory); @@ -78855,10 +80058,11 @@ var ts; } for (var _i = 0, _a = this.openFiles; _i < _a.length; _i++) { var openFile = _a[_i]; - this.eventHandler({ + var event = { eventName: server.ContextEvent, data: { project: openFile.getDefaultProject(), fileName: openFile.fileName } - }); + }; + this.eventHandler(event); } } this.printProjects(); @@ -78930,7 +80134,7 @@ var ts; break; } }; - ProjectService.prototype.assignScriptInfoToInferredProjectIfNecessary = function (info, addToListOfOpenFiles) { + ProjectService.prototype.assignScriptInfoToInferredProjectIfNecessary = function (info, addToListOfOpenFiles, projectRootPath) { var externalProject = this.findContainingExternalProject(info.fileName); if (externalProject) { if (addToListOfOpenFiles) { @@ -78955,19 +80159,19 @@ var ts; return; } if (info.containingProjects.length === 0) { - var inferredProject = this.createInferredProjectWithRootFileIfNecessary(info); - if (!this.useSingleInferredProject) { + var inferredProject = this.createInferredProjectWithRootFileIfNecessary(info, projectRootPath); + if (!this.useSingleInferredProject && !inferredProject.projectRootPath) { for (var _b = 0, _c = this.openFiles; _b < _c.length; _b++) { var f = _c[_b]; if (f.containingProjects.length === 0 || !inferredProject.containsScriptInfo(f)) { continue; } for (var _d = 0, _e = f.containingProjects; _d < _e.length; _d++) { - var fContainingProject = _e[_d]; - if (fContainingProject.projectKind === server.ProjectKind.Inferred && - fContainingProject.isRoot(f) && - fContainingProject !== inferredProject) { - this.removeProject(fContainingProject); + var containingProject = _e[_d]; + if (containingProject.projectKind === server.ProjectKind.Inferred && + containingProject !== inferredProject && + containingProject.isRoot(f)) { + this.removeProject(containingProject); f.attachToProject(inferredProject); } } @@ -79078,31 +80282,32 @@ var ts; return undefined; }; ProjectService.prototype.printProjects = function () { + var _this = this; if (!this.logger.hasLevel(server.LogLevel.verbose)) { return; } this.logger.startGroup(); var counter = 0; - counter = printProjects(this.logger, this.externalProjects, counter); - counter = printProjects(this.logger, this.configuredProjects, counter); - counter = printProjects(this.logger, this.inferredProjects, counter); - this.logger.info("Open files: "); - for (var _i = 0, _a = this.openFiles; _i < _a.length; _i++) { - var rootFile = _a[_i]; - this.logger.info("\t" + rootFile.fileName); - } - this.logger.endGroup(); - function printProjects(logger, projects, counter) { + var printProjects = function (projects, counter) { for (var _i = 0, projects_3 = projects; _i < projects_3.length; _i++) { var project = projects_3[_i]; project.updateGraph(); - logger.info("Project '" + project.getProjectName() + "' (" + server.ProjectKind[project.projectKind] + ") " + counter); - logger.info(project.filesToString()); - logger.info("-----------------------------------------------"); + _this.logger.info("Project '" + project.getProjectName() + "' (" + server.ProjectKind[project.projectKind] + ") " + counter); + _this.logger.info(project.filesToString()); + _this.logger.info("-----------------------------------------------"); counter++; } return counter; + }; + counter = printProjects(this.externalProjects, counter); + counter = printProjects(this.configuredProjects, counter); + printProjects(this.inferredProjects, counter); + this.logger.info("Open files: "); + for (var _i = 0, _a = this.openFiles; _i < _a.length; _i++) { + var rootFile = _a[_i]; + this.logger.info("\t" + rootFile.fileName); } + this.logger.endGroup(); }; ProjectService.prototype.findConfiguredProjectByProjectName = function (configFileName) { configFileName = server.asNormalizedPath(this.toCanonicalFileName(configFileName)); @@ -79223,10 +80428,11 @@ var ts; if (!this.eventHandler) { return; } - this.eventHandler({ + var event = { eventName: server.ConfigFileDiagEvent, - data: { configFileName: configFileName, diagnostics: diagnostics || [], triggerFile: triggerFile } - }); + data: { configFileName: configFileName, diagnostics: diagnostics || server.emptyArray, triggerFile: triggerFile } + }; + this.eventHandler(event); }; ProjectService.prototype.createAndAddConfiguredProject = function (configFileName, projectOptions, configFileErrors, clientFileName) { var _this = this; @@ -79375,18 +80581,60 @@ var ts; } return configFileErrors; }; - ProjectService.prototype.createInferredProjectWithRootFileIfNecessary = function (root) { + ProjectService.prototype.getOrCreateInferredProjectForProjectRootPathIfEnabled = function (root, projectRootPath) { + if (!this.useInferredProjectPerProjectRoot) { + return undefined; + } + if (projectRootPath) { + for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { + var project = _a[_i]; + if (project.projectRootPath === projectRootPath) { + return project; + } + } + return this.createInferredProject(false, projectRootPath); + } + var bestMatch; + for (var _b = 0, _c = this.inferredProjects; _b < _c.length; _b++) { + var project = _c[_b]; + if (!project.projectRootPath) + continue; + if (!ts.containsPath(project.projectRootPath, root.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) + continue; + if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) + continue; + bestMatch = project; + } + return bestMatch; + }; + ProjectService.prototype.getOrCreateSingleInferredProjectIfEnabled = function () { + if (!this.useSingleInferredProject) { + return undefined; + } + if (this.inferredProjects.length > 0 && this.inferredProjects[0].projectRootPath === undefined) { + return this.inferredProjects[0]; + } + return this.createInferredProject(true); + }; + ProjectService.prototype.createInferredProject = function (isSingleInferredProject, projectRootPath) { + var compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects; + var project = new server.InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath); + if (isSingleInferredProject) { + this.inferredProjects.unshift(project); + } + else { + this.inferredProjects.push(project); + } + return project; + }; + ProjectService.prototype.createInferredProjectWithRootFileIfNecessary = function (root, projectRootPath) { var _this = this; - var useExistingProject = this.useSingleInferredProject && this.inferredProjects.length; - var project = useExistingProject - ? this.inferredProjects[0] - : new server.InferredProject(this, this.documentRegistry, this.compilerOptionsForInferredProjects); + var project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(root, projectRootPath) || + this.getOrCreateSingleInferredProjectIfEnabled() || + this.createInferredProject(); project.addRoot(root); this.directoryWatchers.startWatchingContainingDirectoriesForFile(root.fileName, project, function (fileName) { return _this.onConfigFileAddedForInferredProject(fileName); }); project.updateGraph(); - if (!useExistingProject) { - this.inferredProjects.push(project); - } return project; }; ProjectService.prototype.getOrCreateScriptInfo = function (uncheckedFileName, openedByClient, fileContent, scriptKind) { @@ -79519,7 +80767,7 @@ var ts; project.markAsDirty(); } var info = this.getOrCreateScriptInfoForNormalizedPath(fileName, true, fileContent, scriptKind, hasMixedContent); - this.assignScriptInfoToInferredProjectIfNecessary(info, true); + this.assignScriptInfoToInferredProjectIfNecessary(info, true, projectRootPath); this.deleteOrphanScriptInfoNotInAnyProject(); this.printProjects(); return { configFileName: configFileName, configFileErrors: configFileErrors }; @@ -79533,13 +80781,13 @@ var ts; this.printProjects(); }; ProjectService.prototype.collectChanges = function (lastKnownProjectVersions, currentProjects, result) { - var _loop_10 = function (proj) { + var _loop_11 = function (proj) { var knownProject = ts.forEach(lastKnownProjectVersions, function (p) { return p.projectName === proj.getProjectName() && p; }); result.push(proj.getChangesSinceVersion(knownProject && knownProject.version)); }; for (var _i = 0, currentProjects_1 = currentProjects; _i < currentProjects_1.length; _i++) { var proj = currentProjects_1[_i]; - _loop_10(proj); + _loop_11(proj); } }; ProjectService.prototype.synchronizeProjectList = function (knownProjects) { @@ -79658,7 +80906,7 @@ var ts; var types = (typeAcquisition && typeAcquisition.include) || []; var excludeRules = []; var normalizedNames = rootFiles.map(function (f) { return ts.normalizeSlashes(f.fileName); }); - var _loop_11 = function (name) { + var _loop_12 = function (name) { var rule = this_3.safelist[name]; for (var _i = 0, normalizedNames_1 = normalizedNames; _i < normalizedNames_1.length; _i++) { var root = normalizedNames_1[_i]; @@ -79673,7 +80921,7 @@ var ts; } } if (rule.exclude) { - var _loop_12 = function (exclude) { + var _loop_13 = function (exclude) { var processedRule = root.replace(rule.match, function () { var groups = []; for (var _i = 0; _i < arguments.length; _i++) { @@ -79696,7 +80944,7 @@ var ts; }; for (var _c = 0, _d = rule.exclude; _c < _d.length; _c++) { var exclude = _d[_c]; - _loop_12(exclude); + _loop_13(exclude); } } else { @@ -79715,7 +80963,7 @@ var ts; var this_3 = this; for (var _i = 0, _a = Object.keys(this.safelist); _i < _a.length; _i++) { var name = _a[_i]; - _loop_11(name); + _loop_12(name); } var excludeRegexes = excludeRules.map(function (e) { return new RegExp(e, "i"); }); proj.rootFiles = proj.rootFiles.filter(function (_file, index) { return !excludeRegexes.some(function (re) { return re.test(normalizedNames[index]); }); }); @@ -79904,20 +81152,16 @@ var ts; var MultistepOperation = (function () { function MultistepOperation(operationHost) { this.operationHost = operationHost; - this.completed = true; } MultistepOperation.prototype.startNew = function (action) { this.complete(); this.requestId = this.operationHost.getCurrentRequestId(); - this.completed = false; this.executeAction(action); }; MultistepOperation.prototype.complete = function () { - if (!this.completed) { - if (this.requestId) { - this.operationHost.sendRequestCompletedEvent(this.requestId); - } - this.completed = true; + if (this.requestId !== undefined) { + this.operationHost.sendRequestCompletedEvent(this.requestId); + this.requestId = undefined; } this.setTimerHandle(undefined); this.setImmediateId(undefined); @@ -80253,6 +81497,7 @@ var ts; logger: this.logger, cancellationToken: this.cancellationToken, useSingleInferredProject: opts.useSingleInferredProject, + useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot, typingsInstaller: this.typingsInstaller, throttleWaitMilliseconds: throttleWaitMilliseconds, eventHandler: this.eventHandler, @@ -80279,7 +81524,7 @@ var ts; case server.ContextEvent: var _a = event.data, project_1 = _a.project, fileName_3 = _a.fileName; this.projectService.logger.info("got context event, updating diagnostics for " + fileName_3); - this.errorCheck.startNew(function (next) { return _this.updateErrorCheck(next, [{ fileName: fileName_3, project: project_1 }], _this.changeSeq, function (n) { return n === _this.changeSeq; }, 100); }); + this.errorCheck.startNew(function (next) { return _this.updateErrorCheck(next, [{ fileName: fileName_3, project: project_1 }], 100); }); break; case server.ConfigFileDiagEvent: var _b = event.data, triggerFile = _b.triggerFile, configFileName = _b.configFileName, diagnostics = _b.diagnostics; @@ -80387,26 +81632,24 @@ var ts; this.logError(err, "syntactic check"); } }; - Session.prototype.updateProjectStructure = function (seq, matchSeq, ms) { + Session.prototype.updateProjectStructure = function () { var _this = this; - if (ms === void 0) { ms = 1500; } + var ms = 1500; + var seq = this.changeSeq; this.host.setTimeout(function () { - if (matchSeq(seq)) { + if (_this.changeSeq === seq) { _this.projectService.refreshInferredProjects(); } }, ms); }; - Session.prototype.updateErrorCheck = function (next, checkList, seq, matchSeq, ms, followMs, requireOpen) { + Session.prototype.updateErrorCheck = function (next, checkList, ms, requireOpen) { var _this = this; - if (ms === void 0) { ms = 1500; } - if (followMs === void 0) { followMs = 200; } if (requireOpen === void 0) { requireOpen = true; } - if (followMs > ms) { - followMs = ms; - } + var seq = this.changeSeq; + var followMs = Math.min(ms, 200); var index = 0; var checkOne = function () { - if (matchSeq(seq)) { + if (_this.changeSeq === seq) { var checkSpec_1 = checkList[index]; index++; if (checkSpec_1.project.containsFile(checkSpec_1.fileName, requireOpen)) { @@ -80420,7 +81663,7 @@ var ts; } } }; - if ((checkList.length > index) && (matchSeq(seq))) { + if (checkList.length > index && this.changeSeq === seq) { next.delay(ms, checkOne); } }; @@ -80498,7 +81741,7 @@ var ts; Session.prototype.getDiagnosticsWorker = function (args, isSemantic, selector, includeLinePosition) { var _a = this.getFileAndProject(args), project = _a.project, file = _a.file; if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { - return []; + return server.emptyArray; } var scriptInfo = project.getScriptInfoForNormalizedPath(file); var diagnostics = selector(project, file); @@ -80550,7 +81793,7 @@ var ts; var position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file)); var implementations = project.getLanguageService().getImplementationAtPosition(file, position); if (!implementations) { - return []; + return server.emptyArray; } if (simplifiedResult) { return implementations.map(function (_a) { @@ -80595,7 +81838,7 @@ var ts; Session.prototype.getSyntacticDiagnosticsSync = function (args) { var configFile = this.getConfigFileAndProject(args).configFile; if (configFile) { - return []; + return server.emptyArray; } return this.getDiagnosticsWorker(args, false, function (project, file) { return project.getLanguageService().getSyntacticDiagnostics(file); }, args.includeLinePosition); }; @@ -80636,7 +81879,7 @@ var ts; } }; Session.prototype.setCompilerOptionsForInferredProjects = function (args) { - this.projectService.setCompilerOptionsForInferredProjects(args.options); + this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath); }; Session.prototype.getProjectInfo = function (args) { return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, false); @@ -80698,13 +81941,13 @@ var ts; if (!renameInfo.canRename) { return { info: renameInfo, - locs: [] + locs: server.emptyArray }; } var fileSpans = server.combineProjectOutput(projects, function (project) { var renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments); if (!renameLocations) { - return []; + return server.emptyArray; } return renameLocations.map(function (location) { var locationScriptInfo = project.getScriptInfo(location.fileName); @@ -80785,7 +82028,7 @@ var ts; var refs = server.combineProjectOutput(projects, function (project) { var references = project.getLanguageService().getReferencesAtPosition(file, position); if (!references) { - return []; + return server.emptyArray; } return references.map(function (ref) { var refScriptInfo = project.getScriptInfo(ref.fileName); @@ -80826,7 +82069,7 @@ var ts; if (this.eventHandler) { this.eventHandler({ eventName: "configFileDiag", - data: { triggerFile: fileName, configFileName: configFileName, diagnostics: configFileErrors || [] } + data: { triggerFile: fileName, configFileName: configFileName, diagnostics: configFileErrors || server.emptyArray } }); } }; @@ -81014,7 +82257,7 @@ var ts; var info = this.projectService.getScriptInfo(args.file); var result = []; if (!info) { - return []; + return server.emptyArray; } var projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects; for (var _i = 0, projectsToSearch_1 = projectsToSearch; _i < projectsToSearch_1.length; _i++) { @@ -81074,11 +82317,10 @@ var ts; return project && { fileName: fileName, project: project }; }); if (checkList.length > 0) { - this.updateErrorCheck(next, checkList, this.changeSeq, function (n) { return n === _this.changeSeq; }, delay); + this.updateErrorCheck(next, checkList, delay); } }; Session.prototype.change = function (args) { - var _this = this; var _a = this.getFileAndProject(args, false), file = _a.file, project = _a.project; if (project) { var scriptInfo = project.getScriptInfoForNormalizedPath(file); @@ -81088,7 +82330,7 @@ var ts; scriptInfo.editContent(start, end, args.insertString); this.changeSeq++; } - this.updateProjectStructure(this.changeSeq, function (n) { return n === _this.changeSeq; }); + this.updateProjectStructure(); } }; Session.prototype.reload = function (args, reqSeq) { @@ -81167,7 +82409,7 @@ var ts; return server.combineProjectOutput(projects, function (project) { var navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, project.isNonTsProject()); if (!navItems) { - return []; + return server.emptyArray; } return navItems.map(function (navItem) { var scriptInfo = project.getScriptInfo(navItem.fileName); @@ -81357,7 +82599,6 @@ var ts; : spans; }; Session.prototype.getDiagnosticsForProject = function (next, delay, fileName) { - var _this = this; var _a = this.getProjectInfoWorker(fileName, undefined, true, true), fileNames = _a.fileNames, languageServiceDisabled = _a.languageServiceDisabled; if (languageServiceDisabled) { return; @@ -81392,7 +82633,7 @@ var ts; fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles); if (fileNamesInProject.length > 0) { var checkList = fileNamesInProject.map(function (fileName) { return ({ fileName: fileName, project: project }); }); - this.updateErrorCheck(next, checkList, this.changeSeq, function (n) { return n === _this.changeSeq; }, delay, 200, false); + this.updateErrorCheck(next, checkList, delay, false); } }; Session.prototype.getCanonicalFileName = function (fileName) { @@ -81499,13 +82740,13 @@ var ts; CharRangeSection[CharRangeSection["Mid"] = 3] = "Mid"; CharRangeSection[CharRangeSection["End"] = 4] = "End"; CharRangeSection[CharRangeSection["PostEnd"] = 5] = "PostEnd"; - })(CharRangeSection = server.CharRangeSection || (server.CharRangeSection = {})); + })(CharRangeSection || (CharRangeSection = {})); var EditWalker = (function () { function EditWalker() { this.goSubtree = true; this.lineIndex = new LineIndex(); this.endBranch = []; - this.state = CharRangeSection.Entire; + this.state = 2; this.initialText = ""; this.trailingText = ""; this.lineIndex.root = new LineNode(); @@ -81594,14 +82835,14 @@ var ts; }; EditWalker.prototype.post = function (_relativeStart, _relativeLength, lineCollection) { if (lineCollection === this.lineCollectionAtBranch) { - this.state = CharRangeSection.End; + this.state = 4; } this.stack.pop(); }; EditWalker.prototype.pre = function (_relativeStart, _relativeLength, lineCollection, _parent, nodeType) { var currentNode = this.stack[this.stack.length - 1]; - if ((this.state === CharRangeSection.Entire) && (nodeType === CharRangeSection.Start)) { - this.state = CharRangeSection.Start; + if ((this.state === 2) && (nodeType === 1)) { + this.state = 1; this.branchNode = currentNode; this.lineCollectionAtBranch = lineCollection; } @@ -81614,14 +82855,14 @@ var ts; return new LineNode(); } switch (nodeType) { - case CharRangeSection.PreStart: + case 0: this.goSubtree = false; - if (this.state !== CharRangeSection.End) { + if (this.state !== 4) { currentNode.add(lineCollection); } break; - case CharRangeSection.Start: - if (this.state === CharRangeSection.End) { + case 1: + if (this.state === 4) { this.goSubtree = false; } else { @@ -81630,8 +82871,8 @@ var ts; this.startPath.push(child); } break; - case CharRangeSection.Entire: - if (this.state !== CharRangeSection.End) { + case 2: + if (this.state !== 4) { child = fresh(lineCollection); currentNode.add(child); this.startPath.push(child); @@ -81644,11 +82885,11 @@ var ts; } } break; - case CharRangeSection.Mid: + case 3: this.goSubtree = false; break; - case CharRangeSection.End: - if (this.state !== CharRangeSection.End) { + case 4: + if (this.state !== 4) { this.goSubtree = false; } else { @@ -81659,9 +82900,9 @@ var ts; } } break; - case CharRangeSection.PostEnd: + case 5: this.goSubtree = false; - if (this.state !== CharRangeSection.Start) { + if (this.state !== 1) { currentNode.add(lineCollection); } break; @@ -81671,10 +82912,10 @@ var ts; } }; EditWalker.prototype.leaf = function (relativeStart, relativeLength, ll) { - if (this.state === CharRangeSection.Start) { + if (this.state === 1) { this.initialText = ll.text.substring(0, relativeStart); } - else if (this.state === CharRangeSection.Entire) { + else if (this.state === 2) { this.initialText = ll.text.substring(0, relativeStart); this.trailingText = ll.text.substring(relativeStart + relativeLength); } @@ -81695,7 +82936,6 @@ var ts; }; return TextChange; }()); - server.TextChange = TextChange; var ScriptVersionCache = (function () { function ScriptVersionCache() { this.changes = []; @@ -81720,15 +82960,6 @@ var ts; this.getSnapshot(); } }; - ScriptVersionCache.prototype.latest = function () { - return this.versions[this.currentVersionToIndex()]; - }; - ScriptVersionCache.prototype.latestVersion = function () { - if (this.changes.length > 0) { - this.getSnapshot(); - } - return this.currentVersion; - }; ScriptVersionCache.prototype.reload = function (script) { this.currentVersion++; this.changes = []; @@ -81741,7 +82972,8 @@ var ts; snap.index.load(lm.lines); this.minVersion = this.currentVersion; }; - ScriptVersionCache.prototype.getSnapshot = function () { + ScriptVersionCache.prototype.getSnapshot = function () { return this._getSnapshot(); }; + ScriptVersionCache.prototype._getSnapshot = function () { var snap = this.versions[this.currentVersionToIndex()]; if (this.changes.length > 0) { var snapIndex = snap.index; @@ -81759,6 +82991,24 @@ var ts; } return snap; }; + ScriptVersionCache.prototype.getSnapshotVersion = function () { + return this._getSnapshot().version; + }; + ScriptVersionCache.prototype.getLineInfo = function (line) { + return this._getSnapshot().index.lineNumberToInfo(line); + }; + ScriptVersionCache.prototype.lineOffsetToPosition = function (line, column) { + return this._getSnapshot().index.absolutePositionOfStartOfLine(line) + (column - 1); + }; + ScriptVersionCache.prototype.positionToLineOffset = function (position) { + return this._getSnapshot().index.positionToLineOffset(position); + }; + ScriptVersionCache.prototype.lineToTextSpan = function (line) { + var index = this._getSnapshot().index; + var _a = index.lineNumberToInfo(line + 1), lineText = _a.lineText, absolutePosition = _a.absolutePosition; + var len = lineText !== undefined ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition; + return ts.createTextSpan(absolutePosition, len); + }; ScriptVersionCache.prototype.getTextChangesBetweenVersions = function (oldVersion, newVersion) { if (oldVersion < newVersion) { if (oldVersion >= this.minVersion) { @@ -81820,7 +83070,6 @@ var ts; }; return LineIndexSnapshot; }()); - server.LineIndexSnapshot = LineIndexSnapshot; var LineIndex = (function () { function LineIndex() { this.checkEdits = false; @@ -82019,18 +83268,18 @@ var ts; var childCharCount = this.children[childIndex].charCount(); var adjustedStart = rangeStart; while (adjustedStart >= childCharCount) { - this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, CharRangeSection.PreStart); + this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, 0); adjustedStart -= childCharCount; childIndex++; childCharCount = this.children[childIndex].charCount(); } if ((adjustedStart + rangeLength) <= childCharCount) { - if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, CharRangeSection.Entire)) { + if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, 2)) { return; } } else { - if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, CharRangeSection.Start)) { + if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, 1)) { return; } var adjustedLength = rangeLength - (childCharCount - adjustedStart); @@ -82038,7 +83287,7 @@ var ts; var child = this.children[childIndex]; childCharCount = child.charCount(); while (adjustedLength > childCharCount) { - if (this.execWalk(0, childCharCount, walkFns, childIndex, CharRangeSection.Mid)) { + if (this.execWalk(0, childCharCount, walkFns, childIndex, 3)) { return; } adjustedLength -= childCharCount; @@ -82046,7 +83295,7 @@ var ts; childCharCount = this.children[childIndex].charCount(); } if (adjustedLength > 0) { - if (this.execWalk(0, adjustedLength, walkFns, childIndex, CharRangeSection.End)) { + if (this.execWalk(0, adjustedLength, walkFns, childIndex, 4)) { return; } } @@ -82055,82 +83304,46 @@ var ts; var clen = this.children.length; if (childIndex < (clen - 1)) { for (var ej = childIndex + 1; ej < clen; ej++) { - this.skipChild(0, 0, ej, walkFns, CharRangeSection.PostEnd); + this.skipChild(0, 0, ej, walkFns, 5); } } } }; LineNode.prototype.charOffsetToLineInfo = function (lineNumberAccumulator, relativePosition) { - var childInfo = this.childFromCharOffset(lineNumberAccumulator, relativePosition); - if (!childInfo.child) { - return { - oneBasedLine: lineNumberAccumulator, - zeroBasedColumn: relativePosition, - lineText: undefined, - }; + if (this.children.length === 0) { + return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: undefined }; } - else if (childInfo.childIndex < this.children.length) { - if (childInfo.child.isLeaf()) { - return { - oneBasedLine: childInfo.lineNumberAccumulator, - zeroBasedColumn: childInfo.relativePosition, - lineText: childInfo.child.text, - }; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (child.charCount() > relativePosition) { + if (child.isLeaf()) { + return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: child.text }; + } + else { + return child.charOffsetToLineInfo(lineNumberAccumulator, relativePosition); + } } else { - var lineNode = (childInfo.child); - return lineNode.charOffsetToLineInfo(childInfo.lineNumberAccumulator, childInfo.relativePosition); + relativePosition -= child.charCount(); + lineNumberAccumulator += child.lineCount(); } } - else { - var lineInfo = this.lineNumberToInfo(this.lineCount(), 0); - return { oneBasedLine: this.lineCount(), zeroBasedColumn: lineInfo.leaf.charCount(), lineText: undefined }; - } + var leaf = this.lineNumberToInfo(this.lineCount(), 0).leaf; + return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf.charCount(), lineText: undefined }; }; LineNode.prototype.lineNumberToInfo = function (relativeOneBasedLine, positionAccumulator) { - var childInfo = this.childFromLineNumber(relativeOneBasedLine, positionAccumulator); - if (!childInfo.child) { - return { position: positionAccumulator, leaf: undefined }; - } - else if (childInfo.child.isLeaf()) { - return { position: childInfo.positionAccumulator, leaf: childInfo.child }; - } - else { - var lineNode = (childInfo.child); - return lineNode.lineNumberToInfo(childInfo.relativeOneBasedLine, childInfo.positionAccumulator); - } - }; - LineNode.prototype.childFromLineNumber = function (relativeOneBasedLine, positionAccumulator) { - var child; - var i; - for (i = 0; i < this.children.length; i++) { - child = this.children[i]; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; var childLineCount = child.lineCount(); if (childLineCount >= relativeOneBasedLine) { - break; + return child.isLeaf() ? { position: positionAccumulator, leaf: child } : child.lineNumberToInfo(relativeOneBasedLine, positionAccumulator); } else { relativeOneBasedLine -= childLineCount; positionAccumulator += child.charCount(); } } - return { child: child, relativeOneBasedLine: relativeOneBasedLine, positionAccumulator: positionAccumulator }; - }; - LineNode.prototype.childFromCharOffset = function (lineNumberAccumulator, relativePosition) { - var child; - var i; - var len; - for (i = 0, len = this.children.length; i < len; i++) { - child = this.children[i]; - if (child.charCount() > relativePosition) { - break; - } - else { - relativePosition -= child.charCount(); - lineNumberAccumulator += child.lineCount(); - } - } - return { child: child, childIndex: i, relativePosition: relativePosition, lineNumberAccumulator: lineNumberAccumulator }; + return { position: positionAccumulator, leaf: undefined }; }; LineNode.prototype.splitAfter = function (childIndex) { var splitNode; @@ -82227,7 +83440,6 @@ var ts; }; return LineNode; }()); - server.LineNode = LineNode; var LineLeaf = (function () { function LineLeaf(text) { this.text = text; @@ -82246,7 +83458,6 @@ var ts; }; return LineLeaf; }()); - server.LineLeaf = LineLeaf; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); var ts; @@ -82335,14 +83546,15 @@ var ts; Logger.prototype.info = function (s) { this.msg(s, server.Msg.Info); }; + Logger.prototype.err = function (s) { + this.msg(s, server.Msg.Err); + }; Logger.prototype.startGroup = function () { this.inGroup = true; this.firstInGroup = true; }; Logger.prototype.endGroup = function () { this.inGroup = false; - this.seq++; - this.firstInGroup = true; }; Logger.prototype.loggingEnabled = function () { return !!this.logFilename || this.traceToConsole; @@ -82352,24 +83564,32 @@ var ts; }; Logger.prototype.msg = function (s, type) { if (type === void 0) { type = server.Msg.Err; } - if (this.fd >= 0 || this.traceToConsole) { - s = "[" + nowString() + "] " + s + "\n"; + if (!this.canWrite) + return; + s = "[" + nowString() + "] " + s + "\n"; + if (!this.inGroup || this.firstInGroup) { var prefix = Logger.padStringRight(type + " " + this.seq.toString(), " "); - if (this.firstInGroup) { - s = prefix + s; - this.firstInGroup = false; - } - if (!this.inGroup) { - this.seq++; - this.firstInGroup = true; - } - if (this.fd >= 0) { - var buf = new Buffer(s); - fs.writeSync(this.fd, buf, 0, buf.length, null); - } - if (this.traceToConsole) { - console.warn(s); - } + s = prefix + s; + } + this.write(s); + if (!this.inGroup) { + this.seq++; + } + }; + Object.defineProperty(Logger.prototype, "canWrite", { + get: function () { + return this.fd >= 0 || this.traceToConsole; + }, + enumerable: true, + configurable: true + }); + Logger.prototype.write = function (s) { + if (this.fd >= 0) { + var buf = new Buffer(s); + fs.writeSync(this.fd, buf, 0, buf.length, null); + } + if (this.traceToConsole) { + console.warn(s); } }; return Logger; @@ -82538,6 +83758,7 @@ var ts; host: host, cancellationToken: cancellationToken, useSingleInferredProject: useSingleInferredProject, + useInferredProjectPerProjectRoot: useInferredProjectPerProjectRoot, typingsInstaller: typingsInstaller || server.nullTypingsInstaller, byteLength: Buffer.byteLength, hrtime: process.hrtime, @@ -82820,12 +84041,21 @@ var ts; if (localeStr) { ts.validateLocaleAndSetLanguage(localeStr, sys); } + ts.setStackTraceLimit(); var typingSafeListLocation = server.findArgument(server.Arguments.TypingSafeListLocation); var npmLocation = server.findArgument(server.Arguments.NpmLocation); - var globalPlugins = (server.findArgument("--globalPlugins") || "").split(","); - var pluginProbeLocations = (server.findArgument("--pluginProbeLocations") || "").split(","); + function parseStringArray(argName) { + var arg = server.findArgument(argName); + if (arg === undefined) { + return server.emptyArray; + } + return arg.split(",").filter(function (name) { return name !== ""; }); + } + var globalPlugins = parseStringArray("--globalPlugins"); + var pluginProbeLocations = parseStringArray("--pluginProbeLocations"); var allowLocalPluginLoads = server.hasArgument("--allowLocalPluginLoads"); var useSingleInferredProject = server.hasArgument("--useSingleInferredProject"); + var useInferredProjectPerProjectRoot = server.hasArgument("--useInferredProjectPerProjectRoot"); var disableAutomaticTypingAcquisition = server.hasArgument("--disableAutomaticTypingAcquisition"); var telemetryEnabled = server.hasArgument(server.Arguments.EnableTelemetry); var options = { @@ -82834,6 +84064,7 @@ var ts; installerEventPort: eventPort, canUseEvents: eventPort === undefined, useSingleInferredProject: useSingleInferredProject, + useInferredProjectPerProjectRoot: useInferredProjectPerProjectRoot, disableAutomaticTypingAcquisition: disableAutomaticTypingAcquisition, globalTypingsCacheLocation: getGlobalTypingsCacheLocation(), typingSafeListLocation: typingSafeListLocation, diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index fce0d53e6350a..d43f0e03bfff5 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -1175,7 +1175,7 @@ declare namespace ts { interface CatchClause extends Node { kind: SyntaxKind.CatchClause; parent?: TryStatement; - variableDeclaration: VariableDeclaration; + variableDeclaration?: VariableDeclaration; block: Block; } type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; @@ -1452,38 +1452,39 @@ declare namespace ts { interface FlowLock { locked?: boolean; } - interface AfterFinallyFlow extends FlowNode, FlowLock { + interface AfterFinallyFlow extends FlowNodeBase, FlowLock { antecedent: FlowNode; } - interface PreFinallyFlow extends FlowNode { + interface PreFinallyFlow extends FlowNodeBase { antecedent: FlowNode; lock: FlowLock; } - interface FlowNode { + type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + interface FlowNodeBase { flags: FlowFlags; id?: number; } - interface FlowStart extends FlowNode { + interface FlowStart extends FlowNodeBase { container?: FunctionExpression | ArrowFunction | MethodDeclaration; } - interface FlowLabel extends FlowNode { + interface FlowLabel extends FlowNodeBase { antecedents: FlowNode[]; } - interface FlowAssignment extends FlowNode { + interface FlowAssignment extends FlowNodeBase { node: Expression | VariableDeclaration | BindingElement; antecedent: FlowNode; } - interface FlowCondition extends FlowNode { + interface FlowCondition extends FlowNodeBase { expression: Expression; antecedent: FlowNode; } - interface FlowSwitchClause extends FlowNode { + interface FlowSwitchClause extends FlowNodeBase { switchStatement: SwitchStatement; clauseStart: number; clauseEnd: number; antecedent: FlowNode; } - interface FlowArrayMutation extends FlowNode { + interface FlowArrayMutation extends FlowNodeBase { node: CallExpression | BinaryExpression; antecedent: FlowNode; } @@ -1701,6 +1702,7 @@ declare namespace ts { AddUndefined = 8192, WriteClassExpressionAsTypeLiteral = 16384, InArrayType = 32768, + UseAliasDefinedOutsideCurrentScope = 65536, } enum SymbolFormatFlags { None = 0, @@ -1987,6 +1989,12 @@ declare namespace ts { NoDefault = 2, AnyDefault = 4, } + enum Ternary { + False = 0, + Maybe = 1, + True = -1, + } + type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary; interface JsFileExtensionInfo { extension: string; isMixedContent: boolean; @@ -2073,6 +2081,7 @@ declare namespace ts { outFile?: string; paths?: MapLike; preserveConstEnums?: boolean; + preserveSymlinks?: boolean; project?: string; reactNamespace?: string; jsxFactory?: string; @@ -2186,6 +2195,11 @@ declare namespace ts { } interface ResolvedModuleFull extends ResolvedModule { extension: Extension; + packageId?: PackageId; + } + interface PackageId { + name: string; + version: string; } enum Extension { Ts = ".ts", @@ -2402,6 +2416,8 @@ declare namespace ts { function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; function isParameterPropertyDeclaration(node: Node): boolean; + function isEmptyBindingPattern(node: BindingName): node is BindingPattern; + function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; function getCombinedNodeFlags(node: Node): NodeFlags; function validateLocaleAndSetLanguage(locale: string, sys: { @@ -2959,8 +2975,8 @@ declare namespace ts { function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray): DefaultClause; function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray): HeritageClause; function updateHeritageClause(node: HeritageClause, types: ReadonlyArray): HeritageClause; - function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block): CatchClause; - function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block): CatchClause; + function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; + function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; @@ -3687,7 +3703,10 @@ declare namespace ts.server { error: undefined; } | { module: undefined; - error: {}; + error: { + stack?: string; + message?: string; + }; }; interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; @@ -3838,9 +3857,6 @@ declare namespace ts.server { function isInferredProjectName(name: string): boolean; function makeInferredProjectName(counter: number): string; function createSortedArray(): SortedArray; - function toSortedArray(arr: string[]): SortedArray; - function toSortedArray(arr: T[], comparer: Comparer): SortedArray; - function enumerateInsertsAndDeletes(newItems: SortedReadonlyArray, oldItems: SortedReadonlyArray, inserted: (newItem: T) => void, deleted: (oldItem: T) => void, compare?: Comparer): void; class ThrottledOperations { private readonly host; private pendingTimeouts; @@ -3857,8 +3873,6 @@ declare namespace ts.server { scheduleCollect(): void; private static run(self); } - function insertSorted(array: SortedArray, insert: T, compare: Comparer): void; - function removeSorted(array: SortedArray, remove: T, compare: Comparer): void; } declare namespace ts.server.protocol { enum CommandTypes { @@ -4168,7 +4182,7 @@ declare namespace ts.server.protocol { } interface RenameResponseBody { info: RenameInfo; - locs: SpanGroup[]; + locs: ReadonlyArray; } interface RenameResponse extends Response { body?: RenameResponseBody; @@ -4248,6 +4262,7 @@ declare namespace ts.server.protocol { } interface SetCompilerOptionsForInferredProjectsArgs { options: ExternalProjectCompilerOptions; + projectRootPath?: string; } interface SetCompilerOptionsForInferredProjectsResponse extends Response { } @@ -4681,6 +4696,7 @@ declare namespace ts.server.protocol { paths?: MapLike; plugins?: PluginImport[]; preserveConstEnums?: boolean; + preserveSymlinks?: boolean; project?: string; reactNamespace?: string; removeComments?: boolean; @@ -4750,6 +4766,7 @@ declare namespace ts.server { host: ServerHost; cancellationToken: ServerCancellationToken; useSingleInferredProject: boolean; + useInferredProjectPerProjectRoot: boolean; typingsInstaller: ITypingsInstaller; byteLength: (buf: string, encoding?: string) => number; hrtime: (start?: number[]) => number[]; @@ -4757,8 +4774,8 @@ declare namespace ts.server { canUseEvents: boolean; eventHandler?: ProjectServiceEventHandler; throttleWaitMilliseconds?: number; - globalPlugins?: string[]; - pluginProbeLocations?: string[]; + globalPlugins?: ReadonlyArray; + pluginProbeLocations?: ReadonlyArray; allowLocalPluginLoads?: boolean; } class Session implements EventSender { @@ -4780,13 +4797,13 @@ declare namespace ts.server { private defaultEventHandler(event); logError(err: Error, cmd: string): void; send(msg: protocol.Message): void; - configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: Diagnostic[]): void; + configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: ReadonlyArray): void; event(info: T, eventName: string): void; output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void; private semanticCheck(file, project); private syntacticCheck(file, project); - private updateProjectStructure(seq, matchSeq, ms?); - private updateErrorCheck(next, checkList, seq, matchSeq, ms?, followMs?, requireOpen?); + private updateProjectStructure(); + private updateErrorCheck(next, checkList, ms, requireOpen?); private cleanProjects(caption, projects); private cleanup(); private getEncodedSemanticClassifications(args); @@ -4878,38 +4895,10 @@ declare namespace ts.server { } } declare namespace ts.server { - interface LineCollection { - charCount(): number; - lineCount(): number; - isLeaf(): this is LineLeaf; - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void; - } interface AbsolutePositionAndLineText { absolutePosition: number; lineText: string | undefined; } - enum CharRangeSection { - PreStart = 0, - Start = 1, - Entire = 2, - Mid = 3, - End = 4, - PostEnd = 5, - } - interface ILineIndexWalker { - goSubtree: boolean; - done: boolean; - leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void; - pre?(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineNode, nodeType: CharRangeSection): void; - post?(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineNode, nodeType: CharRangeSection): void; - } - class TextChange { - pos: number; - deleteLen: number; - insertedText: string; - constructor(pos: number, deleteLen: number, insertedText?: string); - getTextChangeRange(): TextChangeRange; - } class ScriptVersionCache { private changes; private readonly versions; @@ -4921,79 +4910,17 @@ declare namespace ts.server { private versionToIndex(version); private currentVersionToIndex(); edit(pos: number, deleteLen: number, insertedText?: string): void; - latest(): LineIndexSnapshot; - latestVersion(): number; reload(script: string): void; - getSnapshot(): LineIndexSnapshot; + getSnapshot(): IScriptSnapshot; + private _getSnapshot(); + getSnapshotVersion(): number; + getLineInfo(line: number): AbsolutePositionAndLineText; + lineOffsetToPosition(line: number, column: number): number; + positionToLineOffset(position: number): protocol.Location; + lineToTextSpan(line: number): TextSpan; getTextChangesBetweenVersions(oldVersion: number, newVersion: number): TextChangeRange; static fromString(script: string): ScriptVersionCache; } - class LineIndexSnapshot implements IScriptSnapshot { - readonly version: number; - readonly cache: ScriptVersionCache; - readonly index: LineIndex; - readonly changesSincePreviousVersion: ReadonlyArray; - constructor(version: number, cache: ScriptVersionCache, index: LineIndex, changesSincePreviousVersion?: ReadonlyArray); - getText(rangeStart: number, rangeEnd: number): string; - getLength(): number; - getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; - } - class LineIndex { - root: LineNode; - checkEdits: boolean; - absolutePositionOfStartOfLine(oneBasedLine: number): number; - positionToLineOffset(position: number): protocol.Location; - private positionToColumnAndLineText(position); - lineNumberToInfo(oneBasedLine: number): AbsolutePositionAndLineText; - load(lines: string[]): void; - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void; - getText(rangeStart: number, rangeLength: number): string; - getLength(): number; - every(f: (ll: LineLeaf, s: number, len: number) => boolean, rangeStart: number, rangeEnd?: number): boolean; - edit(pos: number, deleteLength: number, newText?: string): LineIndex; - private static buildTreeFromBottom(nodes); - static linesFromText(text: string): { - lines: string[]; - lineMap: number[]; - }; - } - class LineNode implements LineCollection { - private readonly children; - totalChars: number; - totalLines: number; - constructor(children?: LineCollection[]); - isLeaf(): boolean; - updateCounts(): void; - private execWalk(rangeStart, rangeLength, walkFns, childIndex, nodeType); - private skipChild(relativeStart, relativeLength, childIndex, walkFns, nodeType); - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void; - charOffsetToLineInfo(lineNumberAccumulator: number, relativePosition: number): { - oneBasedLine: number; - zeroBasedColumn: number; - lineText: string | undefined; - }; - lineNumberToInfo(relativeOneBasedLine: number, positionAccumulator: number): { - position: number; - leaf: LineLeaf | undefined; - }; - private childFromLineNumber(relativeOneBasedLine, positionAccumulator); - private childFromCharOffset(lineNumberAccumulator, relativePosition); - private splitAfter(childIndex); - remove(child: LineCollection): void; - private findChildIndex(child); - insertAt(child: LineCollection, nodes: LineCollection[]): LineNode[]; - add(collection: LineCollection): void; - charCount(): number; - lineCount(): number; - } - class LineLeaf implements LineCollection { - text: string; - constructor(text: string); - isLeaf(): boolean; - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void; - charCount(): number; - lineCount(): number; - } } declare namespace ts.server { class ScriptInfo { @@ -5174,7 +5101,7 @@ declare namespace ts.server { private projectStructureVersion; private projectStateVersion; private typingFiles; - protected projectErrors: Diagnostic[]; + protected projectErrors: ReadonlyArray; typesVersion: number; isNonTsProject(): boolean; isJsOnlyProject(): boolean; @@ -5182,8 +5109,8 @@ declare namespace ts.server { static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {}; constructor(projectName: string, projectKind: ProjectKind, projectService: ProjectService, documentRegistry: DocumentRegistry, hasExplicitListOfFiles: boolean, languageServiceEnabled: boolean, compilerOptions: CompilerOptions, compileOnSaveEnabled: boolean); private setInternalCompilerOptionsForEmittingJsFiles(); - getGlobalProjectErrors(): Diagnostic[]; - getAllProjectErrors(): Diagnostic[]; + getGlobalProjectErrors(): ReadonlyArray; + getAllProjectErrors(): ReadonlyArray; getLanguageService(ensureSynchronized?: boolean): LanguageService; getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[]; getProjectVersion(): string; @@ -5228,12 +5155,13 @@ declare namespace ts.server { protected removeRoot(info: ScriptInfo): void; } class InferredProject extends Project { + readonly projectRootPath: string | undefined; private static readonly newName; private _isJsInferredProject; toggleJsInferredProject(isJsInferredProject: boolean): void; setCompilerOptions(options?: CompilerOptions): void; directoriesWatchedForTsconfig: string[]; - constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions); + constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, projectRootPath?: string); addRoot(info: ScriptInfo): void; removeRoot(info: ScriptInfo): void; getProjectRootPath(): string; @@ -5257,7 +5185,7 @@ declare namespace ts.server { private enablePlugin(pluginConfigEntry, searchPaths); private enableProxy(pluginModuleFactory, configEntry); getProjectRootPath(): string; - setProjectErrors(projectErrors: Diagnostic[]): void; + setProjectErrors(projectErrors: ReadonlyArray): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; getTypeAcquisition(): TypeAcquisition; getExternalFiles(): SortedReadonlyArray; @@ -5279,7 +5207,7 @@ declare namespace ts.server { constructor(externalProjectName: string, projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, languageServiceEnabled: boolean, compileOnSaveEnabled: boolean, projectFilePath?: string); getProjectRootPath(): string; getTypeAcquisition(): TypeAcquisition; - setProjectErrors(projectErrors: Diagnostic[]): void; + setProjectErrors(projectErrors: ReadonlyArray): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; } } @@ -5301,7 +5229,7 @@ declare namespace ts.server { data: { triggerFile: string; configFileName: string; - diagnostics: Diagnostic[]; + diagnostics: ReadonlyArray; }; } interface ProjectLanguageServiceStateEvent { @@ -5357,7 +5285,7 @@ declare namespace ts.server { function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; - function combineProjectOutput(projects: Project[], action: (project: Project) => T[], comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[]; + function combineProjectOutput(projects: ReadonlyArray, action: (project: Project) => ReadonlyArray, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[]; interface HostConfiguration { formatCodeOptions: FormatCodeSettings; hostInfo: string; @@ -5365,18 +5293,19 @@ declare namespace ts.server { } interface OpenConfiguredProjectResult { configFileName?: NormalizedPath; - configFileErrors?: Diagnostic[]; + configFileErrors?: ReadonlyArray; } interface ProjectServiceOptions { host: ServerHost; logger: Logger; cancellationToken: HostCancellationToken; useSingleInferredProject: boolean; + useInferredProjectPerProjectRoot: boolean; typingsInstaller: ITypingsInstaller; eventHandler?: ProjectServiceEventHandler; throttleWaitMilliseconds?: number; - globalPlugins?: string[]; - pluginProbeLocations?: string[]; + globalPlugins?: ReadonlyArray; + pluginProbeLocations?: ReadonlyArray; allowLocalPluginLoads?: boolean; } class ProjectService { @@ -5389,7 +5318,7 @@ declare namespace ts.server { readonly configuredProjects: ConfiguredProject[]; readonly openFiles: ScriptInfo[]; private compilerOptionsForInferredProjects; - private compileOnSaveForInferredProjects; + private compilerOptionsForInferredProjectsPerProjectRoot; private readonly projectToSizeMap; private readonly directoryWatchers; private readonly throttledOperations; @@ -5402,6 +5331,7 @@ declare namespace ts.server { readonly logger: Logger; readonly cancellationToken: HostCancellationToken; readonly useSingleInferredProject: boolean; + readonly useInferredProjectPerProjectRoot: boolean; readonly typingsInstaller: ITypingsInstaller; readonly throttleWaitMilliseconds?: number; private readonly eventHandler?; @@ -5414,7 +5344,7 @@ declare namespace ts.server { getCompilerOptionsForInferredProjects(): CompilerOptions; onUpdateLanguageServiceStateForProject(project: Project, languageServiceEnabled: boolean): void; updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void; - setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void; + setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void; stopWatchingDirectory(directory: string): void; findProject(projectName: string): Project; getDefaultProjectForFile(fileName: NormalizedPath, refreshInferredProjects: boolean): Project; @@ -5431,7 +5361,7 @@ declare namespace ts.server { private onConfigFileAddedForInferredProject(fileName); private getCanonicalFileName(fileName); private removeProject(project); - private assignScriptInfoToInferredProjectIfNecessary(info, addToListOfOpenFiles); + private assignScriptInfoToInferredProjectIfNecessary(info, addToListOfOpenFiles, projectRootPath?); private closeOpenFile(info); private deleteOrphanScriptInfoNotInAnyProject(); private openOrUpdateConfiguredProjectForFile(fileName, projectRootPath?); @@ -5450,7 +5380,10 @@ declare namespace ts.server { private openConfigFile(configFileName, clientFileName?); private updateNonInferredProject(project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave, configFileErrors); private updateConfiguredProject(project); - createInferredProjectWithRootFileIfNecessary(root: ScriptInfo): InferredProject; + private getOrCreateInferredProjectForProjectRootPathIfEnabled(root, projectRootPath); + private getOrCreateSingleInferredProjectIfEnabled(); + private createInferredProject(isSingleInferredProject?, projectRootPath?); + createInferredProjectWithRootFileIfNecessary(root: ScriptInfo, projectRootPath?: string): InferredProject; getOrCreateScriptInfo(uncheckedFileName: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind): ScriptInfo; getScriptInfo(uncheckedFileName: string): ScriptInfo; watchClosedScriptInfo(info: ScriptInfo): void; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 07c0852235dd1..9e95700ac6a61 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -513,6 +513,7 @@ var ts; TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined"; TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral"; TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType"; + TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope"; })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {})); var SymbolFormatFlags; (function (SymbolFormatFlags) { @@ -759,6 +760,12 @@ var ts; InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault"; InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault"; })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {})); + var Ternary; + (function (Ternary) { + Ternary[Ternary["False"] = 0] = "False"; + Ternary[Ternary["Maybe"] = 1] = "Maybe"; + Ternary[Ternary["True"] = -1] = "True"; + })(Ternary = ts.Ternary || (ts.Ternary = {})); var SpecialPropertyAssignmentKind; (function (SpecialPropertyAssignmentKind) { SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["None"] = 0] = "None"; @@ -1156,15 +1163,9 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { - var Ternary; - (function (Ternary) { - Ternary[Ternary["False"] = 0] = "False"; - Ternary[Ternary["Maybe"] = 1] = "Maybe"; - Ternary[Ternary["True"] = -1] = "True"; - })(Ternary = ts.Ternary || (ts.Ternary = {})); ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; ts.localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0; function createDictionaryObject() { @@ -1452,10 +1453,9 @@ var ts; ts.removeWhere = removeWhere; function filterMutate(array, f) { var outIndex = 0; - for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { - var item = array_3[_i]; - if (f(item)) { - array[outIndex] = item; + for (var i = 0; i < array.length; i++) { + if (f(array[i], i, array)) { + array[outIndex] = array[i]; outIndex++; } } @@ -1501,8 +1501,8 @@ var ts; var result; if (array) { result = []; - for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { - var v = array_4[_i]; + for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { + var v = array_3[_i]; if (v) { if (isArray(v)) { addRange(result, v); @@ -1572,11 +1572,13 @@ var ts; ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; - for (var i = 0; i < array.length; i++) { - var item = array[i]; - var mapped = mapFn(item, i); - if (mapped !== undefined) { - result.push(mapped); + if (array) { + for (var i = 0; i < array.length; i++) { + var item = array[i]; + var mapped = mapFn(item, i); + if (mapped !== undefined) { + result.push(mapped); + } } } return result; @@ -1644,8 +1646,8 @@ var ts; function some(array, predicate) { if (array) { if (predicate) { - for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { - var v = array_5[_i]; + for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { + var v = array_4[_i]; if (predicate(v)) { return true; } @@ -1670,8 +1672,8 @@ var ts; var result; if (array) { result = []; - loop: for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { - var item = array_6[_i]; + loop: for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { + var item = array_5[_i]; for (var _a = 0, result_1 = result; _a < result_1.length; _a++) { var res = result_1[_a]; if (areEqual ? areEqual(res, item) : res === item) { @@ -1759,8 +1761,8 @@ var ts; ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; - for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { - var v = array_7[_i]; + for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { + var v = array_6[_i]; result += v[prop]; } return result; @@ -2020,8 +2022,8 @@ var ts; ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); - for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { - var value = array_8[_i]; + for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { + var value = array_7[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; @@ -2181,11 +2183,11 @@ var ts; ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { var end = start + length; - Debug.assert(start >= 0, "start must be non-negative, is " + start); - Debug.assert(length >= 0, "length must be non-negative, is " + length); + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); if (file) { - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + Debug.assertLessThanOrEqual(start, file.text.length); + Debug.assertLessThanOrEqual(end, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { @@ -2669,8 +2671,28 @@ var ts; ts.fileExtensionIsOneOf = fileExtensionIsOneOf; var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42, 63]; - var singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; - var singleAsteriskRegexFragmentOther = "[^/]*"; + ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; + var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; + var filesMatcher = { + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } + }; + var directoriesMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } + }; + var excludeMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } + }; + var wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher + }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { @@ -2685,18 +2707,16 @@ var ts; if (specs === undefined || specs.length === 0) { return undefined; } - var replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther; - var singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther; - var doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; return flatMap(specs, function (spec) { - return spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); + return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } function isImplicitGlob(lastPathComponent) { return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; - function getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter) { + function getSubPatternFromSpec(spec, basePath, usage, _a) { + var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; @@ -2728,16 +2748,24 @@ var ts; subpattern += ts.directorySeparator; } if (usage !== "exclude") { + var componentPattern = ""; if (component.charCodeAt(0) === 42) { - subpattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63) { - subpattern += "[^./]"; + componentPattern += "[^./]"; component = component.substr(1); } + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } hasWrittenComponent = true; } @@ -2747,12 +2775,6 @@ var ts; } return subpattern; } - function replaceWildCardCharacterFiles(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentFiles); - } - function replaceWildCardCharacterOther(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentOther); - } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } @@ -2889,14 +2911,7 @@ var ts; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } - var extensions = allSupportedExtensions.slice(0); - for (var _i = 0, extraFileExtensions_1 = extraFileExtensions; _i < extraFileExtensions_1.length; _i++) { - var extInfo = extraFileExtensions_1[_i]; - if (extensions.indexOf(extInfo.extension) === -1) { - extensions.push(extInfo.extension); - } - } - return extensions; + return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; }))); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { @@ -3038,12 +3053,37 @@ var ts; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + verboseDebugInfo(); + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; + function assertEqual(a, b, msg, msg2) { + if (a !== b) { + var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; + fail("Expected " + a + " === " + b + ". " + message); + } + } + Debug.assertEqual = assertEqual; + function assertLessThan(a, b, msg) { + if (a >= b) { + fail("Expected " + a + " < " + b + ". " + (msg || "")); + } + } + Debug.assertLessThan = assertLessThan; + function assertLessThanOrEqual(a, b) { + if (a > b) { + fail("Expected " + a + " <= " + b); + } + } + Debug.assertLessThanOrEqual = assertLessThanOrEqual; + function assertGreaterThanOrEqual(a, b) { + if (a < b) { + fail("Expected " + a + " >= " + b); + } + } + Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); @@ -3178,6 +3218,10 @@ var ts; Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; + function isAnySupportedFileExtension(path) { + return tryGetExtensionFromPath(path) !== undefined; + } + ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } @@ -3189,6 +3233,12 @@ var ts; })(ts || (ts = {})); var ts; (function (ts) { + function setStackTraceLimit() { + if (Error.stackTraceLimit < 100) { + Error.stackTraceLimit = 100; + } + } + ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; @@ -3238,7 +3288,7 @@ var ts; watcher.referenceCount += 1; return; } - watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); + watcher = _fs.watch(dirPath || ".", { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; @@ -4064,6 +4114,7 @@ var ts; Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), + Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), @@ -4251,6 +4302,7 @@ var ts; Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), + Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), @@ -4504,6 +4556,8 @@ var ts; Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), + Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), }; })(ts || (ts = {})); var ts; @@ -4524,19 +4578,6 @@ var ts; return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; - function findDeclaration(symbol, predicate) { - var declarations = symbol.declarations; - if (declarations) { - for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { - var declaration = declarations_2[_i]; - if (predicate(declaration)) { - return declaration; - } - } - } - return undefined; - } - ts.findDeclaration = findDeclaration; var stringWriter = createSingleLineStringWriter(); var stringWriterAcquired = false; function createSingleLineStringWriter() { @@ -4599,9 +4640,13 @@ var ts; function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && - oldResolution.resolvedFileName === newResolution.resolvedFileName; + oldResolution.resolvedFileName === newResolution.resolvedFileName && + packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; + function packageIdIsEqual(a, b) { + return a === b || a && b && a.name === b.name && a.version === b.version; + } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } @@ -4666,14 +4711,6 @@ var ts; return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; - function getStartPosOfNode(node) { - return node.pos; - } - ts.getStartPosOfNode = getStartPosOfNode; - function isDefined(value) { - return value !== undefined; - } - ts.isDefined = isDefined; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); @@ -4704,6 +4741,25 @@ var ts; return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; + function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { + if (text.charCodeAt(commentPos + 1) === 47 && + commentPos + 2 < commentEnd && + text.charCodeAt(commentPos + 2) === 47) { + var textSubStr = text.substring(commentPos, commentEnd); + return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || + textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || + textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || + textSubStr.match(defaultLibReferenceRegEx) ? + true : false; + } + return false; + } + ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; + function isPinnedComment(text, comment) { + return text.charCodeAt(comment.pos + 1) === 42 && + text.charCodeAt(comment.pos + 2) === 33; + } + ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { if (nodeIsMissing(node)) { return node.pos; @@ -4760,15 +4816,20 @@ var ts; var escapeText = getEmitFlags(node) & 16777216 ? escapeString : escapeNonAsciiString; switch (node.kind) { case 9: - return '"' + escapeText(node.text) + '"'; + if (node.singleQuote) { + return "'" + escapeText(node.text, 39) + "'"; + } + else { + return '"' + escapeText(node.text, 34) + '"'; + } case 13: - return "`" + escapeText(node.text) + "`"; + return "`" + escapeText(node.text, 96) + "`"; case 14: - return "`" + escapeText(node.text) + "${"; + return "`" + escapeText(node.text, 96) + "${"; case 15: - return "}" + escapeText(node.text) + "${"; + return "}" + escapeText(node.text, 96) + "${"; case 16: - return "}" + escapeText(node.text) + "`"; + return "}" + escapeText(node.text, 96) + "`"; case 8: return node.text; } @@ -5023,10 +5084,6 @@ var ts; return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos); } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; - function getLeadingCommentRangesOfNodeFromText(node, text) { - return ts.getLeadingCommentRanges(text, node.pos); - } - ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 146 || node.kind === 145 || @@ -5034,7 +5091,7 @@ var ts; node.kind === 187 || node.kind === 185) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); + ts.getLeadingCommentRanges(text, node.pos); return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 && text.charCodeAt(comment.pos + 2) === 42 && @@ -5043,8 +5100,9 @@ var ts; } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; + var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; + var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (158 <= node.kind && node.kind <= 173) { return true; @@ -5271,21 +5329,11 @@ var ts; } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { - while (true) { - node = node.parent; - if (!node || ts.isFunctionLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { - while (true) { - node = node.parent; - if (!node || ts.isClassLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { @@ -6095,14 +6143,14 @@ var ts; ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*/gim; + var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim"); if (simpleReferenceRegEx.test(comment)) { if (isNoDefaultLibRegEx.test(comment)) { return { isNoDefaultLib: true }; } else { var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment); - var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); var match = refMatchResult || refLibResult; if (match) { var pos = commentRange.pos + match[1].length + match[2].length; @@ -6291,10 +6339,6 @@ var ts; return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; - function getOriginalSourceFiles(sourceFiles) { - return ts.sameMap(sourceFiles, getOriginalSourceFile); - } - ts.getOriginalSourceFiles = getOriginalSourceFiles; var Associativity; (function (Associativity) { Associativity[Associativity["Left"] = 0] = "Left"; @@ -6533,7 +6577,9 @@ var ts; } } ts.createDiagnosticCollection = createDiagnosticCollection; - var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", @@ -6544,11 +6590,16 @@ var ts; "\n": "\\n", "\\": "\\\\", "\"": "\\\"", + "\'": "\\\'", + "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" }); - function escapeString(s) { + function escapeString(s, quoteChar) { + var escapedCharsRegExp = quoteChar === 96 ? backtickQuoteEscapedCharsRegExp : + quoteChar === 39 ? singleQuoteEscapedCharsRegExp : + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } ts.escapeString = escapeString; @@ -6566,8 +6617,8 @@ var ts; return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; - function escapeNonAsciiString(s) { - s = escapeString(s); + function escapeNonAsciiString(s, quoteChar) { + s = escapeString(s, quoteChar); return nonAsciiCharacters.test(s) ? s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) : s; @@ -6908,7 +6959,7 @@ var ts; var currentDetachedCommentInfo; if (removeComments) { if (node.pos === 0) { - leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment); + leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { @@ -6940,9 +6991,8 @@ var ts; } } return currentDetachedCommentInfo; - function isPinnedComment(comment) { - return text.charCodeAt(comment.pos + 1) === 42 && - text.charCodeAt(comment.pos + 2) === 33; + function isPinnedCommentLocal(comment) { + return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; @@ -7013,9 +7063,13 @@ var ts; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { - return (getModifierFlags(node) & flags) !== 0; + return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; + function getSelectedModifierFlags(node, flags) { + return getModifierFlags(node) & flags; + } + ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912) { return node.modifierFlagsCache & ~536870912; @@ -7091,21 +7145,6 @@ var ts; return false; } ts.isDestructuringAssignment = isDestructuringAssignment; - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 71) { - return true; - } - else if (ts.isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } - } function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } @@ -7218,72 +7257,6 @@ var ts; return carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; - function isSimpleExpression(node) { - return isSimpleExpressionWorker(node, 0); - } - ts.isSimpleExpression = isSimpleExpression; - function isSimpleExpressionWorker(node, depth) { - if (depth <= 5) { - var kind = node.kind; - if (kind === 9 - || kind === 8 - || kind === 12 - || kind === 13 - || kind === 71 - || kind === 99 - || kind === 97 - || kind === 101 - || kind === 86 - || kind === 95) { - return true; - } - else if (kind === 179) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 180) { - return isSimpleExpressionWorker(node.expression, depth + 1) - && isSimpleExpressionWorker(node.argumentExpression, depth + 1); - } - else if (kind === 192 - || kind === 193) { - return isSimpleExpressionWorker(node.operand, depth + 1); - } - else if (kind === 194) { - return node.operatorToken.kind !== 40 - && isSimpleExpressionWorker(node.left, depth + 1) - && isSimpleExpressionWorker(node.right, depth + 1); - } - else if (kind === 195) { - return isSimpleExpressionWorker(node.condition, depth + 1) - && isSimpleExpressionWorker(node.whenTrue, depth + 1) - && isSimpleExpressionWorker(node.whenFalse, depth + 1); - } - else if (kind === 190 - || kind === 189 - || kind === 188) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 177) { - return node.elements.length === 0; - } - else if (kind === 178) { - return node.properties.length === 0; - } - else if (kind === 181) { - if (!isSimpleExpressionWorker(node.expression, depth + 1)) { - return false; - } - for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { - var argument = _a[_i]; - if (!isSimpleExpressionWorker(argument, depth + 1)) { - return false; - } - } - return true; - } - } - return false; - } function formatEnum(value, enumObject, isFlags) { if (value === void 0) { value = 0; } var members = getEnumMembers(enumObject); @@ -7352,18 +7325,6 @@ var ts; return formatEnum(flags, ts.ObjectFlags, true); } ts.formatObjectFlags = formatObjectFlags; - function getRangePos(range) { - return range ? range.pos : -1; - } - ts.getRangePos = getRangePos; - function getRangeEnd(range) { - return range ? range.end : -1; - } - ts.getRangeEnd = getRangeEnd; - function movePos(pos, value) { - return ts.positionIsSynthesized(pos) ? -1 : pos + value; - } - ts.movePos = movePos; function createRange(pos, end) { return { pos: pos, end: end }; } @@ -7392,14 +7353,6 @@ var ts; return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; - function collapseRangeToStart(range) { - return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos); - } - ts.collapseRangeToStart = collapseRangeToStart; - function collapseRangeToEnd(range) { - return isCollapsedRange(range) ? range : moveRangePos(range, range.end); - } - ts.collapseRangeToEnd = collapseRangeToEnd; function createTokenRange(pos, token) { return createRange(pos, pos + ts.tokenToString(token).length); } @@ -7452,22 +7405,6 @@ var ts; function isInitializedVariable(node) { return node.initializer !== undefined; } - function isMergedWithClass(node) { - if (node.symbol) { - for (var _i = 0, _a = node.symbol.declarations; _i < _a.length; _i++) { - var declaration = _a[_i]; - if (declaration.kind === 229 && declaration !== node) { - return true; - } - } - } - return false; - } - ts.isMergedWithClass = isMergedWithClass; - function isFirstDeclarationOfKind(node, kind) { - return node.symbol && getDeclarationOfKind(node.symbol, kind) === node; - } - ts.isFirstDeclarationOfKind = isFirstDeclarationOfKind; function isWatchSet(options) { return options.watch && options.hasOwnProperty("watch"); } @@ -7668,6 +7605,20 @@ var ts; return ts.hasModifier(node, 92) && node.parent.kind === 152 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function isEmptyBindingPattern(node) { + if (ts.isBindingPattern(node)) { + return ts.every(node.elements, isEmptyBindingElement); + } + return false; + } + ts.isEmptyBindingPattern = isEmptyBindingPattern; + function isEmptyBindingElement(node) { + if (ts.isOmittedExpression(node)) { + return true; + } + return isEmptyBindingPattern(node.name); + } + ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 176 || ts.isBindingPattern(node))) { node = node.parent; @@ -8748,6 +8699,18 @@ var ts; return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; + function isUnaryExpressionWithWrite(expr) { + switch (expr.kind) { + case 193: + return true; + case 192: + return expr.operator === 43 || + expr.operator === 44; + default: + return false; + } + } + ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; function isExpressionKind(kind) { return kind === 195 || kind === 197 @@ -8932,9 +8895,19 @@ var ts; var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) - || kind === 207; + || isBlockStatement(node); } ts.isStatement = isStatement; + function isBlockStatement(node) { + if (node.kind !== 207) + return false; + if (node.parent !== undefined) { + if (node.parent.kind === 224 || node.parent.kind === 260) { + return false; + } + } + return !ts.isFunctionBlock(node); + } function isModuleReference(node) { var kind = node.kind; return kind === 248 @@ -12439,11 +12412,31 @@ var ts; var node = parseTokenNode(); return token() === 23 ? undefined : node; } - function parseLiteralTypeNode() { + function parseLiteralTypeNode(negative) { var node = createNode(173); - node.literal = parseSimpleUnaryExpression(); - finishNode(node); - return node; + var unaryMinusExpression; + if (negative) { + unaryMinusExpression = createNode(192); + unaryMinusExpression.operator = 38; + nextToken(); + } + var expression; + switch (token()) { + case 9: + case 8: + expression = parseLiteralLikeNode(token()); + break; + case 101: + case 86: + expression = parseTokenNode(); + } + if (negative) { + unaryMinusExpression.operand = expression; + finishNode(unaryMinusExpression); + expression = unaryMinusExpression; + } + node.literal = expression; + return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8; @@ -12475,7 +12468,7 @@ var ts; case 86: return parseLiteralTypeNode(); case 38: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference(); + return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(true) : parseTypeReference(); case 105: case 95: return parseTokenNode(); @@ -12524,6 +12517,7 @@ var ts; case 101: case 86: case 134: + case 39: return true; case 38: return lookAhead(nextTokenIsNumericLiteral); @@ -12842,7 +12836,7 @@ var ts; if (!arrowFunction) { return undefined; } - var isAsync = !!(ts.getModifierFlags(arrowFunction) & 256); + var isAsync = ts.hasModifier(arrowFunction, 256); var lastToken = token(); arrowFunction.equalsGreaterThanToken = parseExpectedToken(36, false, ts.Diagnostics._0_expected, "=>"); arrowFunction.body = (lastToken === 36 || lastToken === 17) @@ -12958,7 +12952,7 @@ var ts; function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNode(187); node.modifiers = parseModifiersForArrowFunction(); - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; fillSignature(56, isAsync | (allowAmbiguity ? 0 : 8), node); if (!node.parameters) { return undefined; @@ -13691,7 +13685,7 @@ var ts; parseExpected(89); node.asteriskToken = parseOptionalToken(39); var isGenerator = node.asteriskToken ? 1 : 0; - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : @@ -13916,10 +13910,13 @@ var ts; function parseCatchClause() { var result = createNode(260); parseExpected(74); - if (parseExpected(19)) { + if (parseOptional(19)) { result.variableDeclaration = parseVariableDeclaration(); + parseExpected(20); + } + else { + result.variableDeclaration = undefined; } - parseExpected(20); result.block = parseBlock(false); return finishNode(result); } @@ -15651,8 +15648,8 @@ var ts; array._children = undefined; array.pos += delta; array.end += delta; - for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { - var node = array_9[_i]; + for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { + var node = array_8[_i]; visitNode(node); } } @@ -15724,8 +15721,8 @@ var ts; array.intersectsChange = true; array._children = undefined; adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (var _i = 0, array_10 = array; _i < array_10.length; _i++) { - var node = array_10[_i]; + for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { + var node = array_9[_i]; visitNode(node); } return; @@ -16241,6 +16238,12 @@ var ts; category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "preserveSymlinks", + type: "boolean", + category: ts.Diagnostics.Module_Resolution_Options, + description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, + }, { name: "sourceRoot", type: "string", @@ -16852,7 +16855,7 @@ var ts; var text = valueExpression.text; if (option && typeof option.type !== "string") { var customOption = option; - if (!customOption.type.has(text)) { + if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } @@ -17103,12 +17106,10 @@ var ts; } } else { - var specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; var outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"]; if (outDir) { - specs.push(outDir); + excludeSpecs = [outDir]; } - excludeSpecs = specs; } if (fileNames === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; @@ -17359,7 +17360,7 @@ var ts; return value; } else if (typeof option.type !== "string") { - return option.type.get(value); + return option.type.get(typeof value === "string" ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } @@ -17434,23 +17435,13 @@ var ts; }; } function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { - var validSpecs = []; - for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) { - var spec = specs_1[_i]; - if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidMultipleRecursionPatterns.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else { - validSpecs.push(spec); + return specs.filter(function (spec) { + var diag = specToDiagnostic(spec, allowTrailingRecursion); + if (diag !== undefined) { + errors.push(createDiagnostic(diag, spec)); } - } - return validSpecs; + return diag === undefined; + }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { @@ -17468,6 +17459,17 @@ var ts; return ts.createCompilerDiagnostic(message, spec); } } + function specToDiagnostic(spec, allowTrailingRecursion) { + if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + else if (invalidMultipleRecursionPatterns.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; + } + else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + } function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) { var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude"); var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); @@ -17590,6 +17592,12 @@ var ts; return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; + function withPackageId(packageId, r) { + return r && { path: r.path, extension: r.ext, packageId: packageId }; + } + function noPackageId(r) { + return withPackageId(undefined, r); + } var Extensions; (function (Extensions) { Extensions[Extensions["TypeScript"] = 0] = "TypeScript"; @@ -17605,12 +17613,11 @@ var ts; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { - resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport }, + resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } - function tryReadPackageJsonFields(readTypes, packageJsonPath, baseDirectory, state) { - var jsonContent = readJson(packageJsonPath, state.host); + function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { @@ -17704,7 +17711,9 @@ var ts; } var resolvedTypeReferenceDirective; if (resolved) { - resolved = realpath(resolved, host, traceEnabled); + if (!options.preserveSymlinks) { + resolved = realpath(resolved, host, traceEnabled); + } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary); } @@ -18005,7 +18014,7 @@ var ts; if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, false, state); if (path_1 !== undefined) { - return { path: path_1, extension: extension }; + return { path: path_1, extension: extension, packageId: undefined }; } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); @@ -18026,7 +18035,7 @@ var ts; function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, undefined, true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { - throw new Error("Could not resolve JS module " + moduleName + " starting at " + initialDir + ". Looked in: " + failedLookupLocations.join(", ")); + throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } @@ -18052,7 +18061,13 @@ var ts; trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); - return resolved_1 && { value: resolved_1.value && { resolved: { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }, isExternalLibraryImport: true } }; + if (!resolved_1) + return undefined; + var resolvedValue = resolved_1.value; + if (!compilerOptions.preserveSymlinks) { + resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); + } + return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); @@ -18087,7 +18102,7 @@ var ts; } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return resolvedFromFile; + return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { @@ -18105,6 +18120,9 @@ var ts; return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; + function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { + return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + } function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); if (resolvedByAddingExtension) { @@ -18134,9 +18152,9 @@ var ts; case Extensions.JavaScript: return tryExtension(".js") || tryExtension(".jsx"); } - function tryExtension(extension) { - var path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); - return path && { path: path, extension: extension }; + function tryExtension(ext) { + var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + return path && { path: path, ext: ext }; } } function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) { @@ -18159,12 +18177,20 @@ var ts; function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); + var packageId; if (considerPackageJson) { var packageJsonPath = pathToPackageJson(candidate); if (directoryExists && state.host.fileExists(packageJsonPath)) { - var fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); + } + var jsonContent = readJson(packageJsonPath, state.host); + if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") { + packageId = { name: jsonContent.name, version: jsonContent.version }; + } + var fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { - return fromPackageJson; + return withPackageId(packageId, fromPackageJson); } } else { @@ -18174,13 +18200,10 @@ var ts; failedLookupLocations.push(packageJsonPath); } } - return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return withPackageId(packageId, loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state)); } - function loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); - } - var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { + var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } @@ -18196,11 +18219,15 @@ var ts; } } var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; - return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + if (result) { + ts.Debug.assert(result.packageId === undefined); + return { path: result.path, ext: result.extension }; + } } function resolvedIfExtensionMatches(extensions, path) { - var extension = ts.tryGetExtensionFromPath(path); - return extension !== undefined && extensionIsOk(extensions, extension) ? { path: path, extension: extension } : undefined; + var ext = ts.tryGetExtensionFromPath(path); + return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } function extensionIsOk(extensions, extension) { switch (extensions) { @@ -18217,7 +18244,7 @@ var ts; } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || + return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { @@ -18291,7 +18318,7 @@ var ts; if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { @@ -18302,7 +18329,7 @@ var ts; var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, false, failedLookupLocations); function tryResolve(extensions) { - var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); + var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -18314,7 +18341,7 @@ var ts; return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, false, state)); }); if (resolved_3) { return resolved_3; @@ -18325,7 +18352,7 @@ var ts; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, false, state)); } } } @@ -18976,40 +19003,23 @@ var ts; return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: flags, - expression: expression, - antecedent: antecedent - }; + return { flags: flags, expression: expression, antecedent: antecedent }; } function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) { if (!isNarrowingExpression(switchStatement.expression)) { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: 128, - switchStatement: switchStatement, - clauseStart: clauseStart, - clauseEnd: clauseEnd, - antecedent: antecedent - }; + return { flags: 128, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent }; } function createFlowAssignment(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 16, - antecedent: antecedent, - node: node - }; + return { flags: 16, antecedent: antecedent, node: node }; } function createFlowArrayMutation(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 256, - antecedent: antecedent, - node: node - }; + var res = { flags: 256, antecedent: antecedent, node: node }; + return res; } function finishFlowLabel(flow) { var antecedents = flow.antecedents; @@ -20477,7 +20487,6 @@ var ts; } function computeParameter(node, subtreeFlags) { var transformFlags = subtreeFlags; - var modifierFlags = ts.getModifierFlags(node); var name = node.name; var initializer = node.initializer; var dotDotDotToken = node.dotDotDotToken; @@ -20487,7 +20496,7 @@ var ts; || ts.isThisIdentifier(name)) { transformFlags |= 3; } - if (modifierFlags & 92) { + if (ts.hasModifier(node, 92)) { transformFlags |= 3 | 262144; } if (subtreeFlags & 1048576) { @@ -20516,8 +20525,7 @@ var ts; } function computeClassDeclaration(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); - if (modifierFlags & 2) { + if (ts.hasModifier(node, 2)) { transformFlags = 3; } else { @@ -20563,7 +20571,10 @@ var ts; } function computeCatchClause(node, subtreeFlags) { var transformFlags = subtreeFlags; - if (node.variableDeclaration && ts.isBindingPattern(node.variableDeclaration.name)) { + if (!node.variableDeclaration) { + transformFlags |= 8; + } + else if (ts.isBindingPattern(node.variableDeclaration.name)) { transformFlags |= 192; } node.transformFlags = transformFlags | 536870912; @@ -20727,9 +20738,8 @@ var ts; } function computeVariableStatement(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); var declarationListTransformFlags = node.declarationList.transformFlags; - if (modifierFlags & 2) { + if (ts.hasModifier(node, 2)) { transformFlags = 3; } else { @@ -21220,11 +21230,10 @@ var ts; getSuggestionForNonexistentProperty: function (node, type) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentProperty(node, type)); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning)); }, getBaseConstraintOfType: getBaseConstraintOfType, - getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, - resolveNameAtLocation: function (location, name, meaning) { - location = ts.getParseTreeNode(location); - return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, undefined, ts.escapeLeadingUnderscores(name)); + resolveName: function (name, location, meaning) { + return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, undefined, undefined); }, + getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, }; var tupleTypes = []; var unionTypes = ts.createMap(); @@ -21737,13 +21746,13 @@ var ts; current.parent.kind === 149 && current.parent.initializer === current; if (initializerOfProperty) { - if (ts.getModifierFlags(current.parent) & 32) { + if (ts.hasModifier(current.parent, 32)) { if (declaration.kind === 151) { return true; } } else { - var isDeclarationInstanceProperty = declaration.kind === 149 && !(ts.getModifierFlags(declaration) & 32); + var isDeclarationInstanceProperty = declaration.kind === 149 && !ts.hasModifier(declaration, 32); if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } @@ -21823,7 +21832,7 @@ var ts; break; case 149: case 148: - if (ts.isClassLike(location.parent) && !(ts.getModifierFlags(location) & 32)) { + if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32)) { var ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & 107455)) { @@ -21840,7 +21849,7 @@ var ts; result = undefined; break; } - if (lastLocation && ts.getModifierFlags(lastLocation) & 32) { + if (lastLocation && ts.hasModifier(lastLocation, 32)) { error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters); return undefined; } @@ -21900,7 +21909,7 @@ var ts; lastLocation = location; location = location.parent; } - if (result && nameNotFoundMessage && noUnusedIdentifiers) { + if (result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) { result.isReferenced = true; } if (!result) { @@ -21981,7 +21990,7 @@ var ts; error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol)); return true; } - if (location === container && !(ts.getModifierFlags(location) & 32)) { + if (location === container && !ts.hasModifier(location, 32)) { var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -22721,6 +22730,10 @@ var ts; } return false; } + function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) { + var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064, false); + return access.accessibility === 0; + } function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) { if (symbol && enclosingDeclaration && !(symbol.flags & 262144)) { var initialSymbol = symbol; @@ -22776,7 +22789,7 @@ var ts; if (!isDeclarationVisible(declaration)) { var anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(ts.getModifierFlags(anyImportSyntax) & 1) && + !ts.hasModifier(anyImportSyntax, 1) && isDeclarationVisible(anyImportSyntax.parent)) { if (shouldComputeAliasToMakeVisible) { getNodeLinks(declaration).isVisible = true; @@ -22974,8 +22987,7 @@ var ts; var name = symbolToName(type.symbol, context, 793064, false); return ts.createTypeReferenceNode(name, undefined); } - if (!inTypeAlias && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, 793064, false).accessibility === 0) { + if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { var name = symbolToTypeReferenceName(type.aliasSymbol); var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return ts.createTypeReferenceNode(name, typeArgumentNodes); @@ -23050,8 +23062,8 @@ var ts; return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192) && + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16) && (symbol.parent || ts.forEach(symbol.declarations, function (declaration) { @@ -23063,10 +23075,8 @@ var ts; } } function createTypeNodeFromObjectType(type) { - if (type.objectFlags & 32) { - if (getConstraintTypeFromMappedType(type).flags & (16384 | 262144)) { - return createMappedTypeNodeFromType(type); - } + if (isGenericMappedType(type)) { + return createMappedTypeNodeFromType(type); } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -23594,7 +23604,7 @@ var ts; buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064, 0, nextFlags); } else if (!(flags & 1024) && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, 793064, false).accessibility === 0) { + ((flags & 65536) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { var typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags); } @@ -23738,9 +23748,7 @@ var ts; if (!symbolStack) { symbolStack = []; } - var isConstructorObject = type.flags & 32768 && - getObjectFlags(type) & 16 && - type.symbol && type.symbol.flags & 32; + var isConstructorObject = type.objectFlags & 16 && type.symbol && type.symbol.flags & 32; if (isConstructorObject) { writeLiteralType(type, flags); } @@ -23755,16 +23763,16 @@ var ts; writeLiteralType(type, flags); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192) && + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16) && (symbol.parent || - ts.forEach(symbol.declarations, function (declaration) { + ts.some(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 || declaration.parent.kind === 234; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { return !!(flags & 4) || - (ts.contains(symbolStack, symbol)); + ts.contains(symbolStack, symbol); } } } @@ -23801,11 +23809,9 @@ var ts; return false; } function writeLiteralType(type, flags) { - if (type.objectFlags & 32) { - if (getConstraintTypeFromMappedType(type).flags & (16384 | 262144)) { - writeMappedType(type); - return; - } + if (isGenericMappedType(type)) { + writeMappedType(type); + return; } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -24173,7 +24179,7 @@ var ts; case 154: case 151: case 150: - if (ts.getModifierFlags(node) & (8 | 16)) { + if (ts.hasModifier(node, 8 | 16)) { return false; } case 152: @@ -24850,8 +24856,8 @@ var ts; } } function appendTypeParameters(typeParameters, declarations) { - for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { - var declaration = declarations_3[_i]; + for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { + var declaration = declarations_2[_i]; var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); if (!typeParameters) { typeParameters = [tp]; @@ -25120,7 +25126,9 @@ var ts; if (!pushTypeResolution(symbol, 2)) { return unknownType; } - var declaration = ts.findDeclaration(symbol, function (d) { return d.kind === 283 || d.kind === 231; }); + var declaration = ts.find(symbol.declarations, function (d) { + return d.kind === 283 || d.kind === 231; + }); var type = getTypeFromTypeNode(declaration.kind === 283 ? declaration.typeExpression : declaration.type); if (popTypeResolution()) { var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -25719,8 +25727,7 @@ var ts; return getObjectFlags(type) & 32 && !!type.declaration.questionToken; } function isGenericMappedType(type) { - return getObjectFlags(type) & 32 && - maybeTypeOfKind(getConstraintTypeFromMappedType(type), 540672 | 262144); + return getObjectFlags(type) & 32 && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type) { if (!type.members) { @@ -25820,6 +25827,10 @@ var ts; return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } function getConstraintOfIndexedAccess(type) { + var transformed = getTransformedIndexedAccessType(type); + if (transformed) { + return transformed; + } var baseObjectType = getBaseConstraintOfType(type.objectType); var baseIndexType = getBaseConstraintOfType(type.indexType); return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; @@ -25882,11 +25893,18 @@ var ts; return stringType; } if (t.flags & 524288) { + var transformed = getTransformedIndexedAccessType(t); + if (transformed) { + return getBaseConstraint(transformed); + } var baseObjectType = getBaseConstraint(t.objectType); var baseIndexType = getBaseConstraint(t.indexType); var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (isGenericMappedType(t)) { + return emptyObjectType; + } return t; } } @@ -26434,7 +26452,7 @@ var ts; function getIndexInfoOfSymbol(symbol, kind) { var declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, (ts.getModifierFlags(declaration) & 64) !== 0, declaration); + return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64), declaration); } return undefined; } @@ -26702,8 +26720,8 @@ var ts; function getTypeOfGlobalSymbol(symbol, arity) { function getTypeDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { - var declaration = declarations_4[_i]; + for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { + var declaration = declarations_3[_i]; switch (declaration.kind) { case 229: case 230: @@ -27160,11 +27178,11 @@ var ts; return getTypeOfSymbol(prop); } } - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 262178 | 84 | 512)) { + if (!(indexType.flags & 6144) && isTypeAssignableToKind(indexType, 262178 | 84 | 512)) { if (isTypeAny(objectType)) { return anyType; } - var indexInfo = isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84) && getIndexInfoOfType(objectType, 1) || + var indexInfo = isTypeAssignableToKind(indexType, 84) && getIndexInfoOfType(objectType, 1) || getIndexInfoOfType(objectType, 0) || undefined; if (indexInfo) { @@ -27202,25 +27220,69 @@ var ts; return anyType; } function getIndexedAccessForMappedType(type, indexType, accessNode) { - var accessExpression = accessNode && accessNode.kind === 180 ? accessNode : undefined; - if (accessExpression && ts.isAssignmentTarget(accessExpression) && type.declaration.readonlyToken) { - error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); - return unknownType; + if (accessNode) { + if (!isTypeAssignableTo(indexType, getIndexType(type))) { + error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(type)); + return unknownType; + } + if (accessNode.kind === 180 && ts.isAssignmentTarget(accessNode) && type.declaration.readonlyToken) { + error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); + return unknownType; + } } var mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]); var templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; return instantiateType(getTemplateTypeFromMappedType(type), templateMapper); } + function isGenericObjectType(type) { + return type.flags & 540672 ? true : + getObjectFlags(type) & 32 ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : + type.flags & 196608 ? ts.forEach(type.types, isGenericObjectType) : + false; + } + function isGenericIndexType(type) { + return type.flags & (540672 | 262144) ? true : + type.flags & 196608 ? ts.forEach(type.types, isGenericIndexType) : + false; + } + function isStringIndexOnlyType(type) { + if (type.flags & 32768 && !isGenericMappedType(type)) { + var t = resolveStructuredTypeMembers(type); + return t.properties.length === 0 && + t.callSignatures.length === 0 && t.constructSignatures.length === 0 && + t.stringIndexInfo && !t.numberIndexInfo; + } + return false; + } + function getTransformedIndexedAccessType(type) { + var objectType = type.objectType; + if (objectType.flags & 131072 && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) { + var regularTypes = []; + var stringIndexTypes = []; + for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, 0)); + } + else { + regularTypes.push(t); + } + } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + return undefined; + } function getIndexedAccessType(objectType, indexType, accessNode) { - if (maybeTypeOfKind(indexType, 540672 | 262144) || - maybeTypeOfKind(objectType, 540672) && !(accessNode && accessNode.kind === 180) || - isGenericMappedType(objectType)) { + if (isGenericMappedType(objectType)) { + return getIndexedAccessForMappedType(objectType, indexType, accessNode); + } + if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180) && isGenericObjectType(objectType)) { if (objectType.flags & 1) { return objectType; } - if (isGenericMappedType(objectType)) { - return getIndexedAccessForMappedType(objectType, indexType, accessNode); - } var id = objectType.id + "," + indexType.id; var type = indexedAccessTypes.get(id); if (!type) { @@ -27419,7 +27481,7 @@ var ts; var container = ts.getThisContainer(node, false); var parent = container && container.parent; if (parent && (ts.isClassLike(parent) || parent.kind === 230)) { - if (!(ts.getModifierFlags(container) & 32) && + if (!ts.hasModifier(container, 32) && (container.kind !== 152 || ts.isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } @@ -27566,7 +27628,7 @@ var ts; } function cloneTypeMapper(mapper) { return mapper && isInferenceContext(mapper) ? - createInferenceContext(mapper.signature, mapper.flags | 2, mapper.inferences) : + createInferenceContext(mapper.signature, mapper.flags | 2, mapper.compareTypes, mapper.inferences) : mapper; } function identityMapper(type) { @@ -27830,11 +27892,13 @@ var ts; if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) { return true; } - if (node.kind === 187) { - return false; + if (node.kind !== 187) { + var parameter = ts.firstOrUndefined(node.parameters); + if (!(parameter && ts.parameterIsThisKeyword(parameter))) { + return true; + } } - var parameter = ts.firstOrUndefined(node.parameters); - return !(parameter && ts.parameterIsThisKeyword(parameter)); + return node.body.kind === 207 ? false : isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func) { return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); @@ -27897,7 +27961,7 @@ var ts; return 0; } if (source.typeParameters) { - source = instantiateSignatureInContextOf(source, target); + source = instantiateSignatureInContextOf(source, target, undefined, compareTypes); } var result = -1; var sourceThisType = getThisTypeOfSignature(source); @@ -27946,7 +28010,7 @@ var ts; var sourceReturnType = getReturnTypeOfSignature(source); if (target.typePredicate) { if (source.typePredicate) { - result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes); + result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes); } else if (ts.isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { @@ -27962,7 +28026,7 @@ var ts; } return result; } - function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) { + function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) { if (source.kind !== target.kind) { if (reportErrors) { errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); @@ -27971,11 +28035,13 @@ var ts; return 0; } if (source.kind === 1) { - var sourceIdentifierPredicate = source; - var targetIdentifierPredicate = target; - if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + var sourcePredicate = source; + var targetPredicate = target; + var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0); + var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0); + if (sourceIndex !== targetIndex) { if (reportErrors) { - errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0; @@ -28234,11 +28300,21 @@ var ts; !(target.flags & 65536) && !isIntersectionConstituent && source !== globalObjectType && - getPropertiesOfType(source).length > 0 && + (getPropertiesOfType(source).length > 0 || + getSignaturesOfType(source, 0).length > 0 || + getSignaturesOfType(source, 1).length > 0) && isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { - reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + var calls = getSignaturesOfType(source, 0); + var constructs = getSignaturesOfType(source, 1); + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, false)) { + reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target)); + } + else { + reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + } } return 0; } @@ -28859,6 +28935,9 @@ var ts; if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } + if (isGenericMappedType(source)) { + return kind === 0 && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); + } if (isObjectLiteralType(source)) { var related = -1; if (kind === 0) { @@ -28892,8 +28971,8 @@ var ts; if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } - var sourceAccessibility = ts.getModifierFlags(sourceSignature.declaration) & 24; - var targetAccessibility = ts.getModifierFlags(targetSignature.declaration) & 24; + var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24); + var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24); if (targetAccessibility === 8) { return true; } @@ -28945,7 +29024,7 @@ var ts; var symbol = type.symbol; if (symbol && symbol.flags & 32) { var declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && ts.getModifierFlags(declaration) & 128) { + if (declaration && ts.hasModifier(declaration, 128)) { return true; } } @@ -29331,13 +29410,14 @@ var ts; callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } } - function createInferenceContext(signature, flags, baseInferences) { + function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; + context.compareTypes = compareTypes || compareTypesAssignable; return context; function mapper(t) { for (var i = 0; i < inferences.length; i++) { @@ -29425,6 +29505,19 @@ var ts; return inference.candidates && getUnionType(inference.candidates, true); } } + function isPossiblyAssignableTo(source, target) { + var properties = getPropertiesOfObjectType(target); + for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { + var targetProp = properties_5[_i]; + if (!(targetProp.flags & (16777216 | 4194304))) { + var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); + if (!sourceProp) { + return false; + } + } + } + return true; + } function inferTypes(inferences, originalSource, originalTarget, priority) { if (priority === void 0) { priority = 0; } var symbolStack; @@ -29585,15 +29678,17 @@ var ts; return; } } - inferFromProperties(source, target); - inferFromSignatures(source, target, 0); - inferFromSignatures(source, target, 1); - inferFromIndexTypes(source, target); + if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) { + inferFromProperties(source, target); + inferFromSignatures(source, target, 0); + inferFromSignatures(source, target, 1); + inferFromIndexTypes(source, target); + } } function inferFromProperties(source, target) { var properties = getPropertiesOfObjectType(target); - for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { - var targetProp = properties_5[_i]; + for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { + var targetProp = properties_6[_i]; var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); if (sourceProp) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); @@ -29692,7 +29787,7 @@ var ts; var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); if (constraint) { var instantiatedConstraint = instantiateType(constraint, context); - if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } @@ -29740,16 +29835,6 @@ var ts; } return undefined; } - function getLeftmostIdentifierOrThis(node) { - switch (node.kind) { - case 71: - case 99: - return node; - case 179: - return getLeftmostIdentifierOrThis(node.expression); - } - return undefined; - } function getBindingElementNameText(element) { if (element.parent.kind === 174) { var name = element.propertyName || element.name; @@ -30241,7 +30326,7 @@ var ts; parent.parent.operatorToken.kind === 58 && parent.parent.left === parent && !ts.isAssignmentTarget(parent.parent) && - isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression(parent.argumentExpression), 84 | 2048); + isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84); return isLengthPushOrUnshift || isElementAssignment; } function maybeTypePredicateCall(node) { @@ -30387,7 +30472,7 @@ var ts; } else { var indexType = getTypeOfExpression(node.left.argumentExpression); - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 | 2048)) { + if (isTypeAssignableToKind(indexType, 84)) { evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right); } } @@ -31073,7 +31158,7 @@ var ts; break; case 149: case 148: - if (ts.getModifierFlags(container) & 32) { + if (ts.hasModifier(container, 32)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); } break; @@ -31164,14 +31249,14 @@ var ts; if (!isCallExpression && container.kind === 152) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if ((ts.getModifierFlags(container) & 32) || isCallExpression) { + if (ts.hasModifier(container, 32) || isCallExpression) { nodeCheckFlag = 512; } else { nodeCheckFlag = 256; } getNodeLinks(node).flags |= nodeCheckFlag; - if (container.kind === 151 && ts.getModifierFlags(container) & 256) { + if (container.kind === 151 && ts.hasModifier(container, 256)) { if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= 4096; } @@ -31216,7 +31301,7 @@ var ts; } else { if (ts.isClassLike(container.parent) || container.parent.kind === 178) { - if (ts.getModifierFlags(container) & 32) { + if (ts.hasModifier(container, 32)) { return container.kind === 151 || container.kind === 150 || container.kind === 153 || @@ -31742,10 +31827,7 @@ var ts; } } function isNumericComputedName(name) { - return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), 84); - } - function isTypeAnyOrAllConstituentTypesHaveKind(type, kind) { - return isTypeAny(type) || isTypeOfKind(type, kind); + return isTypeAssignableToKind(checkComputedPropertyName(name), 84); } function isInfinityOrNaNString(name) { return name === "Infinity" || name === "-Infinity" || name === "NaN"; @@ -31757,7 +31839,9 @@ var ts; var links = getNodeLinks(node.expression); if (!links.resolvedType) { links.resolvedType = checkExpression(node.expression); - if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 84 | 262178 | 512)) { + if (links.resolvedType.flags & 6144 || + !isTypeAssignableToKind(links.resolvedType, 262178 | 84 | 512) && + !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -32242,9 +32326,7 @@ var ts; return undefined; } function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) { - if (!elementType) { - elementType = checkExpression(openingLikeElement.tagName); - } + if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); } if (elementType.flags & 65536) { var types = elementType.types; return getUnionType(types.map(function (type) { @@ -32339,11 +32421,12 @@ var ts; } function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) { var links = getNodeLinks(node); - if (!links.resolvedJsxElementAttributesType) { + var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { var elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); } - return links.resolvedJsxElementAttributesType; + return links[linkLocation]; } function getAllAttributesTypeFromJsxOpeningLikeElement(node) { if (isJsxIntrinsicIdentifier(node.tagName)) { @@ -32699,7 +32782,7 @@ var ts; if (prop && noUnusedIdentifiers && (prop.flags & 106500) && - prop.valueDeclaration && (ts.getModifierFlags(prop.valueDeclaration) & 8)) { + prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8)) { if (ts.getCheckFlags(prop) & 1) { getSymbolLinks(prop).target.isReferenced = true; } @@ -32970,8 +33053,8 @@ var ts; } return undefined; } - function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper) { - var context = createInferenceContext(signature, 1); + function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) { + var context = createInferenceContext(signature, 1, compareTypes); forEachMatchingParameterType(contextualSignature, signature, function (source, target) { inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); }); @@ -33201,7 +33284,7 @@ var ts; return getLiteralType(element.name.text); case 144: var nameType = checkComputedPropertyName(element.name); - if (isTypeOfKind(nameType, 512)) { + if (isTypeAssignableToKind(nameType, 512)) { return nameType; } else { @@ -33294,9 +33377,10 @@ var ts; return resolveErrorCall(node); } var args = getEffectiveCallArguments(node); + var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; var excludeArgument; var excludeCount = 0; - if (!isDecorator) { + if (!isDecorator && !isSingleNonGenericCandidate) { for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { if (isContextSensitive(args[i])) { if (!excludeArgument) { @@ -33388,6 +33472,17 @@ var ts; if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; + if (isSingleNonGenericCandidate) { + var candidate = candidates[0]; + if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + return undefined; + } + if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, false)) { + candidateForArgumentError = candidate; + return undefined; + } + return candidate; + } for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { var originalCandidate = candidates[candidateIndex]; if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { @@ -33518,7 +33613,7 @@ var ts; return resolveErrorCall(node); } var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && ts.getModifierFlags(valueDecl) & 128) { + if (valueDecl && ts.hasModifier(valueDecl, 128)) { error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -33554,8 +33649,8 @@ var ts; return true; } var declaration = signature.declaration; - var modifiers = ts.getModifierFlags(declaration); - if (!(modifiers & 24)) { + var modifiers = ts.getSelectedModifierFlags(declaration, 24); + if (!modifiers) { return true; } var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); @@ -33758,11 +33853,33 @@ var ts; if (moduleSymbol) { var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); } } return createPromiseReturnType(node, anyType); } + function getTypeWithSyntheticDefaultImportType(type, symbol) { + if (allowSyntheticDefaultImports && type && type !== unknownType) { + var synthType = type; + if (!synthType.syntheticType) { + if (!getPropertyOfType(type, "default")) { + var memberTable = ts.createSymbolTable(); + var newSymbol = createSymbol(2097152, "default"); + newSymbol.target = resolveSymbol(symbol); + memberTable.set("default", newSymbol); + var anonymousSymbol = createSymbol(2048, "__type"); + var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, undefined, undefined); + anonymousSymbol.type = defaultContainingObject; + synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + } + else { + synthType.syntheticType = type; + } + } + return synthType.syntheticType; + } + return type; + } function isCommonJsRequire(node) { if (!ts.isRequireCall(node, true)) { return false; @@ -33881,15 +33998,15 @@ var ts; } } } - function assignBindingElementTypes(node) { - if (ts.isBindingPattern(node.name)) { - for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) { - var element = _a[_i]; - if (!ts.isOmittedExpression(element)) { - if (element.name.kind === 71) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); - } - assignBindingElementTypes(element); + function assignBindingElementTypes(pattern) { + for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (!ts.isOmittedExpression(element)) { + if (element.name.kind === 71) { + getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + } + else { + assignBindingElementTypes(element.name); } } } @@ -33898,12 +34015,13 @@ var ts; var links = getSymbolLinks(parameter); if (!links.type) { links.type = contextualType; - var name = ts.getNameOfDeclaration(parameter.valueDeclaration); - if (links.type === emptyObjectType && - (name.kind === 174 || name.kind === 175)) { - links.type = getTypeFromBindingPattern(name); + var decl = parameter.valueDeclaration; + if (decl.name.kind !== 71) { + if (links.type === emptyObjectType) { + links.type = getTypeFromBindingPattern(decl.name); + } + assignBindingElementTypes(decl.name); } - assignBindingElementTypes(parameter.valueDeclaration); } } function createPromiseType(promisedType) { @@ -34104,14 +34222,14 @@ var ts; } function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) { ts.Debug.assert(node.kind !== 151 || ts.isObjectLiteralMethod(node)); - var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); - if (!hasGrammarError && node.kind === 186) { - checkGrammarForGenerator(node); - } if (checkMode === 1 && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } + var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); + if (!hasGrammarError && node.kind === 186) { + checkGrammarForGenerator(node); + } var links = getNodeLinks(node); var type = getTypeOfSymbol(node.symbol); if (!(links.flags & 1024)) { @@ -34181,7 +34299,7 @@ var ts; } } function checkArithmeticOperandType(operand, type, diagnostic) { - if (!isTypeAnyOrAllConstituentTypesHaveKind(type, 84)) { + if (!isTypeAssignableToKind(type, 84)) { error(operand, diagnostic); return false; } @@ -34269,8 +34387,13 @@ var ts; if (operandType === silentNeverType) { return silentNeverType; } - if (node.operator === 38 && node.operand.kind === 8) { - return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + if (node.operand.kind === 8) { + if (node.operator === 38) { + return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + } + else if (node.operator === 37) { + return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text)); + } } switch (node.operator) { case 37: @@ -34322,30 +34445,22 @@ var ts; } return false; } - function isTypeOfKind(type, kind) { - if (type.flags & kind) { - return true; - } - if (type.flags & 65536) { - var types = type.types; - for (var _i = 0, types_18 = types; _i < types_18.length; _i++) { - var t = types_18[_i]; - if (!isTypeOfKind(t, kind)) { - return false; - } - } + function isTypeAssignableToKind(source, kind, strict) { + if (source.flags & kind) { return true; } - if (type.flags & 131072) { - var types = type.types; - for (var _a = 0, types_19 = types; _a < types_19.length; _a++) { - var t = types_19[_a]; - if (isTypeOfKind(t, kind)) { - return true; - } - } + if (strict && source.flags & (1 | 1024 | 2048 | 4096)) { + return false; } - return false; + return (kind & 84 && isTypeAssignableTo(source, numberType)) || + (kind & 262178 && isTypeAssignableTo(source, stringType)) || + (kind & 136 && isTypeAssignableTo(source, booleanType)) || + (kind & 1024 && isTypeAssignableTo(source, voidType)) || + (kind & 8192 && isTypeAssignableTo(source, neverType)) || + (kind & 4096 && isTypeAssignableTo(source, nullType)) || + (kind & 2048 && isTypeAssignableTo(source, undefinedType)) || + (kind & 512 && isTypeAssignableTo(source, esSymbolType)) || + (kind & 16777216 && isTypeAssignableTo(source, nonPrimitiveType)); } function isConstEnumObjectType(type) { return getObjectFlags(type) & 16 && type.symbol && isConstEnumSymbol(type.symbol); @@ -34357,7 +34472,7 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (isTypeOfKind(leftType, 8190)) { + if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190)) { error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } if (!(isTypeAny(rightType) || @@ -34374,18 +34489,18 @@ var ts; } leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); - if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, 84 | 512))) { + if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 | 512))) { error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 | 540672 | 16777216)) { + if (!isTypeAssignableToKind(rightType, 16777216 | 540672)) { error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; } function checkObjectLiteralAssignment(node, sourceType) { var properties = node.properties; - for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { - var p = properties_6[_i]; + for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) { + var p = properties_7[_i]; checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties); } return sourceType; @@ -34641,24 +34756,22 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (!isTypeOfKind(leftType, 1 | 262178) && !isTypeOfKind(rightType, 1 | 262178)) { + if (!isTypeAssignableToKind(leftType, 262178) && !isTypeAssignableToKind(rightType, 262178)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } var resultType = void 0; - if (isTypeOfKind(leftType, 84) && isTypeOfKind(rightType, 84)) { + if (isTypeAssignableToKind(leftType, 84, true) && isTypeAssignableToKind(rightType, 84, true)) { resultType = numberType; } - else { - if (isTypeOfKind(leftType, 262178) || isTypeOfKind(rightType, 262178)) { - resultType = stringType; - } - else if (isTypeAny(leftType) || isTypeAny(rightType)) { - resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; - } - if (resultType && !checkForDisallowedESSymbolOperand(operator)) { - return resultType; - } + else if (isTypeAssignableToKind(leftType, 262178, true) || isTypeAssignableToKind(rightType, 262178, true)) { + resultType = stringType; + } + else if (isTypeAny(leftType) || isTypeAny(rightType)) { + resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; + } + if (resultType && !checkForDisallowedESSymbolOperand(operator)) { + return resultType; } if (!resultType) { reportOperatorError(); @@ -34823,13 +34936,12 @@ var ts; return getBestChoiceType(type1, type2); } function checkLiteralExpression(node) { - if (node.kind === 8) { - checkGrammarNumericLiteral(node); - } switch (node.kind) { + case 13: case 9: return getFreshTypeOfLiteralType(getLiteralType(node.text)); case 8: + checkGrammarNumericLiteral(node); return getFreshTypeOfLiteralType(getLiteralType(+node.text)); case 101: return trueType; @@ -34977,6 +35089,7 @@ var ts; return checkSuperExpression(node); case 95: return nullWideningType; + case 13: case 9: case 8: case 101: @@ -34984,8 +35097,6 @@ var ts; return checkLiteralExpression(node); case 196: return checkTemplateExpression(node); - case 13: - return stringType; case 12: return globalRegExpType; case 177: @@ -35076,7 +35187,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); checkVariableLikeDeclaration(node); var func = ts.getContainingFunction(node); - if (ts.getModifierFlags(node) & 92) { + if (ts.hasModifier(node, 92)) { func = ts.getContainingFunction(node); if (!(func.kind === 152 && ts.nodeIsPresent(func.body))) { error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -35266,7 +35377,7 @@ var ts; } } else { - var isStatic = ts.getModifierFlags(member) & 32; + var isStatic = ts.hasModifier(member, 32); var names = isStatic ? staticNames : instanceNames; var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); if (memberName) { @@ -35311,7 +35422,7 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var memberNameNode = member.name; - var isStatic = ts.getModifierFlags(member) & 32; + var isStatic = ts.hasModifier(member, 32); if (isStatic && memberNameNode) { var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -35399,7 +35510,7 @@ var ts; function checkMethodDeclaration(node) { checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name); checkFunctionOrMethodDeclaration(node); - if (ts.getModifierFlags(node) & 128 && node.body) { + if (ts.hasModifier(node, 128) && node.body) { error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } @@ -35435,17 +35546,9 @@ var ts; } return ts.forEachChild(n, containsSuperCall); } - function markThisReferencesAsErrors(n) { - if (n.kind === 99) { - error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location); - } - else if (n.kind !== 186 && n.kind !== 228) { - ts.forEachChild(n, markThisReferencesAsErrors); - } - } function isInstancePropertyWithInitializer(n) { return n.kind === 149 && - !(ts.getModifierFlags(n) & 32) && + !ts.hasModifier(n, 32) && !!n.initializer; } var containingClassDecl = node.parent; @@ -35457,8 +35560,8 @@ var ts; if (classExtendsNull) { error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } - var superCallShouldBeFirst = ts.forEach(node.parent.members, isInstancePropertyWithInitializer) || - ts.forEach(node.parameters, function (p) { return ts.getModifierFlags(p) & 92; }); + var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) || + ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92); }); if (superCallShouldBeFirst) { var statements = node.body.statements; var superCallStatement = void 0; @@ -35501,10 +35604,12 @@ var ts; var otherKind = node.kind === 153 ? 154 : 153; var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if ((ts.getModifierFlags(node) & 28) !== (ts.getModifierFlags(otherAccessor) & 28)) { + var nodeFlags = ts.getModifierFlags(node); + var otherFlags = ts.getModifierFlags(otherAccessor); + if ((nodeFlags & 28) !== (otherFlags & 28)) { error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (ts.hasModifier(node, 128) !== ts.hasModifier(otherAccessor, 128)) { + if ((nodeFlags & 128) !== (otherFlags & 128)) { error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type); @@ -35558,7 +35663,14 @@ var ts; ts.forEach(node.typeArguments, checkSourceElement); if (produceDiagnostics) { var symbol = getNodeLinks(node).resolvedSymbol; - var typeParameters = symbol.flags & 524288 ? getSymbolLinks(symbol).typeParameters : type.target.localTypeParameters; + if (!symbol) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return; + } + var typeParameters = symbol.flags & 524288 && getSymbolLinks(symbol).typeParameters; + if (!typeParameters && getObjectFlags(type) & 4) { + typeParameters = type.target.localTypeParameters; + } checkTypeArgumentConstraints(typeParameters, node.typeArguments); } } @@ -35601,7 +35713,7 @@ var ts; if (isTypeAssignableTo(indexType, getIndexType(objectType))) { return type; } - if (maybeTypeOfKind(objectType, 540672) && isTypeOfKind(indexType, 84)) { + if (maybeTypeOfKind(objectType, 540672) && isTypeAssignableToKind(indexType, 84)) { var constraint = getBaseConstraintOfType(objectType); if (constraint && getIndexInfoOfType(constraint, 1)) { return type; @@ -35611,6 +35723,8 @@ var ts; return type; } function checkIndexedAccessType(node) { + checkSourceElement(node.objectType); + checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } function checkMappedType(node) { @@ -35621,7 +35735,7 @@ var ts; checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); } function isPrivateWithinAmbient(node) { - return (ts.getModifierFlags(node) & 8) && ts.isInAmbientContext(node); + return ts.hasModifier(node, 8) && ts.isInAmbientContext(node); } function getEffectiveDeclarationFlags(n, flagsToCheck) { var flags = ts.getCombinedModifierFlags(n); @@ -35708,9 +35822,9 @@ var ts; (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { var reportError = (node.kind === 151 || node.kind === 150) && - (ts.getModifierFlags(node) & 32) !== (ts.getModifierFlags(subsequentNode) & 32); + ts.hasModifier(node, 32) !== ts.hasModifier(subsequentNode, 32); if (reportError) { - var diagnostic = ts.getModifierFlags(node) & 32 ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; + var diagnostic = ts.hasModifier(node, 32) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode_1, diagnostic); } return; @@ -35726,7 +35840,7 @@ var ts; error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing); } else { - if (ts.getModifierFlags(node) & 128) { + if (ts.hasModifier(node, 128)) { error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -35736,8 +35850,8 @@ var ts; } var duplicateFunctionDeclaration = false; var multipleConstructorImplementation = false; - for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { - var current = declarations_5[_i]; + for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { + var current = declarations_4[_i]; var node = current; var inAmbientContext = ts.isInAmbientContext(node); var inAmbientContextOrInterface = node.parent.kind === 230 || node.parent.kind === 163 || inAmbientContext; @@ -35786,7 +35900,7 @@ var ts; }); } if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(ts.getModifierFlags(lastSeenNonAmbientDeclaration) & 128) && !lastSeenNonAmbientDeclaration.questionToken) { + !ts.hasModifier(lastSeenNonAmbientDeclaration, 128) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } if (hasOverloads) { @@ -36330,14 +36444,14 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 151 || member.kind === 149) { - if (!member.symbol.isReferenced && ts.getModifierFlags(member) & 8) { + if (!member.symbol.isReferenced && ts.hasModifier(member, 8)) { error(member.name, ts.Diagnostics._0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(member.symbol.escapedName)); } } else if (member.kind === 152) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; - if (!parameter.symbol.isReferenced && ts.getModifierFlags(parameter) & 8) { + if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8)) { error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(parameter.symbol.escapedName)); } } @@ -36677,7 +36791,7 @@ var ts; 128 | 64 | 32; - return (ts.getModifierFlags(left) & interestingFlags) === (ts.getModifierFlags(right) & interestingFlags); + return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); @@ -36807,7 +36921,7 @@ var ts; checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access); } } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 | 540672 | 16777216)) { + if (!isTypeAssignableToKind(rightType, 16777216 | 540672)) { error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } checkSourceElement(node.statement); @@ -37179,7 +37293,7 @@ var ts; var classDeclaration = type.symbol.valueDeclaration; for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) { var member = _a[_i]; - if (!(ts.getModifierFlags(member) & 32) && ts.hasDynamicName(member)) { + if (!ts.hasModifier(member, 32) && ts.hasDynamicName(member)) { var propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1); @@ -37276,8 +37390,8 @@ var ts; var type = getDeclaredTypeOfSymbol(symbol); if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) { var name = symbolToString(symbol); - for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { - var declaration = declarations_6[_i]; + for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { + var declaration = declarations_5[_i]; error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } @@ -37286,8 +37400,8 @@ var ts; function areTypeParametersIdentical(declarations, typeParameters) { var maxTypeArgumentCount = ts.length(typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { - var declaration = declarations_7[_i]; + for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { + var declaration = declarations_6[_i]; var numTypeParameters = ts.length(declaration.typeParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { return false; @@ -37323,7 +37437,7 @@ var ts; registerForUnusedIdentifiersCheck(node); } function checkClassDeclaration(node) { - if (!node.name && !(ts.getModifierFlags(node) & 512)) { + if (!node.name && !ts.hasModifier(node, 512)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -37416,7 +37530,7 @@ var ts; var signatures = getSignaturesOfType(type, 1); if (signatures.length) { var declaration = signatures[0].declaration; - if (declaration && ts.getModifierFlags(declaration) & 8) { + if (declaration && ts.hasModifier(declaration, 8)) { var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); @@ -37449,7 +37563,7 @@ var ts; if (derived) { if (derived === base) { var derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol); - if (baseDeclarationFlags & 128 && (!derivedClassDecl || !(ts.getModifierFlags(derivedClassDecl) & 128))) { + if (baseDeclarationFlags & 128 && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128))) { if (derivedClassDecl.kind === 199) { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } @@ -37497,8 +37611,8 @@ var ts; for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) { var base = baseTypes_2[_i]; var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); - for (var _a = 0, properties_7 = properties; _a < properties_7.length; _a++) { - var prop = properties_7[_a]; + for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) { + var prop = properties_8[_a]; var existing = seen.get(prop.escapedName); if (!existing) { seen.set(prop.escapedName, { prop: prop, containingType: base }); @@ -37752,8 +37866,8 @@ var ts; } function getFirstNonAmbientClassOrFunctionDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { - var declaration = declarations_8[_i]; + for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { + var declaration = declarations_7[_i]; if ((declaration.kind === 229 || (declaration.kind === 228 && ts.nodeIsPresent(declaration.body))) && !ts.isInAmbientContext(declaration)) { @@ -37968,7 +38082,7 @@ var ts; if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -37995,7 +38109,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (ts.getModifierFlags(node) & 1) { + if (ts.hasModifier(node, 1)) { markExportAsReferenced(node); } if (ts.isInternalModuleImportEqualsDeclaration(node)) { @@ -38023,7 +38137,7 @@ var ts; if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { @@ -38081,7 +38195,7 @@ var ts; } return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === 71) { @@ -38128,8 +38242,8 @@ var ts; return; } if (exportedDeclarationsCount > 1) { - for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { - var declaration = declarations_9[_i]; + for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { + var declaration = declarations_8[_i]; if (isNotOverload(declaration)) { diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } @@ -38407,7 +38521,7 @@ var ts; return []; } var symbols = ts.createSymbolTable(); - var memberFlags = 0; + var isStatic = false; populateSymbols(); return symbolsToArray(symbols); function populateSymbols() { @@ -38429,7 +38543,7 @@ var ts; } case 229: case 230: - if (!(memberFlags & 32)) { + if (!isStatic) { copySymbols(getSymbolOfNode(location).members, meaning & 793064); } break; @@ -38443,7 +38557,7 @@ var ts; if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } - memberFlags = ts.getModifierFlags(location); + isStatic = ts.hasModifier(location, 32); location = location.parent; } copySymbols(globals, meaning); @@ -38779,7 +38893,7 @@ var ts; } function getParentTypeOfClassElement(node) { var classSymbol = getSymbolOfNode(node.parent); - return ts.getModifierFlags(node) & 32 + return ts.hasModifier(node, 32) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -39004,13 +39118,13 @@ var ts; return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && - !(ts.getModifierFlags(parameter) & 92); + !ts.hasModifier(parameter, 92); } function isOptionalUninitializedParameterProperty(parameter) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - !!(ts.getModifierFlags(parameter) & 92); + ts.hasModifier(parameter, 92); } function getNodeCheckFlags(node) { return getNodeLinks(node).flags; @@ -39066,22 +39180,22 @@ var ts; else if (type.flags & 1) { return ts.TypeReferenceSerializationKind.ObjectType; } - else if (isTypeOfKind(type, 1024 | 6144 | 8192)) { + else if (isTypeAssignableToKind(type, 1024 | 6144 | 8192)) { return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } - else if (isTypeOfKind(type, 136)) { + else if (isTypeAssignableToKind(type, 136)) { return ts.TypeReferenceSerializationKind.BooleanType; } - else if (isTypeOfKind(type, 84)) { + else if (isTypeAssignableToKind(type, 84)) { return ts.TypeReferenceSerializationKind.NumberLikeType; } - else if (isTypeOfKind(type, 262178)) { + else if (isTypeAssignableToKind(type, 262178)) { return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } - else if (isTypeOfKind(type, 512)) { + else if (isTypeAssignableToKind(type, 512)) { return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { @@ -39546,7 +39660,7 @@ var ts; node.kind !== 154) { return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === 229 && ts.getModifierFlags(node.parent) & 128)) { + if (!(node.parent.kind === 229 && ts.hasModifier(node.parent, 128))) { return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & 32) { @@ -39742,7 +39856,7 @@ var ts; if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (ts.getModifierFlags(parameter) !== 0) { + if (ts.hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -40021,10 +40135,10 @@ var ts; else if (ts.isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(ts.getModifierFlags(accessor) & 128)) { + else if (accessor.body === undefined && !ts.hasModifier(accessor, 128)) { return grammarErrorAtPos(ts.getSourceFileOfNode(accessor), accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } - else if (accessor.body && ts.getModifierFlags(accessor) & 128) { + else if (accessor.body && ts.hasModifier(accessor, 128)) { return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { @@ -40333,7 +40447,7 @@ var ts; node.kind === 244 || node.kind === 243 || node.kind === 236 || - ts.getModifierFlags(node) & (2 | 1 | 512)) { + ts.hasModifier(node, 2 | 1 | 512)) { return false; } return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); @@ -43102,27 +43216,27 @@ var ts; function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) { var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; if (property === firstAccessor) { - var properties_8 = []; + var properties_9 = []; if (getAccessor) { var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, undefined, undefined, undefined, getAccessor.parameters, undefined, getAccessor.body); ts.setTextRange(getterFunction, getAccessor); ts.setOriginalNode(getterFunction, getAccessor); var getter = ts.createPropertyAssignment("get", getterFunction); - properties_8.push(getter); + properties_9.push(getter); } if (setAccessor) { var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, undefined, undefined, undefined, setAccessor.parameters, undefined, setAccessor.body); ts.setTextRange(setterFunction, setAccessor); ts.setOriginalNode(setterFunction, setAccessor); var setter = ts.createPropertyAssignment("set", setterFunction); - properties_8.push(setter); + properties_9.push(setter); } - properties_8.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); - properties_8.push(ts.createPropertyAssignment("configurable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue())); var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), undefined, [ receiver, createExpressionForPropertyName(property.name), - ts.createObjectLiteral(properties_8, multiLine) + ts.createObjectLiteral(properties_9, multiLine) ]), firstAccessor); return ts.aggregateTransformFlags(expression); } @@ -45062,7 +45176,8 @@ var ts; ? undefined : numElements, location), false, location); } - else if (numElements !== 1 && (flattenContext.level < 1 || numElements === 0)) { + else if (numElements !== 1 && (flattenContext.level < 1 || numElements === 0) + || ts.every(elements, ts.isOmittedExpression)) { var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } @@ -45269,7 +45384,12 @@ var ts; if (ts.hasModifier(node, 2)) { break; } - recordEmittedDeclarationInScope(node); + if (node.name) { + recordEmittedDeclarationInScope(node); + } + else { + ts.Debug.assert(node.kind === 229 || ts.hasModifier(node, 512)); + } break; } } @@ -45683,8 +45803,8 @@ var ts; && member.initializer !== undefined; } function addInitializedPropertyStatements(statements, properties, receiver) { - for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) { - var property = properties_9[_i]; + for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { + var property = properties_10[_i]; var statement = ts.createStatement(transformInitializedProperty(property, receiver)); ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); ts.setCommentRange(statement, property); @@ -45693,8 +45813,8 @@ var ts; } function generateInitializedPropertyExpressions(properties, receiver) { var expressions = []; - for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { - var property = properties_10[_i]; + for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { + var property = properties_11[_i]; var expression = transformInitializedProperty(property, receiver); expression.startsOnNewLine = true; ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); @@ -46389,24 +46509,24 @@ var ts; && moduleKind !== ts.ModuleKind.System); } function recordEmittedDeclarationInScope(node) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - if (!currentScopeFirstDeclarationsOfName) { - currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); - } - if (!currentScopeFirstDeclarationsOfName.has(name)) { - currentScopeFirstDeclarationsOfName.set(name, node); - } + if (!currentScopeFirstDeclarationsOfName) { + currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); + } + var name = declaredNameInScope(node); + if (!currentScopeFirstDeclarationsOfName.has(name)) { + currentScopeFirstDeclarationsOfName.set(name, node); } } function isFirstEmittedDeclarationInScope(node) { if (currentScopeFirstDeclarationsOfName) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - return currentScopeFirstDeclarationsOfName.get(name) === node; - } + var name = declaredNameInScope(node); + return currentScopeFirstDeclarationsOfName.get(name) === node; } - return false; + return true; + } + function declaredNameInScope(node) { + ts.Debug.assertNode(node.name, ts.isIdentifier); + return node.name.escapedText; } function addVarForEnumOrModuleDeclaration(statements, node) { var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([ @@ -46437,7 +46557,7 @@ var ts; if (!shouldEmitModuleDeclaration(node)) { return ts.createNotEmittedStatement(node); } - ts.Debug.assert(ts.isIdentifier(node.name), "TypeScript module should have an Identifier name."); + ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name."); enableSubstitutionForNamespaceExports(); var statements = []; var emitFlags = 2; @@ -47161,6 +47281,8 @@ var ts; return visitExpressionStatement(node); case 185: return visitParenthesizedExpression(node, noDestructuringValue); + case 260: + return visitCatchClause(node); default: return ts.visitEachChild(node, visitor, context); } @@ -47235,6 +47357,12 @@ var ts; function visitParenthesizedExpression(node, noDestructuringValue) { return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context); } + function visitCatchClause(node) { + if (!node.variableDeclaration) { + return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(undefined)), ts.visitNode(node.block, visitor, ts.isBlock)); + } + return ts.visitEachChild(node, visitor, context); + } function visitBinaryExpression(node, noDestructuringValue) { if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 1048576) { return ts.flattenDestructuringAssignment(node, visitor, context, 1, !noDestructuringValue); @@ -47681,7 +47809,7 @@ var ts; objectProperties = ts.createAssignHelper(context, segments); } } - var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.filter(ts.map(children, transformJsxChildToExpression), ts.isDefined), node, location); + var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } @@ -48268,7 +48396,7 @@ var ts; function shouldVisitNode(node) { return (node.transformFlags & 128) !== 0 || convertedLoopState !== undefined - || (hierarchyFacts & 4096 && ts.isStatement(node)) + || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207))) || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node)) || isTypeScriptClassWrapper(node); } @@ -48548,9 +48676,11 @@ var ts; var outer = ts.createPartiallyEmittedExpression(inner); outer.end = ts.skipTrivia(currentText, node.pos); ts.setEmitFlags(outer, 1536); - return ts.createParen(ts.createCall(outer, undefined, extendsClauseElement + var result = ts.createParen(ts.createCall(outer, undefined, extendsClauseElement ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)] : [])); + ts.addSyntheticLeadingComment(result, 3, "* @class "); + return result; } function transformClassBody(node, extendsClauseElement) { var statements = []; @@ -49135,11 +49265,12 @@ var ts; ts.setTextRange(declarationList, node); ts.setCommentRange(declarationList, node); if (node.transformFlags & 8388608 - && (ts.isBindingPattern(node.declarations[0].name) - || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { + && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { var firstDeclaration = ts.firstOrUndefined(declarations); - var lastDeclaration = ts.lastOrUndefined(declarations); - ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + if (firstDeclaration) { + var lastDeclaration = ts.lastOrUndefined(declarations); + ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + } } return declarationList; } @@ -49678,6 +49809,7 @@ var ts; function visitCatchClause(node) { var ancestorFacts = enterSubtree(4032, 0); var updated; + ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (ts.isBindingPattern(node.variableDeclaration.name)) { var temp = ts.createTempVariable(undefined); var newVariableDeclaration = ts.createVariableDeclaration(temp); @@ -51197,9 +51329,6 @@ var ts; var block = endBlock(); markLabel(block.endLabel); } - function isWithBlock(block) { - return block.kind === 1; - } function beginExceptionBlock() { var startLabel = defineLabel(); var endLabel = defineLabel(); @@ -51268,9 +51397,6 @@ var ts; emitNop(); exception.state = 3; } - function isExceptionBlock(block) { - return block.kind === 0; - } function beginScriptLoopBlock() { beginBlock({ kind: 3, @@ -51434,7 +51560,7 @@ var ts; return literal; } function createInlineBreak(label, location) { - ts.Debug.assert(label > 0, "Invalid label: " + label); + ts.Debug.assertLessThan(0, label, "Invalid label"); return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3), createLabel(label) @@ -51642,31 +51768,33 @@ var ts; for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { var block = blocks[blockIndex]; var blockAction = blockActions[blockIndex]; - if (isExceptionBlock(block)) { - if (blockAction === 0) { - if (!exceptionBlockStack) { - exceptionBlockStack = []; + switch (block.kind) { + case 0: + if (blockAction === 0) { + if (!exceptionBlockStack) { + exceptionBlockStack = []; + } + if (!statements) { + statements = []; + } + exceptionBlockStack.push(currentExceptionBlock); + currentExceptionBlock = block; } - if (!statements) { - statements = []; + else if (blockAction === 1) { + currentExceptionBlock = exceptionBlockStack.pop(); } - exceptionBlockStack.push(currentExceptionBlock); - currentExceptionBlock = block; - } - else if (blockAction === 1) { - currentExceptionBlock = exceptionBlockStack.pop(); - } - } - else if (isWithBlock(block)) { - if (blockAction === 0) { - if (!withBlockStack) { - withBlockStack = []; + break; + case 1: + if (blockAction === 0) { + if (!withBlockStack) { + withBlockStack = []; + } + withBlockStack.push(block); } - withBlockStack.push(block); - } - else if (blockAction === 1) { - withBlockStack.pop(); - } + else if (blockAction === 1) { + withBlockStack.pop(); + } + break; } } } @@ -54857,6 +54985,9 @@ var ts; return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); }); } function writeVariableStatement(node) { + if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) { + return; + } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isLet(node.declarationList)) { @@ -55822,14 +55953,14 @@ var ts; writer.writeLine(); } } - function emitTrailingCommentsOfPosition(pos) { + function emitTrailingCommentsOfPosition(pos, prefixSpace) { if (disabled) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeEmitTrailingCommentsOfPosition"); } - forEachTrailingCommentToEmit(pos, emitTrailingCommentOfPosition); + forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition); if (extendedDiagnostics) { ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); } @@ -55909,15 +56040,7 @@ var ts; emitPos(commentEnd); } function isTripleSlashComment(commentPos, commentEnd) { - if (currentText.charCodeAt(commentPos + 1) === 47 && - commentPos + 2 < commentEnd && - currentText.charCodeAt(commentPos + 2) === 47) { - var textSubStr = currentText.substring(commentPos, commentEnd); - return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || - textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ? - true : false; - } - return false; + return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd); } } ts.createCommentWriter = createCommentWriter; @@ -56856,7 +56979,9 @@ var ts; if (!(ts.getEmitFlags(node) & 131072)) { var dotRangeStart = node.expression.end; var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1; - var dotToken = { kind: 23, pos: dotRangeStart, end: dotRangeEnd }; + var dotToken = ts.createToken(23); + dotToken.pos = dotRangeStart; + dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } @@ -56968,7 +57093,9 @@ var ts; var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right); emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); + emitLeadingCommentsOfPosition(node.operatorToken.pos); writeTokenNode(node.operatorToken); + emitTrailingCommentsOfPosition(node.operatorToken.end, true); increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); decreaseIndentIf(indentBeforeOperator, indentAfterOperator); @@ -57155,8 +57282,19 @@ var ts; emitWithPrefix(" ", node.label); write(";"); } + function emitTokenWithComment(token, pos, contextNode) { + var node = contextNode && ts.getParseTreeNode(contextNode); + if (node && node.kind === contextNode.kind) { + pos = ts.skipTrivia(currentSourceFile.text, pos); + } + pos = writeToken(token, pos, contextNode); + if (node && node.kind === contextNode.kind) { + emitTrailingCommentsOfPosition(pos, true); + } + return pos; + } function emitReturnStatement(node) { - writeToken(96, node.pos, node); + emitTokenWithComment(96, node.pos, node); emitExpressionWithPrefix(" ", node.expression); write(";"); } @@ -57597,10 +57735,12 @@ var ts; function emitCatchClause(node) { var openParenPos = writeToken(74, node.pos); write(" "); - writeToken(19, openParenPos); - emit(node.variableDeclaration); - writeToken(20, node.variableDeclaration ? node.variableDeclaration.end : openParenPos); - write(" "); + if (node.variableDeclaration) { + writeToken(19, openParenPos); + emit(node.variableDeclaration); + writeToken(20, node.variableDeclaration.end); + write(" "); + } emit(node.block); } function emitPropertyAssignment(node) { @@ -58712,6 +58852,9 @@ var ts; var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; }; resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); }; } + var packageIdToSourceFile = ts.createMap(); + var sourceFileToPackageName = ts.createMap(); + var redirectTargetsSet = ts.createMap(); var filesByName = ts.createMap(); var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined; var structuralIsReused = tryReuseStructureFromOldProgram(); @@ -58768,6 +58911,8 @@ var ts; isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker, getSourceFileFromReference: getSourceFileFromReference, + sourceFileToPackageName: sourceFileToPackageName, + redirectTargetsSet: redirectTargetsSet, }; verifyCompilerOptions(); ts.performance.mark("afterProgram"); @@ -58911,17 +59056,51 @@ var ts; var filePaths = []; var modifiedSourceFiles = []; oldProgram.structureIsReused = 2; - for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) { - var oldSourceFile = _a[_i]; + var oldSourceFiles = oldProgram.getSourceFiles(); + var SeenPackageName; + (function (SeenPackageName) { + SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists"; + SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified"; + })(SeenPackageName || (SeenPackageName = {})); + var seenPackageNames = ts.createMap(); + for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { + var oldSourceFile = oldSourceFiles_1[_i]; var newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target) : host.getSourceFile(oldSourceFile.fileName, options.target); if (!newSourceFile) { return oldProgram.structureIsReused = 0; } + ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); + var fileChanged = void 0; + if (oldSourceFile.redirectInfo) { + if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { + return oldProgram.structureIsReused = 0; + } + fileChanged = false; + newSourceFile = oldSourceFile; + } + else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) { + if (newSourceFile !== oldSourceFile) { + return oldProgram.structureIsReused = 0; + } + fileChanged = false; + } + else { + fileChanged = newSourceFile !== oldSourceFile; + } newSourceFile.path = oldSourceFile.path; filePaths.push(newSourceFile.path); - if (oldSourceFile !== newSourceFile) { + var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); + if (packageName !== undefined) { + var prevKind = seenPackageNames.get(packageName); + var newKind = fileChanged ? 1 : 0; + if ((prevKind !== undefined && newKind === 1) || prevKind === 1) { + return oldProgram.structureIsReused = 0; + } + seenPackageNames.set(packageName, newKind); + } + if (fileChanged) { if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { oldProgram.structureIsReused = 1; } @@ -58949,8 +59128,8 @@ var ts; return oldProgram.structureIsReused; } modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; }); - for (var _b = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _b < modifiedSourceFiles_1.length; _b++) { - var _c = modifiedSourceFiles_1[_b], oldSourceFile = _c.oldFile, newSourceFile = _c.newFile; + for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) { + var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile; var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { var moduleNames = ts.map(ts.concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral); @@ -58984,8 +59163,8 @@ var ts; if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) { return oldProgram.structureIsReused = 1; } - for (var _d = 0, _e = oldProgram.getMissingFilePaths(); _d < _e.length; _d++) { - var p = _e[_d]; + for (var _c = 0, _d = oldProgram.getMissingFilePaths(); _c < _d.length; _c++) { + var p = _d[_c]; filesByName.set(p, undefined); } for (var i = 0; i < newSourceFiles.length; i++) { @@ -58993,11 +59172,13 @@ var ts; } files = newSourceFiles; fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics(); - for (var _f = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _f < modifiedSourceFiles_2.length; _f++) { - var modifiedFile = modifiedSourceFiles_2[_f]; + for (var _e = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _e < modifiedSourceFiles_2.length; _e++) { + var modifiedFile = modifiedSourceFiles_2[_e]; fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile); } resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives(); + sourceFileToPackageName = oldProgram.sourceFileToPackageName; + redirectTargetsSet = oldProgram.redirectTargetsSet; return oldProgram.structureIsReused = 2; } function getEmitHost(writeFileCallback) { @@ -59476,7 +59657,7 @@ var ts; } } function processSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd) { - getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd); }, function (diagnostic) { + getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, undefined); }, function (diagnostic) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; @@ -59493,7 +59674,24 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } } - function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd) { + function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) { + var redirect = Object.create(redirectTarget); + redirect.fileName = fileName; + redirect.path = path; + redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected }; + Object.defineProperties(redirect, { + id: { + get: function () { return this.redirectInfo.redirectTarget.id; }, + set: function (value) { this.redirectInfo.redirectTarget.id = value; }, + }, + symbol: { + get: function () { return this.redirectInfo.redirectTarget.symbol; }, + set: function (value) { this.redirectInfo.redirectTarget.symbol = value; }, + }, + }); + return redirect; + } + function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) { if (filesByName.has(path)) { var file_1 = filesByName.get(path); if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { @@ -59524,6 +59722,22 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); + if (packageId) { + var packageIdKey = packageId.name + "@" + packageId.version; + var fileFromPackageId = packageIdToSourceFile.get(packageIdKey); + if (fileFromPackageId) { + var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path); + redirectTargetsSet.set(fileFromPackageId.path, true); + filesByName.set(path, dupFile); + sourceFileToPackageName.set(path, packageId.name); + files.push(dupFile); + return dupFile; + } + else if (file) { + packageIdToSourceFile.set(packageIdKey, file); + sourceFileToPackageName.set(path, packageId.name); + } + } filesByName.set(path, file); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); @@ -59645,7 +59859,7 @@ var ts; else if (shouldAddFile) { var path = toPath(resolvedFileName); var pos = ts.skipTrivia(file.text, file.imports[i].pos); - findSourceFile(resolvedFileName, path, false, file, pos, file.imports[i].end); + findSourceFile(resolvedFileName, path, false, file, pos, file.imports[i].end, resolution.packageId); } if (isFromNodeModulesSearch) { currentNodeModulesDepth--; @@ -61220,6 +61434,7 @@ var ts; } ts.symbolToDisplayParts = symbolToDisplayParts; function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) { + flags |= 65536; return mapToDisplayParts(function (writer) { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); @@ -61925,11 +62140,11 @@ var ts; templateStack.pop(); } else { - ts.Debug.assert(token === 15, "Should have been a template middle. Was " + token); + ts.Debug.assertEqual(token, 15, "Should have been a template middle."); } } else { - ts.Debug.assert(lastTemplateStackToken === 17, "Should have been an open brace. Was: " + token); + ts.Debug.assertEqual(lastTemplateStackToken, 17, "Should have been an open brace"); templateStack.pop(); } } @@ -63587,7 +63802,7 @@ var ts; var typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); if (!typeForObject) return false; - typeMembers = typeChecker.getPropertiesOfType(typeForObject); + typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24); }); existingMembers = objectLikeContainer.elements; } } @@ -63964,8 +64179,8 @@ var ts; addPropertySymbols(implementingTypeSymbols, 24); return result; function addPropertySymbols(properties, inValidModifierFlags) { - for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { - var property = properties_11[_i]; + for (var _i = 0, properties_12 = properties; _i < properties_12.length; _i++) { + var property = properties_12[_i]; if (isValidProperty(property, inValidModifierFlags)) { result.push(property); } @@ -65655,11 +65870,15 @@ var ts; } function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) { var bindingElement = getObjectBindingElementWithoutPropertyName(symbol); - if (bindingElement) { - var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent); - return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text); + if (!bindingElement) + return undefined; + var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent); + var propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text); + if (propSymbol && propSymbol.flags & 98304) { + ts.Debug.assert(!!(propSymbol.flags & 33554432)); + return propSymbol.target; } - return undefined; + return propSymbol; } function getSymbolScope(symbol) { var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration; @@ -65679,12 +65898,13 @@ var ts; if (getObjectBindingElementWithoutPropertyName(symbol)) { return undefined; } - if (parent && !((parent.flags & 1536) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) { + var exposedByParent = parent && !(symbol.flags & 262144); + if (exposedByParent && !((parent.flags & 1536) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) { return undefined; } var scope; - for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) { - var declaration = declarations_10[_i]; + for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { + var declaration = declarations_9[_i]; var container = ts.getContainerNode(declaration); if (scope && scope !== container) { return undefined; @@ -65694,7 +65914,7 @@ var ts; } scope = container; } - return parent ? scope.getSourceFile() : scope; + return exposedByParent ? scope.getSourceFile() : scope; } function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) { if (container === void 0) { container = sourceFile; } @@ -66371,8 +66591,8 @@ var ts; var lastIterationMeaning = void 0; do { lastIterationMeaning = meaning; - for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { - var declaration = declarations_11[_i]; + for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) { + var declaration = declarations_10[_i]; var declarationMeaning = ts.getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; @@ -66517,6 +66737,16 @@ var ts; var shorthandContainerName_1 = typeChecker.symbolToString(symbol.parent, node); return ts.map(shorthandDeclarations, function (declaration) { return createDefinitionInfo(declaration, shorthandSymbolKind_1, shorthandSymbolName_1, shorthandContainerName_1); }); } + if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) && + (node === (node.parent.propertyName || node.parent.name))) { + var type = typeChecker.getTypeAtLocation(node.parent.parent); + if (type) { + var propSymbols = ts.getPropertySymbolsFromType(type, node); + if (propSymbols) { + return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); }); + } + } + } var element = ts.getContainingObjectLiteralElement(node); if (element && typeChecker.getContextualType(element.parent)) { return ts.flatMap(ts.getPropertySymbolsFromContextualType(typeChecker, element), function (propertySymbol) { @@ -66933,7 +67163,7 @@ var ts; "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console" ]; - var nodeCoreModules = ts.arrayToMap(JsTyping.nodeCoreModuleList, function (x) { return x; }); + var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList); function loadSafeList(host, safeListPath) { var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); }); return ts.createMapFromTemplate(result.config); @@ -67093,8 +67323,8 @@ var ts; if (!matches) { return; } - for (var _i = 0, declarations_12 = declarations; _i < declarations_12.length; _i++) { - var declaration = declarations_12[_i]; + for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { + var declaration = declarations_11[_i]; if (patternMatcher.patternContainsDots) { var containers = getContainers(declaration); if (!containers) { @@ -68741,8 +68971,8 @@ var ts; var nameToDeclarations = sourceFile.getNamedDeclarations(); var declarations = nameToDeclarations.get(name.text); if (declarations) { - for (var _b = 0, declarations_13 = declarations; _b < declarations_13.length; _b++) { - var declaration = declarations_13[_b]; + for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) { + var declaration = declarations_12[_b]; var symbol = declaration.symbol; if (symbol) { var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration); @@ -68775,7 +69005,9 @@ var ts; } var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 : 1; var argumentCount = getArgumentCount(list); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var argumentsSpan = getApplicableSpanForArguments(list, sourceFile); return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount }; } @@ -68853,7 +69085,9 @@ var ts; var argumentCount = tagExpression.template.kind === 13 ? 1 : tagExpression.template.templateSpans.length + 1; - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } return { kind: 2, invocation: tagExpression, @@ -68950,7 +69184,9 @@ var ts; tags: candidateSignature.getJsDocTags() }; }); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var selectedItemIndex = candidates.indexOf(resolvedSignature); ts.Debug.assert(selectedItemIndex !== -1); return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount }; @@ -69165,7 +69401,7 @@ var ts; else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304)) || (location.kind === 123 && location.parent.kind === 152)) { var functionDeclaration_1 = location.parent; - var locationIsSymbolDeclaration = ts.findDeclaration(symbol, function (declaration) { + var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) { return declaration === (location.kind === 123 ? functionDeclaration_1.parent : functionDeclaration_1); }); if (locationIsSymbolDeclaration) { @@ -69509,11 +69745,11 @@ var ts; getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; }, writeFile: function (name, text) { if (ts.fileExtensionIs(name, ".map")) { - ts.Debug.assert(sourceMapText === undefined, "Unexpected multiple source map outputs for the file '" + name + "'"); + ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); sourceMapText = text; } else { - ts.Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: '" + name + "'"); + ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); outputText = text; } }, @@ -70132,6 +70368,7 @@ var ts; this.NoSpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(25, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 8)); this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2)); this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2)); + this.SpaceBetweenOpenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19, 19), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2)); this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19, 20), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8)); this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8)); this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8)); @@ -70203,7 +70440,7 @@ var ts; this.SpaceAfterComma, this.NoSpaceAfterComma, this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword, this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl, - this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, + this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace, this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail, @@ -72050,6 +72287,12 @@ var ts; } return false; } + var ChangeKind; + (function (ChangeKind) { + ChangeKind[ChangeKind["Remove"] = 0] = "Remove"; + ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode"; + ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes"; + })(ChangeKind || (ChangeKind = {})); function getSeparatorCharacter(separator) { return ts.tokenToString(separator.kind); } @@ -72074,7 +72317,7 @@ var ts; } textChanges.getAdjustedStartPosition = getAdjustedStartPosition; function getAdjustedEndPosition(sourceFile, node, options) { - if (options.useNonAdjustedEndPosition) { + if (options.useNonAdjustedEndPosition || ts.isExpression(node)) { return node.getEnd(); } var end = node.getEnd(); @@ -72094,6 +72337,9 @@ var ts; } return s; } + function getNewlineKind(context) { + return context.newLineCharacter === "\n" ? 1 : 0; + } var ChangeTracker = (function () { function ChangeTracker(newLine, rulesProvider, validator) { this.newLine = newLine; @@ -72103,24 +72349,24 @@ var ts; this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine }); } ChangeTracker.fromCodeFixContext = function (context) { - return new ChangeTracker(context.newLineCharacter === "\n" ? 1 : 0, context.rulesProvider); + return new ChangeTracker(getNewlineKind(context), context.rulesProvider); + }; + ChangeTracker.prototype.deleteRange = function (sourceFile, range) { + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range }); + return this; }; ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, node, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); - return this; - }; - ChangeTracker.prototype.deleteRange = function (sourceFile, range) { - this.changes.push({ sourceFile: sourceFile, range: range }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) { @@ -72156,33 +72402,68 @@ var ts; }; ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, range: range, options: options, node: newNode }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode }); return this; }; ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); }; ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); + }; + ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, + sourceFile: sourceFile, + options: options, + node: newNode, + range: { pos: startPosition, end: endPosition } + }); + return this; + }; + ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithMultipleNodes, + sourceFile: sourceFile, + options: options, + nodes: newNodes, + range: { pos: startPosition, end: endPosition } + }); return this; }; + ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) { + return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options); + }; + ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); return this; }; ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: startPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options); }; ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) { if (options === void 0) { options = {}; } @@ -72192,6 +72473,7 @@ var ts; after.kind === 150) { if (sourceFile.text.charCodeAt(after.end - 1) !== 59) { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: {}, range: { pos: after.end, end: after.end }, @@ -72200,8 +72482,7 @@ var ts; } } var endPosition = getAdjustedEndPosition(sourceFile, after, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: endPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options); }; ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode) { var containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile); @@ -72229,10 +72510,10 @@ var ts; startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile); } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) }, node: newNode, - useIndentationFromFile: true, options: { prefix: prefix, suffix: "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile)) @@ -72259,6 +72540,7 @@ var ts; } if (multilineList) { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: ts.createToken(separator), @@ -72270,6 +72552,7 @@ var ts; insertPos--; } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: insertPos, end: insertPos }, node: newNode, @@ -72278,6 +72561,7 @@ var ts; } else { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: newNode, @@ -72317,30 +72601,43 @@ var ts; return ts.createTextSpanFromBounds(change.range.pos, change.range.end); }; ChangeTracker.prototype.computeNewText = function (change, sourceFile) { - if (!change.node) { + var _this = this; + if (change.kind === ChangeKind.Remove) { return ""; } var options = change.options || {}; - var nonFormattedText = getNonformattedText(change.node, sourceFile, this.newLine); + var text; + var pos = change.range.pos; + var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; + if (change.kind === ChangeKind.ReplaceWithMultipleNodes) { + var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); }); + text = parts.join(change.options.nodeSeparator); + } + else { + ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode"); + text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options); + } + text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, ""); + return (options.prefix || "") + text + (options.suffix || ""); + }; + ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) { + var nonformattedText = getNonformattedText(node, sourceFile, this.newLine); if (this.validator) { - this.validator(nonFormattedText); + this.validator(nonformattedText); } var formatOptions = this.rulesProvider.getFormatOptions(); - var pos = change.range.pos; var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; - var initialIndentation = change.options.indentation !== undefined - ? change.options.indentation - : change.useIndentationFromFile - ? ts.formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix === this.newLineCharacter)) + var initialIndentation = options.indentation !== undefined + ? options.indentation + : (options.useIndentationFromFile !== false) + ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) : 0; - var delta = change.options.delta !== undefined - ? change.options.delta - : ts.formatting.SmartIndenter.shouldIndentChildNode(change.node) - ? formatOptions.indentSize + var delta = options.delta !== undefined + ? options.delta + : ts.formatting.SmartIndenter.shouldIndentChildNode(node) + ? (formatOptions.indentSize || 0) : 0; - var text = applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, this.rulesProvider); - text = posStartsLine || change.options.indentation !== undefined ? text : text.replace(/^\s+/, ""); - return (options.prefix || "") + text + (options.suffix || ""); + return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); }; ChangeTracker.normalize = function (changes) { var normalized = ts.stableSort(changes, function (a, b) { return a.range.pos - b.range.pos; }); @@ -73319,7 +73616,7 @@ var ts; symbolName = name; } else if (ts.isJsxOpeningLikeElement(token.parent) && token.parent.tagName === token) { - symbol = checker.getAliasedSymbol(checker.resolveNameAtLocation(token, checker.getJsxNamespace(), 107455)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), token.parent.tagName, 107455)); symbolName = symbol.name; } else { @@ -73403,8 +73700,8 @@ var ts; var namespaceImportDeclaration; var namedImportDeclaration; var existingModuleSpecifier; - for (var _i = 0, declarations_14 = declarations; _i < declarations_14.length; _i++) { - var declaration = declarations_14[_i]; + for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) { + var declaration = declarations_13[_i]; if (declaration.kind === 238) { var namedBindings = declaration.importClause && declaration.importClause.namedBindings; if (namedBindings && namedBindings.kind === 240) { @@ -73478,14 +73775,53 @@ var ts; : isNamespaceImport ? ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(symbolName))) : ts.createImportClause(undefined, ts.createNamedImports([ts.createImportSpecifier(undefined, ts.createIdentifier(symbolName))])); - var importDecl = ts.createImportDeclaration(undefined, undefined, importClause, ts.createLiteral(moduleSpecifierWithoutQuotes)); + var moduleSpecifierLiteral = ts.createLiteral(moduleSpecifierWithoutQuotes); + moduleSpecifierLiteral.singleQuote = getSingleQuoteStyleFromExistingImports(); + var importDecl = ts.createImportDeclaration(undefined, undefined, importClause, moduleSpecifierLiteral); if (!lastImportDeclaration) { - changeTracker.insertNodeAt(sourceFile, sourceFile.getStart(), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); + changeTracker.insertNodeAt(sourceFile, getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); } else { changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: context.newLineCharacter }); } return createCodeAction(ts.Diagnostics.Import_0_from_1, [symbolName, "\"" + moduleSpecifierWithoutQuotes + "\""], changeTracker.getChanges(), "NewImport", moduleSpecifierWithoutQuotes); + function getSourceFileImportLocation(node) { + var text = node.text; + var ranges = ts.getLeadingCommentRanges(text, 0); + if (!ranges) + return 0; + var position = 0; + if (ranges.length && ranges[0].kind === 3 && ts.isPinnedComment(text, ranges[0])) { + position = ranges[0].end + 1; + ranges = ranges.slice(1); + } + for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) { + var range = ranges_1[_i]; + if (range.kind === 2 && ts.isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { + position = range.end + 1; + continue; + } + break; + } + return position; + } + function getSingleQuoteStyleFromExistingImports() { + var firstModuleSpecifier = ts.forEach(sourceFile.statements, function (node) { + if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) { + if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { + return node.moduleSpecifier; + } + } + else if (ts.isImportEqualsDeclaration(node)) { + if (ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) { + return node.moduleReference.expression; + } + } + }); + if (firstModuleSpecifier) { + return sourceFile.text.charCodeAt(firstModuleSpecifier.getStart()) === 39; + } + } function getModuleSpecifierForNewImport() { var fileName = sourceFile.fileName; var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName; @@ -73615,7 +73951,8 @@ var ts; (function (States) { States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; States[States["NodeModules"] = 1] = "NodeModules"; - States[States["PackageContent"] = 2] = "PackageContent"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; })(States || (States = {})); var partStart = 0; var partEnd = 0; @@ -73632,15 +73969,21 @@ var ts; } break; case 1: - packageRootIndex = partEnd; - state = 2; - break; case 2: + if (state === 1 && fullPath.charAt(partStart + 1) === "@") { + state = 2; + } + else { + packageRootIndex = partEnd; + state = 3; + } + break; + case 3: if (fullPath.indexOf("/node_modules/", partStart) === partStart) { state = 1; } else { - state = 2; + state = 3; } break; } @@ -73930,206 +74273,1032 @@ var ts; (function (ts) { var refactor; (function (refactor) { - var actionName = "convert"; - var convertFunctionToES6Class = { - name: "Convert to ES2015 class", - description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, - getEditsForAction: getEditsForAction, - getAvailableActions: getAvailableActions - }; - refactor.registerRefactor(convertFunctionToES6Class); - function getAvailableActions(context) { - if (!ts.isInJavaScriptFile(context.file)) { - return undefined; - } - var start = context.startPosition; - var node = ts.getTokenAtPosition(context.file, start, false); - var checker = context.program.getTypeChecker(); - var symbol = checker.getSymbolAtLocation(node); - if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { - symbol = symbol.valueDeclaration.initializer.symbol; + var convertFunctionToES6Class; + (function (convertFunctionToES6Class_1) { + var actionName = "convert"; + var convertFunctionToES6Class = { + name: "Convert to ES2015 class", + description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, + getEditsForAction: getEditsForAction, + getAvailableActions: getAvailableActions + }; + refactor.registerRefactor(convertFunctionToES6Class); + function getAvailableActions(context) { + if (!ts.isInJavaScriptFile(context.file)) { + return undefined; + } + var start = context.startPosition; + var node = ts.getTokenAtPosition(context.file, start, false); + var checker = context.program.getTypeChecker(); + var symbol = checker.getSymbolAtLocation(node); + if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = symbol.valueDeclaration.initializer.symbol; + } + if (symbol && (symbol.flags & 16) && symbol.members && (symbol.members.size > 0)) { + return [ + { + name: convertFunctionToES6Class.name, + description: convertFunctionToES6Class.description, + actions: [ + { + description: convertFunctionToES6Class.description, + name: actionName + } + ] + } + ]; + } } - if (symbol && (symbol.flags & 16) && symbol.members && (symbol.members.size > 0)) { - return [ - { - name: convertFunctionToES6Class.name, - description: convertFunctionToES6Class.description, - actions: [ - { - description: convertFunctionToES6Class.description, - name: actionName + function getEditsForAction(context, action) { + if (actionName !== action) { + return undefined; + } + var start = context.startPosition; + var sourceFile = context.file; + var checker = context.program.getTypeChecker(); + var token = ts.getTokenAtPosition(sourceFile, start, false); + var ctorSymbol = checker.getSymbolAtLocation(token); + var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; + var deletedNodes = []; + var deletes = []; + if (!(ctorSymbol.flags & (16 | 3))) { + return undefined; + } + var ctorDeclaration = ctorSymbol.valueDeclaration; + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + var precedingNode; + var newClassDeclaration; + switch (ctorDeclaration.kind) { + case 228: + precedingNode = ctorDeclaration; + deleteNode(ctorDeclaration); + newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); + break; + case 226: + precedingNode = ctorDeclaration.parent.parent; + if (ctorDeclaration.parent.declarations.length === 1) { + deleteNode(precedingNode); + } + else { + deleteNode(ctorDeclaration, true); + } + newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); + break; + } + if (!newClassDeclaration) { + return undefined; + } + changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); + for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { + var deleteCallback = deletes_1[_i]; + deleteCallback(); + } + return { + edits: changeTracker.getChanges() + }; + function deleteNode(node, inList) { + if (inList === void 0) { inList = false; } + if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { + return; + } + deletedNodes.push(node); + if (inList) { + deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + } + else { + deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + } + } + function createClassElementsFromSymbol(symbol) { + var memberElements = []; + if (symbol.members) { + symbol.members.forEach(function (member) { + var memberElement = createClassElement(member, undefined); + if (memberElement) { + memberElements.push(memberElement); } - ] + }); } - ]; - } - } - function getEditsForAction(context, action) { - if (actionName !== action) { - return undefined; + if (symbol.exports) { + symbol.exports.forEach(function (member) { + var memberElement = createClassElement(member, [ts.createToken(115)]); + if (memberElement) { + memberElements.push(memberElement); + } + }); + } + return memberElements; + function shouldConvertDeclaration(_target, source) { + return ts.isFunctionLike(source); + } + function createClassElement(symbol, modifiers) { + if (!(symbol.flags & 4)) { + return; + } + var memberDeclaration = symbol.valueDeclaration; + var assignmentBinaryExpression = memberDeclaration.parent; + if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { + return; + } + var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 + ? assignmentBinaryExpression.parent : assignmentBinaryExpression; + deleteNode(nodeToDelete); + if (!assignmentBinaryExpression.right) { + return ts.createProperty([], modifiers, symbol.name, undefined, undefined, undefined); + } + switch (assignmentBinaryExpression.right.kind) { + case 186: { + var functionExpression = assignmentBinaryExpression.right; + var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, functionExpression.parameters, undefined, functionExpression.body); + copyComments(assignmentBinaryExpression, method); + return method; + } + case 187: { + var arrowFunction = assignmentBinaryExpression.right; + var arrowFunctionBody = arrowFunction.body; + var bodyBlock = void 0; + if (arrowFunctionBody.kind === 207) { + bodyBlock = arrowFunctionBody; + } + else { + var expression = arrowFunctionBody; + bodyBlock = ts.createBlock([ts.createReturn(expression)]); + } + var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, arrowFunction.parameters, undefined, bodyBlock); + copyComments(assignmentBinaryExpression, method); + return method; + } + default: { + if (ts.isSourceFileJavaScript(sourceFile)) { + return; + } + var prop = ts.createProperty(undefined, modifiers, memberDeclaration.name, undefined, undefined, assignmentBinaryExpression.right); + copyComments(assignmentBinaryExpression.parent, prop); + return prop; + } + } + } + } + function copyComments(sourceNode, targetNode) { + ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { + if (kind === 3) { + pos += 2; + end -= 2; + } + else { + pos += 2; + } + ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); + }); + } + function createClassFromVariableDeclaration(node) { + var initializer = node.initializer; + if (!initializer || initializer.kind !== 186) { + return undefined; + } + if (node.name.kind !== 71) { + return undefined; + } + var memberElements = createClassElementsFromSymbol(initializer.symbol); + if (initializer.body) { + memberElements.unshift(ts.createConstructor(undefined, undefined, initializer.parameters, initializer.body)); + } + var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); + return cls; + } + function createClassFromFunctionDeclaration(node) { + var memberElements = createClassElementsFromSymbol(ctorSymbol); + if (node.body) { + memberElements.unshift(ts.createConstructor(undefined, undefined, node.parameters, node.body)); + } + var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); + return cls; + } } - var start = context.startPosition; - var sourceFile = context.file; - var checker = context.program.getTypeChecker(); - var token = ts.getTokenAtPosition(sourceFile, start, false); - var ctorSymbol = checker.getSymbolAtLocation(token); - var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; - var deletedNodes = []; - var deletes = []; - if (!(ctorSymbol.flags & (16 | 3))) { - return undefined; + })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {})); + })(refactor = ts.refactor || (ts.refactor = {})); +})(ts || (ts = {})); +var ts; +(function (ts) { + var refactor; + (function (refactor) { + var extractMethod; + (function (extractMethod_1) { + var extractMethod = { + name: "Extract Method", + description: ts.Diagnostics.Extract_function.message, + getAvailableActions: getAvailableActions, + getEditsForAction: getEditsForAction, + }; + refactor.registerRefactor(extractMethod); + function getAvailableActions(context) { + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: context.endPosition - context.startPosition }); + var targetRange = rangeToExtract.targetRange; + if (targetRange === undefined) { + return undefined; + } + var extractions = getPossibleExtractions(targetRange, context); + if (extractions === undefined) { + return undefined; + } + var actions = []; + var usedNames = ts.createMap(); + var i = 0; + for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { + var extr = extractions_1[_i]; + if (extr.errors && extr.errors.length) { + continue; + } + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + if (!usedNames.has(description)) { + usedNames.set(description, true); + actions.push({ + description: description, + name: "scope_" + i + }); + } + i++; + } + if (actions.length === 0) { + return undefined; + } + return [{ + name: extractMethod.name, + description: extractMethod.description, + inlineable: true, + actions: actions + }]; } - var ctorDeclaration = ctorSymbol.valueDeclaration; - var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); - var precedingNode; - var newClassDeclaration; - switch (ctorDeclaration.kind) { - case 228: - precedingNode = ctorDeclaration; - deleteNode(ctorDeclaration); - newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); - break; - case 226: - precedingNode = ctorDeclaration.parent.parent; - if (ctorDeclaration.parent.declarations.length === 1) { - deleteNode(precedingNode); + function getEditsForAction(context, actionName) { + var length = context.endPosition === undefined ? 0 : context.endPosition - context.startPosition; + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: length }); + var targetRange = rangeToExtract.targetRange; + var parsedIndexMatch = /^scope_(\d+)$/.exec(actionName); + ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); + var index = +parsedIndexMatch[1]; + ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); + var extractions = getPossibleExtractions(targetRange, context, index); + ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); + return ({ edits: extractions[0].changes }); + } + var Messages; + (function (Messages) { + function createMessage(message) { + return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message }; + } + Messages.CannotExtractFunction = createMessage("Cannot extract function."); + Messages.StatementOrExpressionExpected = createMessage("Statement or expression expected."); + Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements."); + Messages.CannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement."); + Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); + Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); + Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); + Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); + Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); + Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); + Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); + Messages.CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); + })(Messages || (Messages = {})); + var RangeFacts; + (function (RangeFacts) { + RangeFacts[RangeFacts["None"] = 0] = "None"; + RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn"; + RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator"; + RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; + RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; + RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; + })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + function getRangeToExtract(sourceFile, span) { + var length = span.length || 0; + var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, false), sourceFile, span); + var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span); + var declarations = []; + var rangeFacts = RangeFacts.None; + if (!start || !end) { + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractFunction)] }; + } + if (start.parent !== end.parent) { + var startParent = ts.skipParentheses(start.parent); + var endParent = ts.skipParentheses(end.parent); + if (ts.isBinaryExpression(startParent) && ts.isBinaryExpression(endParent) && ts.isNodeDescendantOf(startParent, endParent)) { + start = end = endParent; } else { - deleteNode(ctorDeclaration, true); + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); } - newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); - break; + } + if (start !== end) { + if (!isBlockLike(start.parent)) { + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); + } + var statements = []; + for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) { + var statement = _a[_i]; + if (statement === start || statements.length) { + var errors = checkNode(statement); + if (errors) { + return { errors: errors }; + } + statements.push(statement); + } + if (statement === end) { + break; + } + } + return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } }; + } + else { + var errors = checkRootNode(start) || checkNode(start); + if (errors) { + return { errors: errors }; + } + var range = ts.isStatement(start) + ? [start] + : start.parent && start.parent.kind === 210 + ? [start.parent] + : start; + return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + } + function createErrorResult(sourceFile, start, length, message) { + return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; + } + function checkRootNode(node) { + if (ts.isIdentifier(node)) { + return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; + } + return undefined; + } + function checkForStaticContext(nodeToCheck, containingClass) { + var current = nodeToCheck; + while (current !== containingClass) { + if (current.kind === 149) { + if (ts.hasModifier(current, 32)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 146) { + var ctorOrMethod = ts.getContainingFunction(current); + if (ctorOrMethod.kind === 152) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 151) { + if (ts.hasModifier(current, 32)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + } + current = current.parent; + } + } + function checkNode(nodeToCheck) { + var PermittedJumps; + (function (PermittedJumps) { + PermittedJumps[PermittedJumps["None"] = 0] = "None"; + PermittedJumps[PermittedJumps["Break"] = 1] = "Break"; + PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue"; + PermittedJumps[PermittedJumps["Return"] = 4] = "Return"; + })(PermittedJumps || (PermittedJumps = {})); + if (!ts.isStatement(nodeToCheck) && !(ts.isExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)]; + } + if (ts.isInAmbientContext(nodeToCheck)) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)]; + } + var containingClass = ts.getContainingClass(nodeToCheck); + if (containingClass) { + checkForStaticContext(nodeToCheck, containingClass); + } + var errors; + var permittedJumps = 4; + var seenLabels; + visit(nodeToCheck); + return errors; + function visit(node) { + if (errors) { + return true; + } + if (ts.isDeclaration(node)) { + var declaringNode = (node.kind === 226) ? node.parent.parent : node; + if (ts.hasModifier(declaringNode, 1)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + return true; + } + declarations.push(node.symbol); + } + switch (node.kind) { + case 238: + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + case 97: + if (node.parent.kind === 181) { + var containingClass_1 = ts.getContainingClass(node); + if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + } + } + else { + rangeFacts |= RangeFacts.UsesThis; + } + break; + } + if (!node || ts.isFunctionLike(node) || ts.isClassLike(node)) { + switch (node.kind) { + case 228: + case 229: + if (node.parent.kind === 265 && node.parent.externalModuleIndicator === undefined) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope)); + } + break; + } + return false; + } + var savedPermittedJumps = permittedJumps; + if (node.parent) { + switch (node.parent.kind) { + case 211: + if (node.parent.thenStatement === node || node.parent.elseStatement === node) { + permittedJumps = 0; + } + break; + case 224: + if (node.parent.tryBlock === node) { + permittedJumps = 0; + } + else if (node.parent.finallyBlock === node) { + permittedJumps = 4; + } + break; + case 260: + if (node.parent.block === node) { + permittedJumps = 0; + } + break; + case 257: + if (node.expression !== node) { + permittedJumps |= 1; + } + break; + default: + if (ts.isIterationStatement(node.parent, false)) { + if (node.parent.statement === node) { + permittedJumps |= 1 | 2; + } + } + break; + } + } + switch (node.kind) { + case 169: + case 99: + rangeFacts |= RangeFacts.UsesThis; + break; + case 222: + { + var label = node.label; + (seenLabels || (seenLabels = [])).push(label.escapedText); + ts.forEachChild(node, visit); + seenLabels.pop(); + break; + } + case 218: + case 217: + { + var label = node.label; + if (label) { + if (!ts.contains(seenLabels, label.escapedText)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); + } + } + else { + if (!(permittedJumps & (218 ? 1 : 2))) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements)); + } + } + break; + } + case 191: + rangeFacts |= RangeFacts.IsAsyncFunction; + break; + case 197: + rangeFacts |= RangeFacts.IsGenerator; + break; + case 219: + if (permittedJumps & 4) { + rangeFacts |= RangeFacts.HasReturn; + } + else { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement)); + } + break; + default: + ts.forEachChild(node, visit); + break; + } + permittedJumps = savedPermittedJumps; + } + } } - if (!newClassDeclaration) { - return undefined; + extractMethod_1.getRangeToExtract = getRangeToExtract; + function isValidExtractionTarget(node) { + return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); } - changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); - for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { - var deleteCallback = deletes_1[_i]; - deleteCallback(); + function collectEnclosingScopes(range) { + var current = isReadonlyArray(range.range) ? ts.firstOrUndefined(range.range) : range.range; + if (range.facts & RangeFacts.UsesThis) { + var containingClass = ts.getContainingClass(current); + if (containingClass) { + return [containingClass]; + } + } + var start = current; + var scopes = undefined; + while (current) { + if (current !== start && isValidExtractionTarget(current)) { + (scopes = scopes || []).push(current); + } + if (current && current.parent && current.parent.kind === 146) { + current = ts.findAncestor(current, function (parent) { return ts.isFunctionLike(parent); }).parent; + } + else { + current = current.parent; + } + } + return scopes; } - return { - edits: changeTracker.getChanges() - }; - function deleteNode(node, inList) { - if (inList === void 0) { inList = false; } - if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { - return; + extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; + function getPossibleExtractions(targetRange, context, requestedChangesIndex) { + if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + var sourceFile = context.file; + if (targetRange === undefined) { + return undefined; + } + var scopes = collectEnclosingScopes(targetRange); + if (scopes === undefined) { + return undefined; + } + var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); + var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; + context.cancellationToken.throwIfCancellationRequested(); + if (requestedChangesIndex !== undefined) { + if (errorsPerScope[requestedChangesIndex].length) { + return undefined; + } + return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; + } + else { + return scopes.map(function (scope, i) { + var errors = errorsPerScope[i]; + if (errors.length) { + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + errors: errors + }; + } + return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; + }); + } + } + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getDescriptionForScope(scope) { + if (ts.isFunctionLike(scope)) { + switch (scope.kind) { + case 152: + return "constructor"; + case 186: + return scope.name + ? "function expression " + scope.name.getText() + : "anonymous function expression"; + case 228: + return "function " + scope.name.getText(); + case 187: + return "arrow function"; + case 151: + return "method " + scope.name.getText(); + case 153: + return "get " + scope.name.getText(); + case 154: + return "set " + scope.name.getText(); + } + } + else if (isModuleBlock(scope)) { + return "namespace " + scope.parent.name.getText(); + } + else if (ts.isClassLike(scope)) { + return scope.kind === 229 + ? "class " + scope.name.text + : scope.name.text + ? "class expression " + scope.name.text + : "anonymous class expression"; } - deletedNodes.push(node); - if (inList) { - deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + else if (ts.isSourceFile(scope)) { + return "file '" + scope.fileName + "'"; } else { - deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + return "unknown"; } } - function createClassElementsFromSymbol(symbol) { - var memberElements = []; - if (symbol.members) { - symbol.members.forEach(function (member) { - var memberElement = createClassElement(member, undefined); - if (memberElement) { - memberElements.push(memberElement); + function getUniqueName(isNameOkay) { + var functionNameText = "newFunction"; + if (isNameOkay(functionNameText)) { + return functionNameText; + } + var i = 1; + while (!isNameOkay(functionNameText = "newFunction_" + i)) { + i++; + } + return functionNameText; + } + function extractFunctionInScope(node, scope, _a, range, context) { + var usagesInScope = _a.usages, substitutions = _a.substitutions; + var checker = context.program.getTypeChecker(); + var file = scope.getSourceFile(); + var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var isJS = ts.isInJavaScriptFile(scope); + var functionName = ts.createIdentifier(functionNameText); + var functionReference = ts.createIdentifier(functionNameText); + var returnType = undefined; + var parameters = []; + var callArguments = []; + var writes; + usagesInScope.forEach(function (usage, name) { + var typeNode = undefined; + if (!isJS) { + var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); + type = checker.getBaseTypeOfLiteralType(type); + typeNode = checker.typeToTypeNode(type, node, ts.NodeBuilderFlags.NoTruncation); + } + var paramDecl = ts.createParameter(undefined, undefined, undefined, name, undefined, typeNode); + parameters.push(paramDecl); + if (usage.usage === 2) { + (writes || (writes = [])).push(usage); + } + callArguments.push(ts.createIdentifier(name)); + }); + if (ts.isExpression(node) && !isJS) { + var contextualType = checker.getContextualType(node); + returnType = checker.typeToTypeNode(contextualType); + } + var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var newFunction; + if (ts.isClassLike(scope)) { + var modifiers = isJS ? [] : [ts.createToken(112)]; + if (range.facts & RangeFacts.InStaticRegion) { + modifiers.push(ts.createToken(115)); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + modifiers.push(ts.createToken(120)); + } + newFunction = ts.createMethod(undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, [], parameters, returnType, body); + } + else { + newFunction = ts.createFunctionDeclaration(undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, [], parameters, returnType, body); + } + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); + var newNodes = []; + var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, undefined, callArguments); + if (range.facts & RangeFacts.IsGenerator) { + call = ts.createYield(ts.createToken(39), call); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + call = ts.createAwait(call); + } + if (writes) { + if (returnValueProperty) { + newNodes.push(ts.createVariableStatement(undefined, [ts.createVariableDeclaration(returnValueProperty, ts.createKeywordTypeNode(119))])); + } + var assignments = getPropertyAssignmentsForWrites(writes); + if (returnValueProperty) { + assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty)); + } + if (assignments.length === 1) { + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); + } + else { + newNodes.push(ts.createStatement(ts.createBinary(assignments[0].name, 58, call))); + } + } + else { + newNodes.push(ts.createStatement(ts.createBinary(ts.createObjectLiteral(assignments), 58, call))); + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); } + } + } + else { + if (range.facts & RangeFacts.HasReturn) { + newNodes.push(ts.createReturn(call)); + } + else if (isReadonlyArray(range.range)) { + newNodes.push(ts.createStatement(call)); + } + else { + newNodes.push(call); + } + } + if (isReadonlyArray(range.range)) { + changeTracker.replaceNodesWithNodes(context.file, range.range, newNodes, { + nodeSeparator: context.newLineCharacter, + suffix: context.newLineCharacter }); } - if (symbol.exports) { - symbol.exports.forEach(function (member) { - var memberElement = createClassElement(member, [ts.createToken(115)]); - if (memberElement) { - memberElements.push(memberElement); + else { + changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); + } + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + changes: changeTracker.getChanges() + }; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); + } + function generateReturnValueProperty() { + return "__return"; + } + function transformFunctionBody(body) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + return { body: ts.createBlock(body.statements, true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); + } + } + return { body: ts.createBlock(rewrittenStatements, true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = generateReturnValueProperty(); + } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); + } + else { + return ts.createReturn(ts.createObjectLiteral(assignments)); + } + } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } + } + } + } + extractMethod_1.extractFunctionInScope = extractFunctionInScope; + function isModuleBlock(n) { + return n.kind === 234; + } + function isReadonlyArray(v) { + return ts.isArray(v); + } + function getEnclosingTextRange(targetRange, sourceFile) { + return isReadonlyArray(targetRange.range) + ? { pos: targetRange.range[0].getStart(sourceFile), end: targetRange.range[targetRange.range.length - 1].getEnd() } + : targetRange.range; + } + var Usage; + (function (Usage) { + Usage[Usage["Read"] = 1] = "Read"; + Usage[Usage["Write"] = 2] = "Write"; + })(Usage || (Usage = {})); + function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker) { + var usagesPerScope = []; + var substitutionsPerScope = []; + var errorsPerScope = []; + var visibleDeclarationsInExtractedRange = []; + for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) { + var _ = scopes_1[_i]; + usagesPerScope.push({ usages: ts.createMap(), substitutions: ts.createMap() }); + substitutionsPerScope.push(ts.createMap()); + errorsPerScope.push([]); + } + var seenUsages = ts.createMap(); + var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range; + var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] : ts.getEnclosingBlockScopeContainer(scopes[0]); + collectUsages(target); + var _loop_8 = function (i) { + var hasWrite = false; + var readonlyClassPropertyWrite = undefined; + usagesPerScope[i].usages.forEach(function (value) { + if (value.usage === 2) { + hasWrite = true; + if (value.symbol.flags & 106500 && + value.symbol.valueDeclaration && + ts.hasModifier(value.symbol.valueDeclaration, 64)) { + readonlyClassPropertyWrite = value.symbol.valueDeclaration; + } } }); + if (hasWrite && !isReadonlyArray(targetRange.range) && ts.isExpression(targetRange.range)) { + errorsPerScope[i].push(ts.createDiagnosticForNode(targetRange.range, Messages.CannotCombineWritesAndReturns)); + } + else if (readonlyClassPropertyWrite && i > 0) { + errorsPerScope[i].push(ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotCombineWritesAndReturns)); + } + }; + for (var i = 0; i < scopes.length; i++) { + _loop_8(i); } - return memberElements; - function shouldConvertDeclaration(_target, source) { - return ts.isFunctionLike(source); + if (visibleDeclarationsInExtractedRange.length) { + ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); } - function createClassElement(symbol, modifiers) { - if (!(symbol.flags & 4)) { - return; + return { target: target, usagesPerScope: usagesPerScope, errorsPerScope: errorsPerScope }; + function collectUsages(node, valueUsage) { + if (valueUsage === void 0) { valueUsage = 1; } + if (ts.isDeclaration(node) && node.symbol) { + visibleDeclarationsInExtractedRange.push(node.symbol); } - var memberDeclaration = symbol.valueDeclaration; - var assignmentBinaryExpression = memberDeclaration.parent; - if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { - return; + if (ts.isAssignmentExpression(node)) { + collectUsages(node.left, 2); + collectUsages(node.right); + } + else if (ts.isUnaryExpressionWithWrite(node)) { + collectUsages(node.operand, 2); + } + else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) { + ts.forEachChild(node, collectUsages); + } + else if (ts.isIdentifier(node)) { + if (!node.parent) { + return; + } + if (ts.isQualifiedName(node.parent) && node !== node.parent.left) { + return; + } + if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { + return; + } + recordUsage(node, valueUsage, ts.isPartOfTypeNode(node)); + } + else { + ts.forEachChild(node, collectUsages); } - var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 - ? assignmentBinaryExpression.parent : assignmentBinaryExpression; - deleteNode(nodeToDelete); - if (!assignmentBinaryExpression.right) { - return ts.createProperty([], modifiers, symbol.name, undefined, undefined, undefined); - } - switch (assignmentBinaryExpression.right.kind) { - case 186: { - var functionExpression = assignmentBinaryExpression.right; - var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, functionExpression.parameters, undefined, functionExpression.body); - copyComments(assignmentBinaryExpression, method); - return method; - } - case 187: { - var arrowFunction = assignmentBinaryExpression.right; - var arrowFunctionBody = arrowFunction.body; - var bodyBlock = void 0; - if (arrowFunctionBody.kind === 207) { - bodyBlock = arrowFunctionBody; + } + function recordUsage(n, usage, isTypeNode) { + var symbolId = recordUsagebySymbol(n, usage, isTypeNode); + if (symbolId) { + for (var i = 0; i < scopes.length; i++) { + var substitition = substitutionsPerScope[i].get(symbolId); + if (substitition) { + usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitition); } - else { - var expression = arrowFunctionBody; - bodyBlock = ts.createBlock([ts.createReturn(expression)]); + } + } + } + function recordUsagebySymbol(identifier, usage, isTypeName) { + var symbol = checker.getSymbolAtLocation(identifier); + if (!symbol) { + return undefined; + } + var symbolId = ts.getSymbolId(symbol).toString(); + var lastUsage = seenUsages.get(symbolId); + if (lastUsage && lastUsage >= usage) { + return symbolId; + } + seenUsages.set(symbolId, usage); + if (lastUsage) { + for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) { + var perScope = usagesPerScope_1[_i]; + var prevEntry = perScope.usages.get(identifier.text); + if (prevEntry) { + perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } - var method = ts.createMethod(undefined, modifiers, undefined, memberDeclaration.name, undefined, undefined, arrowFunction.parameters, undefined, bodyBlock); - copyComments(assignmentBinaryExpression, method); - return method; } - default: { - if (ts.isSourceFileJavaScript(sourceFile)) { - return; + return symbolId; + } + var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; }); + if (!declInFile) { + return undefined; + } + if (ts.rangeContainsRange(enclosingTextRange, declInFile)) { + return undefined; + } + if (targetRange.facts & RangeFacts.IsGenerator && usage === 2) { + for (var _a = 0, errorsPerScope_1 = errorsPerScope; _a < errorsPerScope_1.length; _a++) { + var errors = errorsPerScope_1[_a]; + errors.push(ts.createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators)); + } + } + for (var i = 0; i < scopes.length; i++) { + var scope = scopes[i]; + var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + if (resolvedSymbol === symbol) { + continue; + } + if (!substitutionsPerScope[i].has(symbolId)) { + var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName); + if (substitution) { + substitutionsPerScope[i].set(symbolId, substitution); + } + else if (isTypeName) { + errorsPerScope[i].push(ts.createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope)); + } + else { + usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } - var prop = ts.createProperty(undefined, modifiers, memberDeclaration.name, undefined, undefined, assignmentBinaryExpression.right); - copyComments(assignmentBinaryExpression.parent, prop); - return prop; } } + return symbolId; } - } - function copyComments(sourceNode, targetNode) { - ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { - if (kind === 3) { - pos += 2; - end -= 2; + function checkForUsedDeclarations(node) { + if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) { + return; + } + var sym = checker.getSymbolAtLocation(node); + if (sym && visibleDeclarationsInExtractedRange.some(function (d) { return d === sym; })) { + for (var _i = 0, errorsPerScope_2 = errorsPerScope; _i < errorsPerScope_2.length; _i++) { + var scope = errorsPerScope_2[_i]; + scope.push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + } + return true; } else { - pos += 2; + ts.forEachChild(node, checkForUsedDeclarations); } - ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); - }); + } + function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) { + if (!symbol) { + return undefined; + } + if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) { + return ts.createIdentifier(symbol.name); + } + var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); + if (prefix === undefined) { + return undefined; + } + return isTypeNode ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name)) : ts.createPropertyAccess(prefix, symbol.name); + } } - function createClassFromVariableDeclaration(node) { - var initializer = node.initializer; - if (!initializer || initializer.kind !== 186) { + function getParentNodeInSpan(node, file, span) { + if (!node) return undefined; + while (node.parent) { + if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { + return node; + } + node = node.parent; } - if (node.name.kind !== 71) { - return undefined; + } + function spanContainsNode(span, node, file) { + return ts.textSpanContainsPosition(span, node.getStart(file)) && + node.getEnd() <= ts.textSpanEnd(span); + } + function isExtractableExpression(node) { + switch (node.parent.kind) { + case 264: + return false; } - var memberElements = createClassElementsFromSymbol(initializer.symbol); - if (initializer.body) { - memberElements.unshift(ts.createConstructor(undefined, undefined, initializer.parameters, initializer.body)); + switch (node.kind) { + case 9: + return node.parent.kind !== 238 && + node.parent.kind !== 242; + case 198: + case 174: + case 176: + return false; + case 71: + return node.parent.kind !== 176 && + node.parent.kind !== 242 && + node.parent.kind !== 246; } - var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); - return cls; + return true; } - function createClassFromFunctionDeclaration(node) { - var memberElements = createClassElementsFromSymbol(ctorSymbol); - if (node.body) { - memberElements.unshift(ts.createConstructor(undefined, undefined, node.parameters, node.body)); + function isBlockLike(node) { + switch (node.kind) { + case 207: + case 265: + case 234: + case 257: + return true; + default: + return false; } - var cls = ts.createClassDeclaration(undefined, undefined, node.name, undefined, undefined, memberElements); - return cls; } - } + })(extractMethod = refactor.extractMethod || (refactor.extractMethod = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); var ts; @@ -74986,8 +76155,8 @@ var ts; if (program) { var oldSourceFiles = program.getSourceFiles(); var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings); - for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { - var oldSourceFile = oldSourceFiles_1[_i]; + for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) { + var oldSourceFile = oldSourceFiles_2[_i]; if (!newProgram.getSourceFile(oldSourceFile.fileName) || shouldCreateNewSourceFiles) { documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey); } @@ -75009,7 +76178,7 @@ var ts; if (!shouldCreateNewSourceFiles) { var oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) { - ts.Debug.assert(hostFileInformation.scriptKind === oldSourceFile.scriptKind, "Registered script kind (" + oldSourceFile.scriptKind + ") should match new script kind (" + hostFileInformation.scriptKind + ") for file: " + path); + ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path); return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind); } } @@ -75615,12 +76784,16 @@ var ts; function getPropertySymbolsFromContextualType(typeChecker, node) { var objectLiteral = node.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(node.name)); - if (name && contextualType) { + return getPropertySymbolsFromType(contextualType, node.name); + } + ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + function getPropertySymbolsFromType(type, propName) { + var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName)); + if (name && type) { var result_10 = []; - var symbol = contextualType.getProperty(name); - if (contextualType.flags & 65536) { - ts.forEach(contextualType.types, function (t) { + var symbol = type.getProperty(name); + if (type.flags & 65536) { + ts.forEach(type.types, function (t) { var symbol = t.getProperty(name); if (symbol) { result_10.push(symbol); @@ -75635,7 +76808,7 @@ var ts; } return undefined; } - ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + ts.getPropertySymbolsFromType = getPropertySymbolsFromType; function isArgumentOfElementAccessExpression(node) { return node && node.parent && @@ -75813,42 +76986,6 @@ var ts; return []; } server.createSortedArray = createSortedArray; - function toSortedArray(arr, comparer) { - arr.sort(comparer); - return arr; - } - server.toSortedArray = toSortedArray; - function enumerateInsertsAndDeletes(newItems, oldItems, inserted, deleted, compare) { - compare = compare || ts.compareValues; - var newIndex = 0; - var oldIndex = 0; - var newLen = newItems.length; - var oldLen = oldItems.length; - while (newIndex < newLen && oldIndex < oldLen) { - var newItem = newItems[newIndex]; - var oldItem = oldItems[oldIndex]; - var compareResult = compare(newItem, oldItem); - if (compareResult === -1) { - inserted(newItem); - newIndex++; - } - else if (compareResult === 1) { - deleted(oldItem); - oldIndex++; - } - else { - newIndex++; - oldIndex++; - } - } - while (newIndex < newLen) { - inserted(newItems[newIndex++]); - } - while (oldIndex < oldLen) { - deleted(oldItems[oldIndex++]); - } - } - server.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes; var ThrottledOperations = (function () { function ThrottledOperations(host) { this.host = host; @@ -75893,6 +77030,11 @@ var ts; return GcTimer; }()); server.GcTimer = GcTimer; + })(server = ts.server || (ts.server = {})); +})(ts || (ts = {})); +(function (ts) { + var server; + (function (server) { function insertSorted(array, insert, compare) { if (array.length === 0) { array.push(insert); @@ -75918,6 +77060,51 @@ var ts; } } server.removeSorted = removeSorted; + function toSortedArray(arr, comparer) { + arr.sort(comparer); + return arr; + } + server.toSortedArray = toSortedArray; + function toDeduplicatedSortedArray(arr) { + arr.sort(); + ts.filterMutate(arr, isNonDuplicateInSortedArray); + return arr; + } + server.toDeduplicatedSortedArray = toDeduplicatedSortedArray; + function isNonDuplicateInSortedArray(value, index, array) { + return index === 0 || value !== array[index - 1]; + } + function enumerateInsertsAndDeletes(newItems, oldItems, inserted, deleted, compare) { + compare = compare || ts.compareValues; + var newIndex = 0; + var oldIndex = 0; + var newLen = newItems.length; + var oldLen = oldItems.length; + while (newIndex < newLen && oldIndex < oldLen) { + var newItem = newItems[newIndex]; + var oldItem = oldItems[oldIndex]; + var compareResult = compare(newItem, oldItem); + if (compareResult === -1) { + inserted(newItem); + newIndex++; + } + else if (compareResult === 1) { + deleted(oldItem); + oldIndex++; + } + else { + newIndex++; + oldIndex++; + } + } + while (newIndex < newLen) { + inserted(newItems[newIndex++]); + } + while (oldIndex < oldLen) { + deleted(oldItems[oldIndex++]); + } + } + server.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); var ts; @@ -76130,20 +77317,16 @@ var ts; var MultistepOperation = (function () { function MultistepOperation(operationHost) { this.operationHost = operationHost; - this.completed = true; } MultistepOperation.prototype.startNew = function (action) { this.complete(); this.requestId = this.operationHost.getCurrentRequestId(); - this.completed = false; this.executeAction(action); }; MultistepOperation.prototype.complete = function () { - if (!this.completed) { - if (this.requestId) { - this.operationHost.sendRequestCompletedEvent(this.requestId); - } - this.completed = true; + if (this.requestId !== undefined) { + this.operationHost.sendRequestCompletedEvent(this.requestId); + this.requestId = undefined; } this.setTimerHandle(undefined); this.setImmediateId(undefined); @@ -76479,6 +77662,7 @@ var ts; logger: this.logger, cancellationToken: this.cancellationToken, useSingleInferredProject: opts.useSingleInferredProject, + useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot, typingsInstaller: this.typingsInstaller, throttleWaitMilliseconds: throttleWaitMilliseconds, eventHandler: this.eventHandler, @@ -76505,7 +77689,7 @@ var ts; case server.ContextEvent: var _a = event.data, project_1 = _a.project, fileName_2 = _a.fileName; this.projectService.logger.info("got context event, updating diagnostics for " + fileName_2); - this.errorCheck.startNew(function (next) { return _this.updateErrorCheck(next, [{ fileName: fileName_2, project: project_1 }], _this.changeSeq, function (n) { return n === _this.changeSeq; }, 100); }); + this.errorCheck.startNew(function (next) { return _this.updateErrorCheck(next, [{ fileName: fileName_2, project: project_1 }], 100); }); break; case server.ConfigFileDiagEvent: var _b = event.data, triggerFile = _b.triggerFile, configFileName = _b.configFileName, diagnostics = _b.diagnostics; @@ -76613,26 +77797,24 @@ var ts; this.logError(err, "syntactic check"); } }; - Session.prototype.updateProjectStructure = function (seq, matchSeq, ms) { + Session.prototype.updateProjectStructure = function () { var _this = this; - if (ms === void 0) { ms = 1500; } + var ms = 1500; + var seq = this.changeSeq; this.host.setTimeout(function () { - if (matchSeq(seq)) { + if (_this.changeSeq === seq) { _this.projectService.refreshInferredProjects(); } }, ms); }; - Session.prototype.updateErrorCheck = function (next, checkList, seq, matchSeq, ms, followMs, requireOpen) { + Session.prototype.updateErrorCheck = function (next, checkList, ms, requireOpen) { var _this = this; - if (ms === void 0) { ms = 1500; } - if (followMs === void 0) { followMs = 200; } if (requireOpen === void 0) { requireOpen = true; } - if (followMs > ms) { - followMs = ms; - } + var seq = this.changeSeq; + var followMs = Math.min(ms, 200); var index = 0; var checkOne = function () { - if (matchSeq(seq)) { + if (_this.changeSeq === seq) { var checkSpec_1 = checkList[index]; index++; if (checkSpec_1.project.containsFile(checkSpec_1.fileName, requireOpen)) { @@ -76646,7 +77828,7 @@ var ts; } } }; - if ((checkList.length > index) && (matchSeq(seq))) { + if (checkList.length > index && this.changeSeq === seq) { next.delay(ms, checkOne); } }; @@ -76724,7 +77906,7 @@ var ts; Session.prototype.getDiagnosticsWorker = function (args, isSemantic, selector, includeLinePosition) { var _a = this.getFileAndProject(args), project = _a.project, file = _a.file; if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { - return []; + return server.emptyArray; } var scriptInfo = project.getScriptInfoForNormalizedPath(file); var diagnostics = selector(project, file); @@ -76776,7 +77958,7 @@ var ts; var position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file)); var implementations = project.getLanguageService().getImplementationAtPosition(file, position); if (!implementations) { - return []; + return server.emptyArray; } if (simplifiedResult) { return implementations.map(function (_a) { @@ -76821,7 +78003,7 @@ var ts; Session.prototype.getSyntacticDiagnosticsSync = function (args) { var configFile = this.getConfigFileAndProject(args).configFile; if (configFile) { - return []; + return server.emptyArray; } return this.getDiagnosticsWorker(args, false, function (project, file) { return project.getLanguageService().getSyntacticDiagnostics(file); }, args.includeLinePosition); }; @@ -76862,7 +78044,7 @@ var ts; } }; Session.prototype.setCompilerOptionsForInferredProjects = function (args) { - this.projectService.setCompilerOptionsForInferredProjects(args.options); + this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath); }; Session.prototype.getProjectInfo = function (args) { return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, false); @@ -76924,13 +78106,13 @@ var ts; if (!renameInfo.canRename) { return { info: renameInfo, - locs: [] + locs: server.emptyArray }; } var fileSpans = server.combineProjectOutput(projects, function (project) { var renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments); if (!renameLocations) { - return []; + return server.emptyArray; } return renameLocations.map(function (location) { var locationScriptInfo = project.getScriptInfo(location.fileName); @@ -77011,7 +78193,7 @@ var ts; var refs = server.combineProjectOutput(projects, function (project) { var references = project.getLanguageService().getReferencesAtPosition(file, position); if (!references) { - return []; + return server.emptyArray; } return references.map(function (ref) { var refScriptInfo = project.getScriptInfo(ref.fileName); @@ -77052,7 +78234,7 @@ var ts; if (this.eventHandler) { this.eventHandler({ eventName: "configFileDiag", - data: { triggerFile: fileName, configFileName: configFileName, diagnostics: configFileErrors || [] } + data: { triggerFile: fileName, configFileName: configFileName, diagnostics: configFileErrors || server.emptyArray } }); } }; @@ -77240,7 +78422,7 @@ var ts; var info = this.projectService.getScriptInfo(args.file); var result = []; if (!info) { - return []; + return server.emptyArray; } var projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects; for (var _i = 0, projectsToSearch_1 = projectsToSearch; _i < projectsToSearch_1.length; _i++) { @@ -77300,11 +78482,10 @@ var ts; return project && { fileName: fileName, project: project }; }); if (checkList.length > 0) { - this.updateErrorCheck(next, checkList, this.changeSeq, function (n) { return n === _this.changeSeq; }, delay); + this.updateErrorCheck(next, checkList, delay); } }; Session.prototype.change = function (args) { - var _this = this; var _a = this.getFileAndProject(args, false), file = _a.file, project = _a.project; if (project) { var scriptInfo = project.getScriptInfoForNormalizedPath(file); @@ -77314,7 +78495,7 @@ var ts; scriptInfo.editContent(start, end, args.insertString); this.changeSeq++; } - this.updateProjectStructure(this.changeSeq, function (n) { return n === _this.changeSeq; }); + this.updateProjectStructure(); } }; Session.prototype.reload = function (args, reqSeq) { @@ -77393,7 +78574,7 @@ var ts; return server.combineProjectOutput(projects, function (project) { var navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, project.isNonTsProject()); if (!navItems) { - return []; + return server.emptyArray; } return navItems.map(function (navItem) { var scriptInfo = project.getScriptInfo(navItem.fileName); @@ -77583,7 +78764,6 @@ var ts; : spans; }; Session.prototype.getDiagnosticsForProject = function (next, delay, fileName) { - var _this = this; var _a = this.getProjectInfoWorker(fileName, undefined, true, true), fileNames = _a.fileNames, languageServiceDisabled = _a.languageServiceDisabled; if (languageServiceDisabled) { return; @@ -77618,7 +78798,7 @@ var ts; fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles); if (fileNamesInProject.length > 0) { var checkList = fileNamesInProject.map(function (fileName) { return ({ fileName: fileName, project: project }); }); - this.updateErrorCheck(next, checkList, this.changeSeq, function (n) { return n === _this.changeSeq; }, delay, 200, false); + this.updateErrorCheck(next, checkList, delay, false); } }; Session.prototype.getCanonicalFileName = function (fileName) { @@ -77725,13 +78905,13 @@ var ts; CharRangeSection[CharRangeSection["Mid"] = 3] = "Mid"; CharRangeSection[CharRangeSection["End"] = 4] = "End"; CharRangeSection[CharRangeSection["PostEnd"] = 5] = "PostEnd"; - })(CharRangeSection = server.CharRangeSection || (server.CharRangeSection = {})); + })(CharRangeSection || (CharRangeSection = {})); var EditWalker = (function () { function EditWalker() { this.goSubtree = true; this.lineIndex = new LineIndex(); this.endBranch = []; - this.state = CharRangeSection.Entire; + this.state = 2; this.initialText = ""; this.trailingText = ""; this.lineIndex.root = new LineNode(); @@ -77820,14 +79000,14 @@ var ts; }; EditWalker.prototype.post = function (_relativeStart, _relativeLength, lineCollection) { if (lineCollection === this.lineCollectionAtBranch) { - this.state = CharRangeSection.End; + this.state = 4; } this.stack.pop(); }; EditWalker.prototype.pre = function (_relativeStart, _relativeLength, lineCollection, _parent, nodeType) { var currentNode = this.stack[this.stack.length - 1]; - if ((this.state === CharRangeSection.Entire) && (nodeType === CharRangeSection.Start)) { - this.state = CharRangeSection.Start; + if ((this.state === 2) && (nodeType === 1)) { + this.state = 1; this.branchNode = currentNode; this.lineCollectionAtBranch = lineCollection; } @@ -77840,14 +79020,14 @@ var ts; return new LineNode(); } switch (nodeType) { - case CharRangeSection.PreStart: + case 0: this.goSubtree = false; - if (this.state !== CharRangeSection.End) { + if (this.state !== 4) { currentNode.add(lineCollection); } break; - case CharRangeSection.Start: - if (this.state === CharRangeSection.End) { + case 1: + if (this.state === 4) { this.goSubtree = false; } else { @@ -77856,8 +79036,8 @@ var ts; this.startPath.push(child); } break; - case CharRangeSection.Entire: - if (this.state !== CharRangeSection.End) { + case 2: + if (this.state !== 4) { child = fresh(lineCollection); currentNode.add(child); this.startPath.push(child); @@ -77870,11 +79050,11 @@ var ts; } } break; - case CharRangeSection.Mid: + case 3: this.goSubtree = false; break; - case CharRangeSection.End: - if (this.state !== CharRangeSection.End) { + case 4: + if (this.state !== 4) { this.goSubtree = false; } else { @@ -77885,9 +79065,9 @@ var ts; } } break; - case CharRangeSection.PostEnd: + case 5: this.goSubtree = false; - if (this.state !== CharRangeSection.Start) { + if (this.state !== 1) { currentNode.add(lineCollection); } break; @@ -77897,10 +79077,10 @@ var ts; } }; EditWalker.prototype.leaf = function (relativeStart, relativeLength, ll) { - if (this.state === CharRangeSection.Start) { + if (this.state === 1) { this.initialText = ll.text.substring(0, relativeStart); } - else if (this.state === CharRangeSection.Entire) { + else if (this.state === 2) { this.initialText = ll.text.substring(0, relativeStart); this.trailingText = ll.text.substring(relativeStart + relativeLength); } @@ -77921,7 +79101,6 @@ var ts; }; return TextChange; }()); - server.TextChange = TextChange; var ScriptVersionCache = (function () { function ScriptVersionCache() { this.changes = []; @@ -77946,15 +79125,6 @@ var ts; this.getSnapshot(); } }; - ScriptVersionCache.prototype.latest = function () { - return this.versions[this.currentVersionToIndex()]; - }; - ScriptVersionCache.prototype.latestVersion = function () { - if (this.changes.length > 0) { - this.getSnapshot(); - } - return this.currentVersion; - }; ScriptVersionCache.prototype.reload = function (script) { this.currentVersion++; this.changes = []; @@ -77967,7 +79137,8 @@ var ts; snap.index.load(lm.lines); this.minVersion = this.currentVersion; }; - ScriptVersionCache.prototype.getSnapshot = function () { + ScriptVersionCache.prototype.getSnapshot = function () { return this._getSnapshot(); }; + ScriptVersionCache.prototype._getSnapshot = function () { var snap = this.versions[this.currentVersionToIndex()]; if (this.changes.length > 0) { var snapIndex = snap.index; @@ -77985,6 +79156,24 @@ var ts; } return snap; }; + ScriptVersionCache.prototype.getSnapshotVersion = function () { + return this._getSnapshot().version; + }; + ScriptVersionCache.prototype.getLineInfo = function (line) { + return this._getSnapshot().index.lineNumberToInfo(line); + }; + ScriptVersionCache.prototype.lineOffsetToPosition = function (line, column) { + return this._getSnapshot().index.absolutePositionOfStartOfLine(line) + (column - 1); + }; + ScriptVersionCache.prototype.positionToLineOffset = function (position) { + return this._getSnapshot().index.positionToLineOffset(position); + }; + ScriptVersionCache.prototype.lineToTextSpan = function (line) { + var index = this._getSnapshot().index; + var _a = index.lineNumberToInfo(line + 1), lineText = _a.lineText, absolutePosition = _a.absolutePosition; + var len = lineText !== undefined ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition; + return ts.createTextSpan(absolutePosition, len); + }; ScriptVersionCache.prototype.getTextChangesBetweenVersions = function (oldVersion, newVersion) { if (oldVersion < newVersion) { if (oldVersion >= this.minVersion) { @@ -78046,7 +79235,6 @@ var ts; }; return LineIndexSnapshot; }()); - server.LineIndexSnapshot = LineIndexSnapshot; var LineIndex = (function () { function LineIndex() { this.checkEdits = false; @@ -78245,18 +79433,18 @@ var ts; var childCharCount = this.children[childIndex].charCount(); var adjustedStart = rangeStart; while (adjustedStart >= childCharCount) { - this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, CharRangeSection.PreStart); + this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, 0); adjustedStart -= childCharCount; childIndex++; childCharCount = this.children[childIndex].charCount(); } if ((adjustedStart + rangeLength) <= childCharCount) { - if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, CharRangeSection.Entire)) { + if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, 2)) { return; } } else { - if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, CharRangeSection.Start)) { + if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, 1)) { return; } var adjustedLength = rangeLength - (childCharCount - adjustedStart); @@ -78264,7 +79452,7 @@ var ts; var child = this.children[childIndex]; childCharCount = child.charCount(); while (adjustedLength > childCharCount) { - if (this.execWalk(0, childCharCount, walkFns, childIndex, CharRangeSection.Mid)) { + if (this.execWalk(0, childCharCount, walkFns, childIndex, 3)) { return; } adjustedLength -= childCharCount; @@ -78272,7 +79460,7 @@ var ts; childCharCount = this.children[childIndex].charCount(); } if (adjustedLength > 0) { - if (this.execWalk(0, adjustedLength, walkFns, childIndex, CharRangeSection.End)) { + if (this.execWalk(0, adjustedLength, walkFns, childIndex, 4)) { return; } } @@ -78281,82 +79469,46 @@ var ts; var clen = this.children.length; if (childIndex < (clen - 1)) { for (var ej = childIndex + 1; ej < clen; ej++) { - this.skipChild(0, 0, ej, walkFns, CharRangeSection.PostEnd); + this.skipChild(0, 0, ej, walkFns, 5); } } } }; LineNode.prototype.charOffsetToLineInfo = function (lineNumberAccumulator, relativePosition) { - var childInfo = this.childFromCharOffset(lineNumberAccumulator, relativePosition); - if (!childInfo.child) { - return { - oneBasedLine: lineNumberAccumulator, - zeroBasedColumn: relativePosition, - lineText: undefined, - }; + if (this.children.length === 0) { + return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: undefined }; } - else if (childInfo.childIndex < this.children.length) { - if (childInfo.child.isLeaf()) { - return { - oneBasedLine: childInfo.lineNumberAccumulator, - zeroBasedColumn: childInfo.relativePosition, - lineText: childInfo.child.text, - }; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (child.charCount() > relativePosition) { + if (child.isLeaf()) { + return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: child.text }; + } + else { + return child.charOffsetToLineInfo(lineNumberAccumulator, relativePosition); + } } else { - var lineNode = (childInfo.child); - return lineNode.charOffsetToLineInfo(childInfo.lineNumberAccumulator, childInfo.relativePosition); + relativePosition -= child.charCount(); + lineNumberAccumulator += child.lineCount(); } } - else { - var lineInfo = this.lineNumberToInfo(this.lineCount(), 0); - return { oneBasedLine: this.lineCount(), zeroBasedColumn: lineInfo.leaf.charCount(), lineText: undefined }; - } + var leaf = this.lineNumberToInfo(this.lineCount(), 0).leaf; + return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf.charCount(), lineText: undefined }; }; LineNode.prototype.lineNumberToInfo = function (relativeOneBasedLine, positionAccumulator) { - var childInfo = this.childFromLineNumber(relativeOneBasedLine, positionAccumulator); - if (!childInfo.child) { - return { position: positionAccumulator, leaf: undefined }; - } - else if (childInfo.child.isLeaf()) { - return { position: childInfo.positionAccumulator, leaf: childInfo.child }; - } - else { - var lineNode = (childInfo.child); - return lineNode.lineNumberToInfo(childInfo.relativeOneBasedLine, childInfo.positionAccumulator); - } - }; - LineNode.prototype.childFromLineNumber = function (relativeOneBasedLine, positionAccumulator) { - var child; - var i; - for (i = 0; i < this.children.length; i++) { - child = this.children[i]; + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; var childLineCount = child.lineCount(); if (childLineCount >= relativeOneBasedLine) { - break; + return child.isLeaf() ? { position: positionAccumulator, leaf: child } : child.lineNumberToInfo(relativeOneBasedLine, positionAccumulator); } else { relativeOneBasedLine -= childLineCount; positionAccumulator += child.charCount(); } } - return { child: child, relativeOneBasedLine: relativeOneBasedLine, positionAccumulator: positionAccumulator }; - }; - LineNode.prototype.childFromCharOffset = function (lineNumberAccumulator, relativePosition) { - var child; - var i; - var len; - for (i = 0, len = this.children.length; i < len; i++) { - child = this.children[i]; - if (child.charCount() > relativePosition) { - break; - } - else { - relativePosition -= child.charCount(); - lineNumberAccumulator += child.lineCount(); - } - } - return { child: child, childIndex: i, relativePosition: relativePosition, lineNumberAccumulator: lineNumberAccumulator }; + return { position: positionAccumulator, leaf: undefined }; }; LineNode.prototype.splitAfter = function (childIndex) { var splitNode; @@ -78453,7 +79605,6 @@ var ts; }; return LineNode; }()); - server.LineNode = LineNode; var LineLeaf = (function () { function LineLeaf(text) { this.text = text; @@ -78472,7 +79623,6 @@ var ts; }; return LineLeaf; }()); - server.LineLeaf = LineLeaf; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); var ts; @@ -78488,7 +79638,7 @@ var ts; } TextStorage.prototype.getVersion = function () { return this.svc - ? "SVC-" + this.svcVersion + "-" + this.svc.getSnapshot().version + ? "SVC-" + this.svcVersion + "-" + this.svc.getSnapshotVersion() : "Text-" + this.textVersion; }; TextStorage.prototype.hasScriptVersionCache = function () { @@ -78526,7 +79676,7 @@ var ts; : ts.ScriptSnapshot.fromString(this.getOrLoadText()); }; TextStorage.prototype.getLineInfo = function (line) { - return this.switchToScriptVersionCache().getSnapshot().index.lineNumberToInfo(line); + return this.switchToScriptVersionCache().getLineInfo(line); }; TextStorage.prototype.lineToTextSpan = function (line) { if (!this.svc) { @@ -78535,23 +79685,20 @@ var ts; var end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length; return ts.createTextSpanFromBounds(start, end); } - var index = this.svc.getSnapshot().index; - var _a = index.lineNumberToInfo(line + 1), lineText = _a.lineText, absolutePosition = _a.absolutePosition; - var len = lineText !== undefined ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition; - return ts.createTextSpan(absolutePosition, len); + return this.svc.lineToTextSpan(line); }; TextStorage.prototype.lineOffsetToPosition = function (line, offset) { if (!this.svc) { return ts.computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text); } - return this.svc.getSnapshot().index.absolutePositionOfStartOfLine(line) + (offset - 1); + return this.svc.lineOffsetToPosition(line, offset); }; TextStorage.prototype.positionToLineOffset = function (position) { if (!this.svc) { var _a = ts.computeLineAndCharacterOfPosition(this.getLineMap(), position), line = _a.line, character = _a.character; return { line: line + 1, offset: character + 1 }; } - return this.svc.getSnapshot().index.positionToLineOffset(position); + return this.svc.positionToLineOffset(position); }; TextStorage.prototype.getFileText = function (tempFileName) { return this.host.readFile(tempFileName || this.fileName) || ""; @@ -79460,7 +80607,8 @@ var ts; log("Loading " + moduleName + " from " + initialDir + " (resolved to " + resolvedPath + ")"); var result = host.require(resolvedPath, moduleName); if (result.error) { - log("Failed to load module: " + JSON.stringify(result.error)); + var err = result.error.stack || result.error.message || JSON.stringify(result.error); + log("Failed to load module '" + moduleName + "': " + err); return undefined; } return result.module; @@ -79590,7 +80738,7 @@ var ts; return ts.map(this.program.getSourceFiles(), function (sourceFile) { var scriptInfo = _this.projectService.getScriptInfoForPath(sourceFile.path); if (!scriptInfo) { - ts.Debug.assert(false, "scriptInfo for a file '" + sourceFile.fileName + "' is missing."); + ts.Debug.fail("scriptInfo for a file '" + sourceFile.fileName + "' is missing."); } return scriptInfo; }); @@ -79752,7 +80900,7 @@ var ts; var sourceFile = _b[_a]; this.extractUnresolvedImportsFromSourceFile(sourceFile, result); } - this.lastCachedUnresolvedImportsList = server.toSortedArray(result); + this.lastCachedUnresolvedImportsList = server.toDeduplicatedSortedArray(result); } unresolvedImports = this.lastCachedUnresolvedImportsList; var cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, unresolvedImports, hasChanges); @@ -79804,7 +80952,7 @@ var ts; fileWatcher.close(); } }); - var _loop_8 = function (missingFilePath) { + var _loop_9 = function (missingFilePath) { if (!this_1.missingFilesMap.has(missingFilePath)) { var fileWatcher_1 = this_1.projectService.host.watchFile(missingFilePath, function (_filename, eventKind) { if (eventKind === ts.FileWatcherEventKind.Created && _this.missingFilesMap.has(missingFilePath)) { @@ -79820,7 +80968,7 @@ var ts; var this_1 = this; for (var _b = 0, missingFilePaths_1 = missingFilePaths; _b < missingFilePaths_1.length; _b++) { var missingFilePath = missingFilePaths_1[_b]; - _loop_8(missingFilePath); + _loop_9(missingFilePath); } } var oldExternalFiles = this.externalFiles || server.emptyArray; @@ -79984,10 +81132,11 @@ var ts; server.Project = Project; var InferredProject = (function (_super) { __extends(InferredProject, _super); - function InferredProject(projectService, documentRegistry, compilerOptions) { + function InferredProject(projectService, documentRegistry, compilerOptions, projectRootPath) { var _this = _super.call(this, InferredProject.newName(), ProjectKind.Inferred, projectService, documentRegistry, undefined, true, compilerOptions, false) || this; _this._isJsInferredProject = false; _this.directoriesWatchedForTsconfig = []; + _this.projectRootPath = projectRootPath; return _this; } InferredProject.prototype.toggleJsInferredProject = function (isJsInferredProject) { @@ -80091,7 +81240,7 @@ var ts; } } if (this.projectService.globalPlugins) { - var _loop_9 = function (globalPluginName) { + var _loop_10 = function (globalPluginName) { if (options.plugins && options.plugins.some(function (p) { return p.name === globalPluginName; })) return "continue"; this_2.enablePlugin({ name: globalPluginName, global: true }, searchPaths); @@ -80099,7 +81248,7 @@ var ts; var this_2 = this; for (var _b = 0, _c = this.projectService.globalPlugins; _b < _c.length; _b++) { var globalPluginName = _c[_b]; - _loop_9(globalPluginName); + _loop_10(globalPluginName); } } }; @@ -80222,10 +81371,12 @@ var ts; } this.typeRootsWatchers = undefined; } - this.directoriesWatchedForWildcards.forEach(function (watcher) { - watcher.close(); - }); - this.directoriesWatchedForWildcards = undefined; + if (this.directoriesWatchedForWildcards) { + this.directoriesWatchedForWildcards.forEach(function (watcher) { + watcher.close(); + }); + this.directoriesWatchedForWildcards = undefined; + } this.stopWatchingDirectory(); }; ConfiguredProject.prototype.addOpenRef = function () { @@ -80455,6 +81606,7 @@ var ts; this.inferredProjects = []; this.configuredProjects = []; this.openFiles = []; + this.compilerOptionsForInferredProjectsPerProjectRoot = ts.createMap(); this.projectToSizeMap = ts.createMap(); this.safelist = defaultTypeSafeList; this.seenProjects = ts.createMap(); @@ -80462,6 +81614,7 @@ var ts; this.logger = opts.logger; this.cancellationToken = opts.cancellationToken; this.useSingleInferredProject = opts.useSingleInferredProject; + this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot; this.typingsInstaller = opts.typingsInstaller || server.nullTypingsInstaller; this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = opts.eventHandler; @@ -80494,10 +81647,11 @@ var ts; if (!this.eventHandler) { return; } - this.eventHandler({ + var event = { eventName: server.ProjectLanguageServiceStateEvent, data: { project: project, languageServiceEnabled: languageServiceEnabled } - }); + }; + this.eventHandler(event); }; ProjectService.prototype.updateTypingsForProject = function (response) { var project = this.findProject(response.projectName); @@ -80514,16 +81668,28 @@ var ts; } project.updateGraph(); }; - ProjectService.prototype.setCompilerOptionsForInferredProjects = function (projectCompilerOptions) { - this.compilerOptionsForInferredProjects = convertCompilerOptions(projectCompilerOptions); - this.compilerOptionsForInferredProjects.allowNonTsExtensions = true; - this.compileOnSaveForInferredProjects = projectCompilerOptions.compileOnSave; + ProjectService.prototype.setCompilerOptionsForInferredProjects = function (projectCompilerOptions, projectRootPath) { + ts.Debug.assert(projectRootPath === undefined || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled"); + var compilerOptions = convertCompilerOptions(projectCompilerOptions); + compilerOptions.allowNonTsExtensions = true; + if (projectRootPath) { + this.compilerOptionsForInferredProjectsPerProjectRoot.set(projectRootPath, compilerOptions); + } + else { + this.compilerOptionsForInferredProjects = compilerOptions; + } + var updatedProjects = []; for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { - var proj = _a[_i]; - proj.setCompilerOptions(this.compilerOptionsForInferredProjects); - proj.compileOnSaveEnabled = projectCompilerOptions.compileOnSave; + var project = _a[_i]; + if (projectRootPath ? + project.projectRootPath === projectRootPath : + !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { + project.setCompilerOptions(compilerOptions); + project.compileOnSaveEnabled = compilerOptions.compileOnSave; + updatedProjects.push(project); + } } - this.updateProjectGraphs(this.inferredProjects); + this.updateProjectGraphs(updatedProjects); }; ProjectService.prototype.stopWatchingDirectory = function (directory) { this.directoryWatchers.stopWatchingDirectory(directory); @@ -80630,10 +81796,11 @@ var ts; } for (var _i = 0, _a = this.openFiles; _i < _a.length; _i++) { var openFile = _a[_i]; - this.eventHandler({ + var event = { eventName: server.ContextEvent, data: { project: openFile.getDefaultProject(), fileName: openFile.fileName } - }); + }; + this.eventHandler(event); } } this.printProjects(); @@ -80705,7 +81872,7 @@ var ts; break; } }; - ProjectService.prototype.assignScriptInfoToInferredProjectIfNecessary = function (info, addToListOfOpenFiles) { + ProjectService.prototype.assignScriptInfoToInferredProjectIfNecessary = function (info, addToListOfOpenFiles, projectRootPath) { var externalProject = this.findContainingExternalProject(info.fileName); if (externalProject) { if (addToListOfOpenFiles) { @@ -80730,19 +81897,19 @@ var ts; return; } if (info.containingProjects.length === 0) { - var inferredProject = this.createInferredProjectWithRootFileIfNecessary(info); - if (!this.useSingleInferredProject) { + var inferredProject = this.createInferredProjectWithRootFileIfNecessary(info, projectRootPath); + if (!this.useSingleInferredProject && !inferredProject.projectRootPath) { for (var _b = 0, _c = this.openFiles; _b < _c.length; _b++) { var f = _c[_b]; if (f.containingProjects.length === 0 || !inferredProject.containsScriptInfo(f)) { continue; } for (var _d = 0, _e = f.containingProjects; _d < _e.length; _d++) { - var fContainingProject = _e[_d]; - if (fContainingProject.projectKind === server.ProjectKind.Inferred && - fContainingProject.isRoot(f) && - fContainingProject !== inferredProject) { - this.removeProject(fContainingProject); + var containingProject = _e[_d]; + if (containingProject.projectKind === server.ProjectKind.Inferred && + containingProject !== inferredProject && + containingProject.isRoot(f)) { + this.removeProject(containingProject); f.attachToProject(inferredProject); } } @@ -80853,31 +82020,32 @@ var ts; return undefined; }; ProjectService.prototype.printProjects = function () { + var _this = this; if (!this.logger.hasLevel(server.LogLevel.verbose)) { return; } this.logger.startGroup(); var counter = 0; - counter = printProjects(this.logger, this.externalProjects, counter); - counter = printProjects(this.logger, this.configuredProjects, counter); - counter = printProjects(this.logger, this.inferredProjects, counter); - this.logger.info("Open files: "); - for (var _i = 0, _a = this.openFiles; _i < _a.length; _i++) { - var rootFile = _a[_i]; - this.logger.info("\t" + rootFile.fileName); - } - this.logger.endGroup(); - function printProjects(logger, projects, counter) { + var printProjects = function (projects, counter) { for (var _i = 0, projects_4 = projects; _i < projects_4.length; _i++) { var project = projects_4[_i]; project.updateGraph(); - logger.info("Project '" + project.getProjectName() + "' (" + server.ProjectKind[project.projectKind] + ") " + counter); - logger.info(project.filesToString()); - logger.info("-----------------------------------------------"); + _this.logger.info("Project '" + project.getProjectName() + "' (" + server.ProjectKind[project.projectKind] + ") " + counter); + _this.logger.info(project.filesToString()); + _this.logger.info("-----------------------------------------------"); counter++; } return counter; + }; + counter = printProjects(this.externalProjects, counter); + counter = printProjects(this.configuredProjects, counter); + printProjects(this.inferredProjects, counter); + this.logger.info("Open files: "); + for (var _i = 0, _a = this.openFiles; _i < _a.length; _i++) { + var rootFile = _a[_i]; + this.logger.info("\t" + rootFile.fileName); } + this.logger.endGroup(); }; ProjectService.prototype.findConfiguredProjectByProjectName = function (configFileName) { configFileName = server.asNormalizedPath(this.toCanonicalFileName(configFileName)); @@ -80998,10 +82166,11 @@ var ts; if (!this.eventHandler) { return; } - this.eventHandler({ + var event = { eventName: server.ConfigFileDiagEvent, - data: { configFileName: configFileName, diagnostics: diagnostics || [], triggerFile: triggerFile } - }); + data: { configFileName: configFileName, diagnostics: diagnostics || server.emptyArray, triggerFile: triggerFile } + }; + this.eventHandler(event); }; ProjectService.prototype.createAndAddConfiguredProject = function (configFileName, projectOptions, configFileErrors, clientFileName) { var _this = this; @@ -81150,18 +82319,60 @@ var ts; } return configFileErrors; }; - ProjectService.prototype.createInferredProjectWithRootFileIfNecessary = function (root) { + ProjectService.prototype.getOrCreateInferredProjectForProjectRootPathIfEnabled = function (root, projectRootPath) { + if (!this.useInferredProjectPerProjectRoot) { + return undefined; + } + if (projectRootPath) { + for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { + var project = _a[_i]; + if (project.projectRootPath === projectRootPath) { + return project; + } + } + return this.createInferredProject(false, projectRootPath); + } + var bestMatch; + for (var _b = 0, _c = this.inferredProjects; _b < _c.length; _b++) { + var project = _c[_b]; + if (!project.projectRootPath) + continue; + if (!ts.containsPath(project.projectRootPath, root.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) + continue; + if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) + continue; + bestMatch = project; + } + return bestMatch; + }; + ProjectService.prototype.getOrCreateSingleInferredProjectIfEnabled = function () { + if (!this.useSingleInferredProject) { + return undefined; + } + if (this.inferredProjects.length > 0 && this.inferredProjects[0].projectRootPath === undefined) { + return this.inferredProjects[0]; + } + return this.createInferredProject(true); + }; + ProjectService.prototype.createInferredProject = function (isSingleInferredProject, projectRootPath) { + var compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects; + var project = new server.InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath); + if (isSingleInferredProject) { + this.inferredProjects.unshift(project); + } + else { + this.inferredProjects.push(project); + } + return project; + }; + ProjectService.prototype.createInferredProjectWithRootFileIfNecessary = function (root, projectRootPath) { var _this = this; - var useExistingProject = this.useSingleInferredProject && this.inferredProjects.length; - var project = useExistingProject - ? this.inferredProjects[0] - : new server.InferredProject(this, this.documentRegistry, this.compilerOptionsForInferredProjects); + var project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(root, projectRootPath) || + this.getOrCreateSingleInferredProjectIfEnabled() || + this.createInferredProject(); project.addRoot(root); this.directoryWatchers.startWatchingContainingDirectoriesForFile(root.fileName, project, function (fileName) { return _this.onConfigFileAddedForInferredProject(fileName); }); project.updateGraph(); - if (!useExistingProject) { - this.inferredProjects.push(project); - } return project; }; ProjectService.prototype.getOrCreateScriptInfo = function (uncheckedFileName, openedByClient, fileContent, scriptKind) { @@ -81294,7 +82505,7 @@ var ts; project.markAsDirty(); } var info = this.getOrCreateScriptInfoForNormalizedPath(fileName, true, fileContent, scriptKind, hasMixedContent); - this.assignScriptInfoToInferredProjectIfNecessary(info, true); + this.assignScriptInfoToInferredProjectIfNecessary(info, true, projectRootPath); this.deleteOrphanScriptInfoNotInAnyProject(); this.printProjects(); return { configFileName: configFileName, configFileErrors: configFileErrors }; @@ -81308,13 +82519,13 @@ var ts; this.printProjects(); }; ProjectService.prototype.collectChanges = function (lastKnownProjectVersions, currentProjects, result) { - var _loop_10 = function (proj) { + var _loop_11 = function (proj) { var knownProject = ts.forEach(lastKnownProjectVersions, function (p) { return p.projectName === proj.getProjectName() && p; }); result.push(proj.getChangesSinceVersion(knownProject && knownProject.version)); }; for (var _i = 0, currentProjects_1 = currentProjects; _i < currentProjects_1.length; _i++) { var proj = currentProjects_1[_i]; - _loop_10(proj); + _loop_11(proj); } }; ProjectService.prototype.synchronizeProjectList = function (knownProjects) { @@ -81433,7 +82644,7 @@ var ts; var types = (typeAcquisition && typeAcquisition.include) || []; var excludeRules = []; var normalizedNames = rootFiles.map(function (f) { return ts.normalizeSlashes(f.fileName); }); - var _loop_11 = function (name) { + var _loop_12 = function (name) { var rule = this_3.safelist[name]; for (var _i = 0, normalizedNames_1 = normalizedNames; _i < normalizedNames_1.length; _i++) { var root = normalizedNames_1[_i]; @@ -81448,7 +82659,7 @@ var ts; } } if (rule.exclude) { - var _loop_12 = function (exclude) { + var _loop_13 = function (exclude) { var processedRule = root.replace(rule.match, function () { var groups = []; for (var _i = 0; _i < arguments.length; _i++) { @@ -81471,7 +82682,7 @@ var ts; }; for (var _c = 0, _d = rule.exclude; _c < _d.length; _c++) { var exclude = _d[_c]; - _loop_12(exclude); + _loop_13(exclude); } } else { @@ -81490,7 +82701,7 @@ var ts; var this_3 = this; for (var _i = 0, _a = Object.keys(this.safelist); _i < _a.length; _i++) { var name = _a[_i]; - _loop_11(name); + _loop_12(name); } var excludeRegexes = excludeRules.map(function (e) { return new RegExp(e, "i"); }); proj.rootFiles = proj.rootFiles.filter(function (_file, index) { return !excludeRegexes.some(function (re) { return re.test(normalizedNames[index]); }); }); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 1ca5c4d7736fc..bec9e8609c820 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1210,7 +1210,7 @@ declare namespace ts { interface CatchClause extends Node { kind: SyntaxKind.CatchClause; parent?: TryStatement; - variableDeclaration: VariableDeclaration; + variableDeclaration?: VariableDeclaration; block: Block; } type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; @@ -1496,38 +1496,39 @@ declare namespace ts { interface FlowLock { locked?: boolean; } - interface AfterFinallyFlow extends FlowNode, FlowLock { + interface AfterFinallyFlow extends FlowNodeBase, FlowLock { antecedent: FlowNode; } - interface PreFinallyFlow extends FlowNode { + interface PreFinallyFlow extends FlowNodeBase { antecedent: FlowNode; lock: FlowLock; } - interface FlowNode { + type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + interface FlowNodeBase { flags: FlowFlags; id?: number; } - interface FlowStart extends FlowNode { + interface FlowStart extends FlowNodeBase { container?: FunctionExpression | ArrowFunction | MethodDeclaration; } - interface FlowLabel extends FlowNode { + interface FlowLabel extends FlowNodeBase { antecedents: FlowNode[]; } - interface FlowAssignment extends FlowNode { + interface FlowAssignment extends FlowNodeBase { node: Expression | VariableDeclaration | BindingElement; antecedent: FlowNode; } - interface FlowCondition extends FlowNode { + interface FlowCondition extends FlowNodeBase { expression: Expression; antecedent: FlowNode; } - interface FlowSwitchClause extends FlowNode { + interface FlowSwitchClause extends FlowNodeBase { switchStatement: SwitchStatement; clauseStart: number; clauseEnd: number; antecedent: FlowNode; } - interface FlowArrayMutation extends FlowNode { + interface FlowArrayMutation extends FlowNodeBase { node: CallExpression | BinaryExpression; antecedent: FlowNode; } @@ -1795,6 +1796,7 @@ declare namespace ts { AddUndefined = 8192, WriteClassExpressionAsTypeLiteral = 16384, InArrayType = 32768, + UseAliasDefinedOutsideCurrentScope = 65536, } enum SymbolFormatFlags { None = 0, @@ -2103,6 +2105,21 @@ declare namespace ts { NoDefault = 2, AnyDefault = 4, } + /** + * Ternary values are defined such that + * x & y is False if either x or y is False. + * x & y is Maybe if either x or y is Maybe, but neither x or y is False. + * x & y is True if both x and y are True. + * x | y is False if both x and y are False. + * x | y is Maybe if either x or y is Maybe, but neither x or y is True. + * x | y is True if either x or y is True. + */ + enum Ternary { + False = 0, + Maybe = 1, + True = -1, + } + type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary; interface JsFileExtensionInfo { extension: string; isMixedContent: boolean; @@ -2195,6 +2212,7 @@ declare namespace ts { outFile?: string; paths?: MapLike; preserveConstEnums?: boolean; + preserveSymlinks?: boolean; project?: string; reactNamespace?: string; jsxFactory?: string; @@ -2300,6 +2318,10 @@ declare namespace ts { readFile(fileName: string): string | undefined; trace?(s: string): void; directoryExists?(directoryName: string): boolean; + /** + * Resolve a symbolic link. + * @see https://nodejs.org/api/fs.html#fs_fs_realpathsync_path_options + */ realpath?(path: string): string; getCurrentDirectory?(): string; getDirectories?(path: string): string[]; @@ -2325,6 +2347,7 @@ declare namespace ts { /** * ResolvedModule with an explicitly provided `extension` property. * Prefer this over `ResolvedModule`. + * If changing this, remember to change `moduleResolutionIsEqualTo`. */ interface ResolvedModuleFull extends ResolvedModule { /** @@ -2332,6 +2355,21 @@ declare namespace ts { * This is optional for backwards-compatibility, but will be added if not provided. */ extension: Extension; + packageId?: PackageId; + } + /** + * Unique identifier with a package name and version. + * If changing this, remember to change `packageIdIsEqual`. + */ + interface PackageId { + /** + * Name of the package. + * Should not include `@types`. + * If accessing a non-index file, this should include its name e.g. "foo/bar". + */ + name: string; + /** Version of the package, e.g. "1.2.3" */ + version: string; } enum Extension { Ts = ".ts", @@ -2741,6 +2779,8 @@ declare namespace ts { function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; function isParameterPropertyDeclaration(node: Node): boolean; + function isEmptyBindingPattern(node: BindingName): node is BindingPattern; + function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; function getCombinedNodeFlags(node: Node): NodeFlags; /** @@ -3310,8 +3350,8 @@ declare namespace ts { function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray): DefaultClause; function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray): HeritageClause; function updateHeritageClause(node: HeritageClause, types: ReadonlyArray): HeritageClause; - function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block): CatchClause; - function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block): CatchClause; + function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; + function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; diff --git a/lib/typescript.js b/lib/typescript.js index eb71a73ba466d..3b497d4c471b4 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -511,7 +511,7 @@ var ts; FlowFlags[FlowFlags["Label"] = 12] = "Label"; FlowFlags[FlowFlags["Condition"] = 96] = "Condition"; })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {})); - var OperationCanceledException = (function () { + var OperationCanceledException = /** @class */ (function () { function OperationCanceledException() { } return OperationCanceledException; @@ -575,6 +575,8 @@ var ts; TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined"; TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral"; TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType"; + TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope"; + // even though `T` can't be accessed in the current scope. })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {})); var SymbolFormatFlags; (function (SymbolFormatFlags) { @@ -860,6 +862,21 @@ var ts; InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault"; InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault"; })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {})); + /** + * Ternary values are defined such that + * x & y is False if either x or y is False. + * x & y is Maybe if either x or y is Maybe, but neither x or y is False. + * x & y is True if both x and y are True. + * x | y is False if both x and y are False. + * x | y is Maybe if either x or y is Maybe, but neither x or y is True. + * x | y is True if either x or y is True. + */ + var Ternary; + (function (Ternary) { + Ternary[Ternary["False"] = 0] = "False"; + Ternary[Ternary["Maybe"] = 1] = "Maybe"; + Ternary[Ternary["True"] = -1] = "True"; + })(Ternary = ts.Ternary || (ts.Ternary = {})); /* @internal */ var SpecialPropertyAssignmentKind; (function (SpecialPropertyAssignmentKind) { @@ -1331,25 +1348,10 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); /* @internal */ (function (ts) { - /** - * Ternary values are defined such that - * x & y is False if either x or y is False. - * x & y is Maybe if either x or y is Maybe, but neither x or y is False. - * x & y is True if both x and y are True. - * x | y is False if both x and y are False. - * x | y is Maybe if either x or y is Maybe, but neither x or y is True. - * x | y is True if either x or y is True. - */ - var Ternary; - (function (Ternary) { - Ternary[Ternary["False"] = 0] = "False"; - Ternary[Ternary["Maybe"] = 1] = "Maybe"; - Ternary[Ternary["True"] = -1] = "True"; - })(Ternary = ts.Ternary || (ts.Ternary = {})); // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined; // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". @@ -1403,7 +1405,7 @@ var ts; var MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); // Keep the class inside a function so it doesn't get compiled if it's not used. function shimMap() { - var MapIterator = (function () { + var MapIterator = /** @class */ (function () { function MapIterator(data, selector) { this.index = 0; this.data = data; @@ -1420,7 +1422,7 @@ var ts; }; return MapIterator; }()); - return (function () { + return /** @class */ (function () { function class_1() { this.data = createDictionaryObject(); this.size = 0; @@ -1668,10 +1670,9 @@ var ts; ts.removeWhere = removeWhere; function filterMutate(array, f) { var outIndex = 0; - for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { - var item = array_3[_i]; - if (f(item)) { - array[outIndex] = item; + for (var i = 0; i < array.length; i++) { + if (f(array[i], i, array)) { + array[outIndex] = array[i]; outIndex++; } } @@ -1722,8 +1723,8 @@ var ts; var result; if (array) { result = []; - for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { - var v = array_4[_i]; + for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { + var v = array_3[_i]; if (v) { if (isArray(v)) { addRange(result, v); @@ -1799,11 +1800,13 @@ var ts; ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; - for (var i = 0; i < array.length; i++) { - var item = array[i]; - var mapped = mapFn(item, i); - if (mapped !== undefined) { - result.push(mapped); + if (array) { + for (var i = 0; i < array.length; i++) { + var item = array[i]; + var mapped = mapFn(item, i); + if (mapped !== undefined) { + result.push(mapped); + } } } return result; @@ -1882,8 +1885,8 @@ var ts; function some(array, predicate) { if (array) { if (predicate) { - for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { - var v = array_5[_i]; + for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { + var v = array_4[_i]; if (predicate(v)) { return true; } @@ -1909,8 +1912,8 @@ var ts; var result; if (array) { result = []; - loop: for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { - var item = array_6[_i]; + loop: for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { + var item = array_5[_i]; for (var _a = 0, result_1 = result; _a < result_1.length; _a++) { var res = result_1[_a]; if (areEqual ? areEqual(res, item) : res === item) { @@ -2003,8 +2006,8 @@ var ts; ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; - for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { - var v = array_7[_i]; + for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { + var v = array_6[_i]; // Note: we need the following type assertion because of GH #17069 result += v[prop]; } @@ -2336,8 +2339,8 @@ var ts; ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); - for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { - var value = array_8[_i]; + for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { + var value = array_7[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; @@ -2502,11 +2505,11 @@ var ts; ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { var end = start + length; - Debug.assert(start >= 0, "start must be non-negative, is " + start); - Debug.assert(length >= 0, "length must be non-negative, is " + length); + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); if (file) { - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + Debug.assertLessThanOrEqual(start, file.text.length); + Debug.assertLessThanOrEqual(end, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { @@ -3055,14 +3058,43 @@ var ts; // proof. var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42 /* asterisk */, 63 /* question */]; - /** - * Matches any single directory segment unless it is the last segment and a .min.js file - * Breakdown: - * [^./] # matches everything up to the first . character (excluding directory seperators) - * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension - */ - var singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; - var singleAsteriskRegexFragmentOther = "[^/]*"; + /* @internal */ + ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; + var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; + var filesMatcher = { + /** + * Matches any single directory segment unless it is the last segment and a .min.js file + * Breakdown: + * [^./] # matches everything up to the first . character (excluding directory seperators) + * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension + */ + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + /** + * Regex for the ** wildcard. Matches any number of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } + }; + var directoriesMatcher = { + singleAsteriskRegexFragment: "[^/]*", + /** + * Regex for the ** wildcard. Matches any number of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } + }; + var excludeMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } + }; + var wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher + }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { @@ -3078,15 +3110,8 @@ var ts; if (specs === undefined || specs.length === 0) { return undefined; } - var replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther; - var singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther; - /** - * Regex for the ** wildcard. Matches any number of subdirectories. When used for including - * files or directories, does not match subdirectories that start with a . character - */ - var doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; return flatMap(specs, function (spec) { - return spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); + return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } /** @@ -3097,7 +3122,8 @@ var ts; return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; - function getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter) { + function getSubPatternFromSpec(spec, basePath, usage, _a) { + var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; @@ -3131,19 +3157,33 @@ var ts; subpattern += ts.directorySeparator; } if (usage !== "exclude") { + var componentPattern = ""; // The * and ? wildcards should not match directories or files that start with . if they // appear first in a component. Dotted directories and files can be included explicitly // like so: **/.*/.* if (component.charCodeAt(0) === 42 /* asterisk */) { - subpattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63 /* question */) { - subpattern += "[^./]"; + componentPattern += "[^./]"; component = component.substr(1); } + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + // Patterns should not include subfolders like node_modules unless they are + // explicitly included as part of the path. + // + // As an optimization, if the component pattern is the same as the component, + // then there definitely were no wildcard characters and we do not need to + // add the exclusion pattern. + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } hasWrittenComponent = true; } @@ -3153,12 +3193,6 @@ var ts; } return subpattern; } - function replaceWildCardCharacterFiles(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentFiles); - } - function replaceWildCardCharacterOther(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentOther); - } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } @@ -3319,14 +3353,7 @@ var ts; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } - var extensions = allSupportedExtensions.slice(0); - for (var _i = 0, extraFileExtensions_1 = extraFileExtensions; _i < extraFileExtensions_1.length; _i++) { - var extInfo = extraFileExtensions_1[_i]; - if (extensions.indexOf(extInfo.extension) === -1) { - extensions.push(extInfo.extension); - } - } - return extensions; + return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; }))); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { @@ -3481,12 +3508,37 @@ var ts; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + verboseDebugInfo(); + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; + function assertEqual(a, b, msg, msg2) { + if (a !== b) { + var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; + fail("Expected " + a + " === " + b + ". " + message); + } + } + Debug.assertEqual = assertEqual; + function assertLessThan(a, b, msg) { + if (a >= b) { + fail("Expected " + a + " < " + b + ". " + (msg || "")); + } + } + Debug.assertLessThan = assertLessThan; + function assertLessThanOrEqual(a, b) { + if (a > b) { + fail("Expected " + a + " <= " + b); + } + } + Debug.assertLessThanOrEqual = assertLessThanOrEqual; + function assertGreaterThanOrEqual(a, b) { + if (a < b) { + fail("Expected " + a + " >= " + b); + } + } + Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); @@ -3652,6 +3704,10 @@ var ts; Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; + function isAnySupportedFileExtension(path) { + return tryGetExtensionFromPath(path) !== undefined; + } + ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } @@ -3664,6 +3720,18 @@ var ts; /// var ts; (function (ts) { + /** + * Set a high stack trace limit to provide more information in case of an error. + * Called for command-line and server use cases. + * Not called if TypeScript is used as a library. + */ + /* @internal */ + function setStackTraceLimit() { + if (Error.stackTraceLimit < 100) { + Error.stackTraceLimit = 100; + } + } + ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; @@ -3714,7 +3782,7 @@ var ts; watcher.referenceCount += 1; return; } - watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); + watcher = _fs.watch(dirPath || ".", { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; @@ -4569,6 +4637,7 @@ var ts; Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), + Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), @@ -4756,6 +4825,7 @@ var ts; Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), + Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), @@ -5009,6 +5079,8 @@ var ts; Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), + Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), }; })(ts || (ts = {})); /// @@ -6812,19 +6884,6 @@ var ts; return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; - function findDeclaration(symbol, predicate) { - var declarations = symbol.declarations; - if (declarations) { - for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { - var declaration = declarations_2[_i]; - if (predicate(declaration)) { - return declaration; - } - } - } - return undefined; - } - ts.findDeclaration = findDeclaration; var stringWriter = createSingleLineStringWriter(); var stringWriterAcquired = false; function createSingleLineStringWriter() { @@ -6886,19 +6945,20 @@ var ts; sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective); } ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective; - /* @internal */ function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && - oldResolution.resolvedFileName === newResolution.resolvedFileName; + oldResolution.resolvedFileName === newResolution.resolvedFileName && + packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; - /* @internal */ + function packageIdIsEqual(a, b) { + return a === b || a && b && a.name === b.name && a.version === b.version; + } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo; - /* @internal */ function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) { ts.Debug.assert(names.length === newResolutions.length); for (var i = 0; i < names.length; i++) { @@ -6968,14 +7028,6 @@ var ts; return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; - function getStartPosOfNode(node) { - return node.pos; - } - ts.getStartPosOfNode = getStartPosOfNode; - function isDefined(value) { - return value !== undefined; - } - ts.isDefined = isDefined; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); @@ -7025,6 +7077,32 @@ var ts; return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; + /** + * Determine if the given comment is a triple-slash + * + * @return true if the comment is a triple-slash comment else false + */ + function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { + // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text + // so that we don't end up computing comment string and doing match for all // comments + if (text.charCodeAt(commentPos + 1) === 47 /* slash */ && + commentPos + 2 < commentEnd && + text.charCodeAt(commentPos + 2) === 47 /* slash */) { + var textSubStr = text.substring(commentPos, commentEnd); + return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || + textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || + textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || + textSubStr.match(defaultLibReferenceRegEx) ? + true : false; + } + return false; + } + ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; + function isPinnedComment(text, comment) { + return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && + text.charCodeAt(comment.pos + 2) === 33 /* exclamation */; + } + ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't* // want to skip trivia because this will launch us forward to the next token. @@ -7094,15 +7172,20 @@ var ts; // or a (possibly escaped) quoted form of the original text if it's string-like. switch (node.kind) { case 9 /* StringLiteral */: - return '"' + escapeText(node.text) + '"'; + if (node.singleQuote) { + return "'" + escapeText(node.text, 39 /* singleQuote */) + "'"; + } + else { + return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"'; + } case 13 /* NoSubstitutionTemplateLiteral */: - return "`" + escapeText(node.text) + "`"; + return "`" + escapeText(node.text, 96 /* backtick */) + "`"; case 14 /* TemplateHead */: - return "`" + escapeText(node.text) + "${"; + return "`" + escapeText(node.text, 96 /* backtick */) + "${"; case 15 /* TemplateMiddle */: - return "}" + escapeText(node.text) + "${"; + return "}" + escapeText(node.text, 96 /* backtick */) + "${"; case 16 /* TemplateTail */: - return "}" + escapeText(node.text) + "`"; + return "}" + escapeText(node.text, 96 /* backtick */) + "`"; case 8 /* NumericLiteral */: return node.text; } @@ -7191,6 +7274,7 @@ var ts; return ts.isExternalModule(node) || compilerOptions.isolatedModules; } ts.isEffectiveExternalModule = isEffectiveExternalModule; + /* @internal */ function isBlockScope(node, parentNode) { switch (node.kind) { case 265 /* SourceFile */: @@ -7384,10 +7468,6 @@ var ts; return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos); } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; - function getLeadingCommentRangesOfNodeFromText(node, text) { - return ts.getLeadingCommentRanges(text, node.pos); - } - ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 146 /* Parameter */ || node.kind === 145 /* TypeParameter */ || @@ -7395,7 +7475,7 @@ var ts; node.kind === 187 /* ArrowFunction */ || node.kind === 185 /* ParenthesizedExpression */) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); + ts.getLeadingCommentRanges(text, node.pos); // True if the comment starts with '/**' but not if it is '/**/' return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && @@ -7405,8 +7485,9 @@ var ts; } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; + var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; + var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (158 /* FirstTypeNode */ <= node.kind && node.kind <= 173 /* LastTypeNode */) { return true; @@ -7660,21 +7741,11 @@ var ts; } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { - while (true) { - node = node.parent; - if (!node || ts.isFunctionLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { - while (true) { - node = node.parent; - if (!node || ts.isClassLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { @@ -8570,14 +8641,14 @@ var ts; ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*/gim; + var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim"); if (simpleReferenceRegEx.test(comment)) { if (isNoDefaultLibRegEx.test(comment)) { return { isNoDefaultLib: true }; } else { var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment); - var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); var match = refMatchResult || refLibResult; if (match) { var pos = commentRange.pos + match[1].length + match[2].length; @@ -8782,10 +8853,6 @@ var ts; return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; - function getOriginalSourceFiles(sourceFiles) { - return ts.sameMap(sourceFiles, getOriginalSourceFile); - } - ts.getOriginalSourceFiles = getOriginalSourceFiles; var Associativity; (function (Associativity) { Associativity[Associativity["Left"] = 0] = "Left"; @@ -9029,7 +9096,9 @@ var ts; // the language service. These characters should be escaped when printing, and if any characters are added, // the map below must be updated. Note that this regexp *does not* include the 'delete' character. // There is no reason for this other than that JSON.stringify does not handle it either. - var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", @@ -9040,6 +9109,8 @@ var ts; "\n": "\\n", "\\": "\\\\", "\"": "\\\"", + "\'": "\\\'", + "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" // nextLine @@ -9049,7 +9120,10 @@ var ts; * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine) * Note that this doesn't actually wrap the input in double quotes. */ - function escapeString(s) { + function escapeString(s, quoteChar) { + var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp : + quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp : + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } ts.escapeString = escapeString; @@ -9069,8 +9143,8 @@ var ts; return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; - function escapeNonAsciiString(s) { - s = escapeString(s); + function escapeNonAsciiString(s, quoteChar) { + s = escapeString(s, quoteChar); // Replace non-ASCII characters with '\uNNNN' escapes if any exist. // Otherwise just return the original string. return nonAsciiCharacters.test(s) ? @@ -9455,7 +9529,7 @@ var ts; // // var x = 10; if (node.pos === 0) { - leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment); + leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { @@ -9495,9 +9569,8 @@ var ts; } } return currentDetachedCommentInfo; - function isPinnedComment(comment) { - return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && - text.charCodeAt(comment.pos + 2) === 33 /* exclamation */; + function isPinnedCommentLocal(comment) { + return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; @@ -9593,9 +9666,13 @@ var ts; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { - return (getModifierFlags(node) & flags) !== 0; + return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; + function getSelectedModifierFlags(node, flags) { + return getModifierFlags(node) & flags; + } + ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) { return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */; @@ -9673,23 +9750,6 @@ var ts; return false; } ts.isDestructuringAssignment = isDestructuringAssignment; - // Returns false if this heritage clause element's expression contains something unsupported - // (i.e. not a name or dotted name). - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 71 /* Identifier */) { - return true; - } - else if (ts.isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } - } function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } @@ -9816,78 +9876,6 @@ var ts; return carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; - /** - * Tests whether a node and its subtree is simple enough to have its position - * information ignored when emitting source maps in a destructuring assignment. - * - * @param node The expression to test. - */ - function isSimpleExpression(node) { - return isSimpleExpressionWorker(node, 0); - } - ts.isSimpleExpression = isSimpleExpression; - function isSimpleExpressionWorker(node, depth) { - if (depth <= 5) { - var kind = node.kind; - if (kind === 9 /* StringLiteral */ - || kind === 8 /* NumericLiteral */ - || kind === 12 /* RegularExpressionLiteral */ - || kind === 13 /* NoSubstitutionTemplateLiteral */ - || kind === 71 /* Identifier */ - || kind === 99 /* ThisKeyword */ - || kind === 97 /* SuperKeyword */ - || kind === 101 /* TrueKeyword */ - || kind === 86 /* FalseKeyword */ - || kind === 95 /* NullKeyword */) { - return true; - } - else if (kind === 179 /* PropertyAccessExpression */) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 180 /* ElementAccessExpression */) { - return isSimpleExpressionWorker(node.expression, depth + 1) - && isSimpleExpressionWorker(node.argumentExpression, depth + 1); - } - else if (kind === 192 /* PrefixUnaryExpression */ - || kind === 193 /* PostfixUnaryExpression */) { - return isSimpleExpressionWorker(node.operand, depth + 1); - } - else if (kind === 194 /* BinaryExpression */) { - return node.operatorToken.kind !== 40 /* AsteriskAsteriskToken */ - && isSimpleExpressionWorker(node.left, depth + 1) - && isSimpleExpressionWorker(node.right, depth + 1); - } - else if (kind === 195 /* ConditionalExpression */) { - return isSimpleExpressionWorker(node.condition, depth + 1) - && isSimpleExpressionWorker(node.whenTrue, depth + 1) - && isSimpleExpressionWorker(node.whenFalse, depth + 1); - } - else if (kind === 190 /* VoidExpression */ - || kind === 189 /* TypeOfExpression */ - || kind === 188 /* DeleteExpression */) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 177 /* ArrayLiteralExpression */) { - return node.elements.length === 0; - } - else if (kind === 178 /* ObjectLiteralExpression */) { - return node.properties.length === 0; - } - else if (kind === 181 /* CallExpression */) { - if (!isSimpleExpressionWorker(node.expression, depth + 1)) { - return false; - } - for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { - var argument = _a[_i]; - if (!isSimpleExpressionWorker(argument, depth + 1)) { - return false; - } - } - return true; - } - } - return false; - } /** * Formats an enum value as a string for debugging and debug assertions. */ @@ -9959,24 +9947,6 @@ var ts; return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true); } ts.formatObjectFlags = formatObjectFlags; - function getRangePos(range) { - return range ? range.pos : -1; - } - ts.getRangePos = getRangePos; - function getRangeEnd(range) { - return range ? range.end : -1; - } - ts.getRangeEnd = getRangeEnd; - /** - * Increases (or decreases) a position by the provided amount. - * - * @param pos The position. - * @param value The delta. - */ - function movePos(pos, value) { - return ts.positionIsSynthesized(pos) ? -1 : pos + value; - } - ts.movePos = movePos; /** * Creates a new TextRange from the provided pos and end. * @@ -10034,26 +10004,6 @@ var ts; return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; - /** - * Creates a new TextRange from a provided range with its end position collapsed to its - * start position. - * - * @param range A TextRange. - */ - function collapseRangeToStart(range) { - return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos); - } - ts.collapseRangeToStart = collapseRangeToStart; - /** - * Creates a new TextRange from a provided range with its start position collapsed to its - * end position. - * - * @param range A TextRange. - */ - function collapseRangeToEnd(range) { - return isCollapsedRange(range) ? range : moveRangePos(range, range.end); - } - ts.collapseRangeToEnd = collapseRangeToEnd; /** * Creates a new TextRange for a token at the provides start position. * @@ -10116,31 +10066,6 @@ var ts; function isInitializedVariable(node) { return node.initializer !== undefined; } - /** - * Gets a value indicating whether a node is merged with a class declaration in the same scope. - */ - function isMergedWithClass(node) { - if (node.symbol) { - for (var _i = 0, _a = node.symbol.declarations; _i < _a.length; _i++) { - var declaration = _a[_i]; - if (declaration.kind === 229 /* ClassDeclaration */ && declaration !== node) { - return true; - } - } - } - return false; - } - ts.isMergedWithClass = isMergedWithClass; - /** - * Gets a value indicating whether a node is the first declaration of its kind. - * - * @param node A Declaration node. - * @param kind The SyntaxKind to find among related declarations. - */ - function isFirstDeclarationOfKind(node, kind) { - return node.symbol && getDeclarationOfKind(node.symbol, kind) === node; - } - ts.isFirstDeclarationOfKind = isFirstDeclarationOfKind; function isWatchSet(options) { // Firefox has Object.prototype.watch return options.watch && options.hasOwnProperty("watch"); @@ -10434,6 +10359,20 @@ var ts; return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && node.parent.kind === 152 /* Constructor */ && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function isEmptyBindingPattern(node) { + if (ts.isBindingPattern(node)) { + return ts.every(node.elements, isEmptyBindingElement); + } + return false; + } + ts.isEmptyBindingPattern = isEmptyBindingPattern; + function isEmptyBindingElement(node) { + if (ts.isOmittedExpression(node)) { + return true; + } + return isEmptyBindingPattern(node.name); + } + ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 176 /* BindingElement */ || ts.isBindingPattern(node))) { node = node.parent; @@ -11618,6 +11557,19 @@ var ts; return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; + /* @internal */ + function isUnaryExpressionWithWrite(expr) { + switch (expr.kind) { + case 193 /* PostfixUnaryExpression */: + return true; + case 192 /* PrefixUnaryExpression */: + return expr.operator === 43 /* PlusPlusToken */ || + expr.operator === 44 /* MinusMinusToken */; + default: + return false; + } + } + ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; function isExpressionKind(kind) { return kind === 195 /* ConditionalExpression */ || kind === 197 /* YieldExpression */ @@ -11824,9 +11776,19 @@ var ts; var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) - || kind === 207 /* Block */; + || isBlockStatement(node); } ts.isStatement = isStatement; + function isBlockStatement(node) { + if (node.kind !== 207 /* Block */) + return false; + if (node.parent !== undefined) { + if (node.parent.kind === 224 /* TryStatement */ || node.parent.kind === 260 /* CatchClause */) { + return false; + } + } + return !ts.isFunctionBlock(node); + } // Module references /* @internal */ function isModuleReference(node) { @@ -14207,11 +14169,31 @@ var ts; var node = parseTokenNode(); return token() === 23 /* DotToken */ ? undefined : node; } - function parseLiteralTypeNode() { + function parseLiteralTypeNode(negative) { var node = createNode(173 /* LiteralType */); - node.literal = parseSimpleUnaryExpression(); - finishNode(node); - return node; + var unaryMinusExpression; + if (negative) { + unaryMinusExpression = createNode(192 /* PrefixUnaryExpression */); + unaryMinusExpression.operator = 38 /* MinusToken */; + nextToken(); + } + var expression; + switch (token()) { + case 9 /* StringLiteral */: + case 8 /* NumericLiteral */: + expression = parseLiteralLikeNode(token()); + break; + case 101 /* TrueKeyword */: + case 86 /* FalseKeyword */: + expression = parseTokenNode(); + } + if (negative) { + unaryMinusExpression.operand = expression; + finishNode(unaryMinusExpression); + expression = unaryMinusExpression; + } + node.literal = expression; + return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8 /* NumericLiteral */; @@ -14244,7 +14226,7 @@ var ts; case 86 /* FalseKeyword */: return parseLiteralTypeNode(); case 38 /* MinusToken */: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference(); + return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); case 105 /* VoidKeyword */: case 95 /* NullKeyword */: return parseTokenNode(); @@ -14293,6 +14275,7 @@ var ts; case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 134 /* ObjectKeyword */: + case 39 /* AsteriskToken */: return true; case 38 /* MinusToken */: return lookAhead(nextTokenIsNumericLiteral); @@ -14721,7 +14704,7 @@ var ts; // Didn't appear to actually be a parenthesized arrow function. Just bail out. return undefined; } - var isAsync = !!(ts.getModifierFlags(arrowFunction) & 256 /* Async */); + var isAsync = ts.hasModifier(arrowFunction, 256 /* Async */); // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. var lastToken = token(); @@ -14879,7 +14862,7 @@ var ts; function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNode(187 /* ArrowFunction */); node.modifiers = parseModifiersForArrowFunction(); - var isAsync = (ts.getModifierFlags(node) & 256 /* Async */) ? 2 /* Await */ : 0 /* None */; + var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; // Arrow functions are never generators. // // If we're speculatively parsing a signature for a parenthesized arrow function, then @@ -15890,7 +15873,7 @@ var ts; parseExpected(89 /* FunctionKeyword */); node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */); var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */; - var isAsync = (ts.getModifierFlags(node) & 256 /* Async */) ? 2 /* Await */ : 0 /* None */; + var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : @@ -16132,10 +16115,14 @@ var ts; function parseCatchClause() { var result = createNode(260 /* CatchClause */); parseExpected(74 /* CatchKeyword */); - if (parseExpected(19 /* OpenParenToken */)) { + if (parseOptional(19 /* OpenParenToken */)) { result.variableDeclaration = parseVariableDeclaration(); + parseExpected(20 /* CloseParenToken */); + } + else { + // Keep shape of node to avoid degrading performance. + result.variableDeclaration = undefined; } - parseExpected(20 /* CloseParenToken */); result.block = parseBlock(/*ignoreMissingOpenBrace*/ false); return finishNode(result); } @@ -17036,8 +17023,8 @@ var ts; // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; - if (identifier || - token() === 39 /* AsteriskToken */ || + if (identifier || // import id + token() === 39 /* AsteriskToken */ || // import * token() === 17 /* OpenBraceToken */) { importDeclaration.importClause = parseImportClause(identifier, afterImportPos); parseExpected(140 /* FromKeyword */); @@ -17345,7 +17332,7 @@ var ts; JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; function parseIsolatedJSDocComment(content, start, length) { initializeState(content, 5 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */); - sourceFile = { languageVariant: 0 /* Standard */, text: content }; + sourceFile = { languageVariant: 0 /* Standard */, text: content }; // tslint:disable-line no-object-literal-type-assertion var jsDoc = parseJSDocCommentWorker(start, length); var diagnostics = parseDiagnostics; clearState(); @@ -18093,8 +18080,8 @@ var ts; array._children = undefined; array.pos += delta; array.end += delta; - for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { - var node = array_9[_i]; + for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { + var node = array_8[_i]; visitNode(node); } } @@ -18231,8 +18218,8 @@ var ts; array._children = undefined; // Adjust the pos or end (or both) of the intersecting array accordingly. adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (var _i = 0, array_10 = array; _i < array_10.length; _i++) { - var node = array_10[_i]; + for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { + var node = array_9[_i]; visitNode(node); } return; @@ -19201,40 +19188,23 @@ var ts; return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: flags, - expression: expression, - antecedent: antecedent - }; + return { flags: flags, expression: expression, antecedent: antecedent }; } function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) { if (!isNarrowingExpression(switchStatement.expression)) { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: 128 /* SwitchClause */, - switchStatement: switchStatement, - clauseStart: clauseStart, - clauseEnd: clauseEnd, - antecedent: antecedent - }; + return { flags: 128 /* SwitchClause */, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent }; } function createFlowAssignment(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 16 /* Assignment */, - antecedent: antecedent, - node: node - }; + return { flags: 16 /* Assignment */, antecedent: antecedent, node: node }; } function createFlowArrayMutation(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 256 /* ArrayMutation */, - antecedent: antecedent, - node: node - }; + var res = { flags: 256 /* ArrayMutation */, antecedent: antecedent, node: node }; + return res; } function finishFlowLabel(flow) { var antecedents = flow.antecedents; @@ -20956,7 +20926,6 @@ var ts; } function computeParameter(node, subtreeFlags) { var transformFlags = subtreeFlags; - var modifierFlags = ts.getModifierFlags(node); var name = node.name; var initializer = node.initializer; var dotDotDotToken = node.dotDotDotToken; @@ -20969,7 +20938,7 @@ var ts; transformFlags |= 3 /* AssertTypeScript */; } // If a parameter has an accessibility modifier, then it is TypeScript syntax. - if (modifierFlags & 92 /* ParameterPropertyModifier */) { + if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { transformFlags |= 3 /* AssertTypeScript */ | 262144 /* ContainsParameterPropertyAssignments */; } // parameters with object rest destructuring are ES Next syntax @@ -21006,8 +20975,7 @@ var ts; } function computeClassDeclaration(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); - if (modifierFlags & 2 /* Ambient */) { + if (ts.hasModifier(node, 2 /* Ambient */)) { // An ambient declaration is TypeScript syntax. transformFlags = 3 /* AssertTypeScript */; } @@ -21068,7 +21036,10 @@ var ts; } function computeCatchClause(node, subtreeFlags) { var transformFlags = subtreeFlags; - if (node.variableDeclaration && ts.isBindingPattern(node.variableDeclaration.name)) { + if (!node.variableDeclaration) { + transformFlags |= 8 /* AssertESNext */; + } + else if (ts.isBindingPattern(node.variableDeclaration.name)) { transformFlags |= 192 /* AssertES2015 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; @@ -21283,10 +21254,9 @@ var ts; } function computeVariableStatement(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); var declarationListTransformFlags = node.declarationList.transformFlags; // An ambient declaration is TypeScript syntax. - if (modifierFlags & 2 /* Ambient */) { + if (ts.hasModifier(node, 2 /* Ambient */)) { transformFlags = 3 /* AssertTypeScript */; } else { @@ -21647,6 +21617,12 @@ var ts; return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; + function withPackageId(packageId, r) { + return r && { path: r.path, extension: r.ext, packageId: packageId }; + } + function noPackageId(r) { + return withPackageId(/*packageId*/ undefined, r); + } /** * Kinds of file that we are currently looking for. * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript. @@ -21667,13 +21643,12 @@ var ts; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { - resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport }, + resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } /** Reads from "main" or "types"/"typings" depending on `extensions`. */ - function tryReadPackageJsonFields(readTypes, packageJsonPath, baseDirectory, state) { - var jsonContent = readJson(packageJsonPath, state.host); + function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { @@ -21778,7 +21753,9 @@ var ts; } var resolvedTypeReferenceDirective; if (resolved) { - resolved = realpath(resolved, host, traceEnabled); + if (!options.preserveSymlinks) { + resolved = realpath(resolved, host, traceEnabled); + } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary); } @@ -22182,7 +22159,7 @@ var ts; if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); if (path_1 !== undefined) { - return { path: path_1, extension: extension }; + return { path: path_1, extension: extension, packageId: undefined }; } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); @@ -22209,7 +22186,7 @@ var ts; function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { - throw new Error("Could not resolve JS module " + moduleName + " starting at " + initialDir + ". Looked in: " + failedLookupLocations.join(", ")); + throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } @@ -22235,8 +22212,14 @@ var ts; trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); + if (!resolved_1) + return undefined; + var resolvedValue = resolved_1.value; + if (!compilerOptions.preserveSymlinks) { + resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); + } // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files. - return resolved_1 && { value: resolved_1.value && { resolved: { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }, isExternalLibraryImport: true } }; + return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); @@ -22271,7 +22254,7 @@ var ts; } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return resolvedFromFile; + return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { @@ -22291,6 +22274,9 @@ var ts; return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; + function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { + return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + } /** * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. @@ -22329,9 +22315,9 @@ var ts; case Extensions.JavaScript: return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */); } - function tryExtension(extension) { - var path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); - return path && { path: path, extension: extension }; + function tryExtension(ext) { + var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + return path && { path: path, ext: ext }; } } /** Return the file if it exists. */ @@ -22355,12 +22341,20 @@ var ts; function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); + var packageId; if (considerPackageJson) { var packageJsonPath = pathToPackageJson(candidate); if (directoryExists && state.host.fileExists(packageJsonPath)) { - var fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); + } + var jsonContent = readJson(packageJsonPath, state.host); + if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") { + packageId = { name: jsonContent.name, version: jsonContent.version }; + } + var fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { - return fromPackageJson; + return withPackageId(packageId, fromPackageJson); } } else { @@ -22371,13 +22365,10 @@ var ts; failedLookupLocations.push(packageJsonPath); } } - return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return withPackageId(packageId, loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state)); } - function loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); - } - var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { + var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } @@ -22395,12 +22386,17 @@ var ts; // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types" var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; // Don't do package.json lookup recursively, because Node.js' package lookup doesn't. - return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); + var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); + if (result) { + // It won't have a `packageId` set, because we disabled `considerPackageJson`. + ts.Debug.assert(result.packageId === undefined); + return { path: result.path, ext: result.extension }; + } } /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ function resolvedIfExtensionMatches(extensions, path) { - var extension = ts.tryGetExtensionFromPath(path); - return extension !== undefined && extensionIsOk(extensions, extension) ? { path: path, extension: extension } : undefined; + var ext = ts.tryGetExtensionFromPath(path); + return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } /** True if `extension` is one of the supported `extensions`. */ function extensionIsOk(extensions, extension) { @@ -22418,7 +22414,7 @@ var ts; } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || + return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { @@ -22497,7 +22493,7 @@ var ts; if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { @@ -22508,7 +22504,7 @@ var ts; var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations); function tryResolve(extensions) { - var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); + var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -22521,7 +22517,7 @@ var ts; return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); }); if (resolved_3) { return resolved_3; @@ -22533,7 +22529,7 @@ var ts; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); } } } @@ -22789,11 +22785,10 @@ var ts; getSuggestionForNonexistentProperty: function (node, type) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentProperty(node, type)); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning)); }, getBaseConstraintOfType: getBaseConstraintOfType, - getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, - resolveNameAtLocation: function (location, name, meaning) { - location = ts.getParseTreeNode(location); - return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, ts.escapeLeadingUnderscores(name)); + resolveName: function (name, location, meaning) { + return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); }, + getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, }; var tupleTypes = []; var unionTypes = ts.createMap(); @@ -23360,13 +23355,13 @@ var ts; current.parent.kind === 149 /* PropertyDeclaration */ && current.parent.initializer === current; if (initializerOfProperty) { - if (ts.getModifierFlags(current.parent) & 32 /* Static */) { + if (ts.hasModifier(current.parent, 32 /* Static */)) { if (declaration.kind === 151 /* MethodDeclaration */) { return true; } } else { - var isDeclarationInstanceProperty = declaration.kind === 149 /* PropertyDeclaration */ && !(ts.getModifierFlags(declaration) & 32 /* Static */); + var isDeclarationInstanceProperty = declaration.kind === 149 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */); if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } @@ -23480,7 +23475,7 @@ var ts; // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. - if (ts.isClassLike(location.parent) && !(ts.getModifierFlags(location) & 32 /* Static */)) { + if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32 /* Static */)) { var ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & 107455 /* Value */)) { @@ -23499,7 +23494,7 @@ var ts; result = undefined; break; } - if (lastLocation && ts.getModifierFlags(lastLocation) & 32 /* Static */) { + if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. @@ -23585,7 +23580,10 @@ var ts; lastLocation = location; location = location.parent; } - if (result && nameNotFoundMessage && noUnusedIdentifiers) { + // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. + // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself. + // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. + if (result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) { result.isReferenced = true; } if (!result) { @@ -23684,7 +23682,7 @@ var ts; } // No static member is present. // Check if we're in an instance method and look for a relevant instance member. - if (location === container && !(ts.getModifierFlags(location) & 32 /* Static */)) { + if (location === container && !ts.hasModifier(location, 32 /* Static */)) { var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -24186,7 +24184,7 @@ var ts; // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, // and an external module with no 'export =' declaration resolves to the module itself. function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) { - return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="), dontResolveAlias)) || moduleSymbol; + return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias)) || moduleSymbol; } // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export =' // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may @@ -24199,7 +24197,7 @@ var ts; return symbol; } function hasExportAssignmentSymbol(moduleSymbol) { - return moduleSymbol.exports.get("export=") !== undefined; + return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined; } function getExportsOfModuleAsArray(moduleSymbol) { return symbolsToArray(getExportsOfModule(moduleSymbol)); @@ -24461,7 +24459,7 @@ var ts; if (symbolFromSymbolTable.flags & 2097152 /* Alias */ && symbolFromSymbolTable.escapedName !== "export=" && !ts.getDeclarationOfKind(symbolFromSymbolTable, 246 /* ExportSpecifier */)) { - if (!useOnlyExternalAliasing || + if (!useOnlyExternalAliasing || // We can use any type of alias to get the name // Is this external alias, then use it to name ts.forEach(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration)) { var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable); @@ -24526,6 +24524,10 @@ var ts; } return false; } + function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) { + var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false); + return access.accessibility === 0 /* Accessible */; + } /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * @@ -24608,7 +24610,7 @@ var ts; // because these kind of aliases can be used to name types in declaration file var anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(ts.getModifierFlags(anyImportSyntax) & 1 /* Export */) && + !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types, // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time @@ -24817,8 +24819,7 @@ var ts; // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); } - if (!inTypeAlias && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === 0 /* Accessible */) { + if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { var name = symbolToTypeReferenceName(type.aliasSymbol); var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return ts.createTypeReferenceNode(name, typeArgumentNodes); @@ -24900,10 +24901,10 @@ var ts; return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */ && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32 /* Static */; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) && - (symbol.parent || + (symbol.parent || // is exported function symbol ts.forEach(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */; })); @@ -24914,10 +24915,8 @@ var ts; } } function createTypeNodeFromObjectType(type) { - if (type.objectFlags & 32 /* Mapped */) { - if (getConstraintTypeFromMappedType(type).flags & (16384 /* TypeParameter */ | 262144 /* Index */)) { - return createMappedTypeNodeFromType(type); - } + if (isGenericMappedType(type)) { + return createMappedTypeNodeFromType(type); } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -25505,7 +25504,7 @@ var ts; buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags); } else if (!(flags & 1024 /* InTypeAlias */) && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === 0 /* Accessible */) { + ((flags & 65536 /* UseAliasDefinedOutsideCurrentScope */) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { var typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags); } @@ -25667,9 +25666,7 @@ var ts; if (!symbolStack) { symbolStack = []; } - var isConstructorObject = type.flags & 32768 /* Object */ && - getObjectFlags(type) & 16 /* Anonymous */ && - type.symbol && type.symbol.flags & 32 /* Class */; + var isConstructorObject = type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */; if (isConstructorObject) { writeLiteralType(type, flags); } @@ -25685,17 +25682,17 @@ var ts; writeLiteralType(type, flags); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */ && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32 /* Static */; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) && - (symbol.parent || - ts.forEach(symbol.declarations, function (declaration) { + (symbol.parent || // is exported function symbol + ts.some(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return !!(flags & 4 /* UseTypeOfFunction */) || - (ts.contains(symbolStack, symbol)); // it is type of the symbol uses itself recursively + return !!(flags & 4 /* UseTypeOfFunction */) || // use typeof if format flags specify it + ts.contains(symbolStack, symbol); // it is type of the symbol uses itself recursively } } } @@ -25733,11 +25730,9 @@ var ts; return false; } function writeLiteralType(type, flags) { - if (type.objectFlags & 32 /* Mapped */) { - if (getConstraintTypeFromMappedType(type).flags & (16384 /* TypeParameter */ | 262144 /* Index */)) { - writeMappedType(type); - return; - } + if (isGenericMappedType(type)) { + writeMappedType(type); + return; } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -26113,7 +26108,7 @@ var ts; case 154 /* SetAccessor */: case 151 /* MethodDeclaration */: case 150 /* MethodSignature */: - if (ts.getModifierFlags(node) & (8 /* Private */ | 16 /* Protected */)) { + if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) { // Private/protected properties/methods are not visible return false; } @@ -26910,8 +26905,8 @@ var ts; // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set // in-place and returns the same array. function appendTypeParameters(typeParameters, declarations) { - for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { - var declaration = declarations_3[_i]; + for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { + var declaration = declarations_2[_i]; var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); if (!typeParameters) { typeParameters = [tp]; @@ -27221,7 +27216,9 @@ var ts; if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) { return unknownType; } - var declaration = ts.findDeclaration(symbol, function (d) { return d.kind === 283 /* JSDocTypedefTag */ || d.kind === 231 /* TypeAliasDeclaration */; }); + var declaration = ts.find(symbol.declarations, function (d) { + return d.kind === 283 /* JSDocTypedefTag */ || d.kind === 231 /* TypeAliasDeclaration */; + }); var type = getTypeFromTypeNode(declaration.kind === 283 /* JSDocTypedefTag */ ? declaration.typeExpression : declaration.type); if (popTypeResolution()) { var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -27883,8 +27880,7 @@ var ts; return getObjectFlags(type) & 32 /* Mapped */ && !!type.declaration.questionToken; } function isGenericMappedType(type) { - return getObjectFlags(type) & 32 /* Mapped */ && - maybeTypeOfKind(getConstraintTypeFromMappedType(type), 540672 /* TypeVariable */ | 262144 /* Index */); + return getObjectFlags(type) & 32 /* Mapped */ && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type) { if (!type.members) { @@ -27990,6 +27986,10 @@ var ts; return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } function getConstraintOfIndexedAccess(type) { + var transformed = getTransformedIndexedAccessType(type); + if (transformed) { + return transformed; + } var baseObjectType = getBaseConstraintOfType(type.objectType); var baseIndexType = getBaseConstraintOfType(type.indexType); return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; @@ -28057,11 +28057,18 @@ var ts; return stringType; } if (t.flags & 524288 /* IndexedAccess */) { + var transformed = getTransformedIndexedAccessType(t); + if (transformed) { + return getBaseConstraint(transformed); + } var baseObjectType = getBaseConstraint(t.objectType); var baseIndexType = getBaseConstraint(t.indexType); var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (isGenericMappedType(t)) { + return emptyObjectType; + } return t; } } @@ -28680,7 +28687,7 @@ var ts; function getIndexInfoOfSymbol(symbol, kind) { var declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, (ts.getModifierFlags(declaration) & 64 /* Readonly */) !== 0, declaration); + return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration); } return undefined; } @@ -28978,8 +28985,8 @@ var ts; function getTypeOfGlobalSymbol(symbol, arity) { function getTypeDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { - var declaration = declarations_4[_i]; + for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { + var declaration = declarations_3[_i]; switch (declaration.kind) { case 229 /* ClassDeclaration */: case 230 /* InterfaceDeclaration */: @@ -29475,11 +29482,11 @@ var ts; return getTypeOfSymbol(prop); } } - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */)) { + if (!(indexType.flags & 6144 /* Nullable */) && isTypeAssignableToKind(indexType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */)) { if (isTypeAny(objectType)) { return anyType; } - var indexInfo = isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || + var indexInfo = isTypeAssignableToKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || getIndexInfoOfType(objectType, 0 /* String */) || undefined; if (indexInfo) { @@ -29517,35 +29524,85 @@ var ts; return anyType; } function getIndexedAccessForMappedType(type, indexType, accessNode) { - var accessExpression = accessNode && accessNode.kind === 180 /* ElementAccessExpression */ ? accessNode : undefined; - if (accessExpression && ts.isAssignmentTarget(accessExpression) && type.declaration.readonlyToken) { - error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); - return unknownType; + if (accessNode) { + // Check if the index type is assignable to 'keyof T' for the object type. + if (!isTypeAssignableTo(indexType, getIndexType(type))) { + error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(type)); + return unknownType; + } + if (accessNode.kind === 180 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) && type.declaration.readonlyToken) { + error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); + return unknownType; + } } var mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]); var templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; return instantiateType(getTemplateTypeFromMappedType(type), templateMapper); } + function isGenericObjectType(type) { + return type.flags & 540672 /* TypeVariable */ ? true : + getObjectFlags(type) & 32 /* Mapped */ ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : + type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericObjectType) : + false; + } + function isGenericIndexType(type) { + return type.flags & (540672 /* TypeVariable */ | 262144 /* Index */) ? true : + type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericIndexType) : + false; + } + // Return true if the given type is a non-generic object type with a string index signature and no + // other members. + function isStringIndexOnlyType(type) { + if (type.flags & 32768 /* Object */ && !isGenericMappedType(type)) { + var t = resolveStructuredTypeMembers(type); + return t.properties.length === 0 && + t.callSignatures.length === 0 && t.constructSignatures.length === 0 && + t.stringIndexInfo && !t.numberIndexInfo; + } + return false; + } + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a + // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed + // access types with default property values as expressed by D. + function getTransformedIndexedAccessType(type) { + var objectType = type.objectType; + if (objectType.flags & 131072 /* Intersection */ && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) { + var regularTypes = []; + var stringIndexTypes = []; + for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, 0 /* String */)); + } + else { + regularTypes.push(t); + } + } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + return undefined; + } function getIndexedAccessType(objectType, indexType, accessNode) { - // If the index type is generic, if the object type is generic and doesn't originate in an expression, - // or if the object type is a mapped type with a generic constraint, we are performing a higher-order - // index access where we cannot meaningfully access the properties of the object type. Note that for a - // generic T and a non-generic K, we eagerly resolve T[K] if it originates in an expression. This is to - // preserve backwards compatibility. For example, an element access 'this["foo"]' has always been resolved - // eagerly using the constraint type of 'this' at the given location. - if (maybeTypeOfKind(indexType, 540672 /* TypeVariable */ | 262144 /* Index */) || - maybeTypeOfKind(objectType, 540672 /* TypeVariable */) && !(accessNode && accessNode.kind === 180 /* ElementAccessExpression */) || - isGenericMappedType(objectType)) { + // If the object type is a mapped type { [P in K]: E }, where K is generic, we instantiate E using a mapper + // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we + // construct the type Box. + if (isGenericMappedType(objectType)) { + return getIndexedAccessForMappedType(objectType, indexType, accessNode); + } + // Otherwise, if the index type is generic, or if the object type is generic and doesn't originate in an + // expression, we are performing a higher-order index access where we cannot meaningfully access the properties + // of the object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates + // in an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]' + // has always been resolved eagerly using the constraint type of 'this' at the given location. + if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180 /* ElementAccessExpression */) && isGenericObjectType(objectType)) { if (objectType.flags & 1 /* Any */) { return objectType; } - // If the object type is a mapped type { [P in K]: E }, we instantiate E using a mapper that substitutes - // the index type for P. For example, for an index access { [P in K]: Box }[X], we construct the - // type Box. - if (isGenericMappedType(objectType)) { - return getIndexedAccessForMappedType(objectType, indexType, accessNode); - } - // Otherwise we defer the operation by creating an indexed access type. + // Defer the operation by creating an indexed access type. var id = objectType.id + "," + indexType.id; var type = indexedAccessTypes.get(id); if (!type) { @@ -29759,7 +29816,7 @@ var ts; var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); var parent = container && container.parent; if (parent && (ts.isClassLike(parent) || parent.kind === 230 /* InterfaceDeclaration */)) { - if (!(ts.getModifierFlags(container) & 32 /* Static */) && + if (!ts.hasModifier(container, 32 /* Static */) && (container.kind !== 152 /* Constructor */ || ts.isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } @@ -29912,7 +29969,7 @@ var ts; } function cloneTypeMapper(mapper) { return mapper && isInferenceContext(mapper) ? - createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.inferences) : + createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.compareTypes, mapper.inferences) : mapper; } function identityMapper(type) { @@ -30222,16 +30279,16 @@ var ts; if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) { return true; } - // For arrow functions we now know we're not context sensitive. - if (node.kind === 187 /* ArrowFunction */) { - return false; + if (node.kind !== 187 /* ArrowFunction */) { + // If the first parameter is not an explicit 'this' parameter, then the function has + // an implicit 'this' parameter which is subject to contextual typing. + var parameter = ts.firstOrUndefined(node.parameters); + if (!(parameter && ts.parameterIsThisKeyword(parameter))) { + return true; + } } - // 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. - var parameter = ts.firstOrUndefined(node.parameters); - return !(parameter && ts.parameterIsThisKeyword(parameter)); + // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value. + return node.body.kind === 207 /* Block */ ? false : isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func) { return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); @@ -30317,7 +30374,7 @@ var ts; return 0 /* False */; } if (source.typeParameters) { - source = instantiateSignatureInContextOf(source, target); + source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } var result = -1 /* True */; var sourceThisType = getThisTypeOfSignature(source); @@ -30376,7 +30433,7 @@ var ts; // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions if (target.typePredicate) { if (source.typePredicate) { - result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes); + result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes); } else if (ts.isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { @@ -30395,7 +30452,7 @@ var ts; } return result; } - function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) { + function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) { if (source.kind !== target.kind) { if (reportErrors) { errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); @@ -30404,11 +30461,13 @@ var ts; return 0 /* False */; } if (source.kind === 1 /* Identifier */) { - var sourceIdentifierPredicate = source; - var targetIdentifierPredicate = target; - if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + var sourcePredicate = source; + var targetPredicate = target; + var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0); + var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0); + if (sourceIndex !== targetIndex) { if (reportErrors) { - errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0 /* False */; @@ -30697,11 +30756,21 @@ var ts; !(target.flags & 65536 /* Union */) && !isIntersectionConstituent && source !== globalObjectType && - getPropertiesOfType(source).length > 0 && + (getPropertiesOfType(source).length > 0 || + getSignaturesOfType(source, 0 /* Call */).length > 0 || + getSignaturesOfType(source, 1 /* Construct */).length > 0) && isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { - reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + var calls = getSignaturesOfType(source, 0 /* Call */); + var constructs = getSignaturesOfType(source, 1 /* Construct */); + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) { + reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target)); + } + else { + reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + } } return 0 /* False */; } @@ -31411,6 +31480,11 @@ var ts; if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } + if (isGenericMappedType(source)) { + // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U } + // if T is related to U. + return kind === 0 /* String */ && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); + } if (isObjectLiteralType(source)) { var related = -1 /* True */; if (kind === 0 /* String */) { @@ -31444,8 +31518,8 @@ var ts; if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } - var sourceAccessibility = ts.getModifierFlags(sourceSignature.declaration) & 24 /* NonPublicAccessibilityModifier */; - var targetAccessibility = ts.getModifierFlags(targetSignature.declaration) & 24 /* NonPublicAccessibilityModifier */; + var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */); + var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */); // A public, protected and private signature is assignable to a private signature. if (targetAccessibility === 8 /* Private */) { return true; @@ -31509,7 +31583,7 @@ var ts; var symbol = type.symbol; if (symbol && symbol.flags & 32 /* Class */) { var declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && ts.getModifierFlags(declaration) & 128 /* Abstract */) { + if (declaration && ts.hasModifier(declaration, 128 /* Abstract */)) { return true; } } @@ -31960,13 +32034,14 @@ var ts; callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } } - function createInferenceContext(signature, flags, baseInferences) { + function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; + context.compareTypes = compareTypes || compareTypesAssignable; return context; function mapper(t) { for (var i = 0; i < inferences.length; i++) { @@ -32061,6 +32136,19 @@ var ts; return inference.candidates && getUnionType(inference.candidates, /*subtypeReduction*/ true); } } + function isPossiblyAssignableTo(source, target) { + var properties = getPropertiesOfObjectType(target); + for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { + var targetProp = properties_5[_i]; + if (!(targetProp.flags & (16777216 /* Optional */ | 4194304 /* Prototype */))) { + var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); + if (!sourceProp) { + return false; + } + } + } + return true; + } function inferTypes(inferences, originalSource, originalTarget, priority) { if (priority === void 0) { priority = 0; } var symbolStack; @@ -32257,15 +32345,19 @@ var ts; return; } } - inferFromProperties(source, target); - inferFromSignatures(source, target, 0 /* Call */); - inferFromSignatures(source, target, 1 /* Construct */); - inferFromIndexTypes(source, target); + // Infer from the members of source and target only if the two types are possibly related. We check + // in both directions because we may be inferring for a co-variant or a contra-variant position. + if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) { + inferFromProperties(source, target); + inferFromSignatures(source, target, 0 /* Call */); + inferFromSignatures(source, target, 1 /* Construct */); + inferFromIndexTypes(source, target); + } } function inferFromProperties(source, target) { var properties = getPropertiesOfObjectType(target); - for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { - var targetProp = properties_5[_i]; + for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { + var targetProp = properties_6[_i]; var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); if (sourceProp) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); @@ -32382,7 +32474,7 @@ var ts; var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); if (constraint) { var instantiatedConstraint = instantiateType(constraint, context); - if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } @@ -32440,16 +32532,6 @@ var ts; } return undefined; } - function getLeftmostIdentifierOrThis(node) { - switch (node.kind) { - case 71 /* Identifier */: - case 99 /* ThisKeyword */: - return node; - case 179 /* PropertyAccessExpression */: - return getLeftmostIdentifierOrThis(node.expression); - } - return undefined; - } function getBindingElementNameText(element) { if (element.parent.kind === 174 /* ObjectBindingPattern */) { var name = element.propertyName || element.name; @@ -32975,7 +33057,7 @@ var ts; parent.parent.operatorToken.kind === 58 /* EqualsToken */ && parent.parent.left === parent && !ts.isAssignmentTarget(parent.parent) && - isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */ | 2048 /* Undefined */); + isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */); return isLengthPushOrUnshift || isElementAssignment; } function maybeTypePredicateCall(node) { @@ -33143,7 +33225,7 @@ var ts; } else { var indexType = getTypeOfExpression(node.left.argumentExpression); - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 /* NumberLike */ | 2048 /* Undefined */)) { + if (isTypeAssignableToKind(indexType, 84 /* NumberLike */)) { evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right); } } @@ -33978,7 +34060,7 @@ var ts; break; case 149 /* PropertyDeclaration */: case 148 /* PropertySignature */: - if (ts.getModifierFlags(container) & 32 /* Static */) { + if (ts.hasModifier(container, 32 /* Static */)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } @@ -34081,7 +34163,7 @@ var ts; if (!isCallExpression && container.kind === 152 /* Constructor */) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if ((ts.getModifierFlags(container) & 32 /* Static */) || isCallExpression) { + if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) { nodeCheckFlag = 512 /* SuperStatic */; } else { @@ -34144,7 +34226,7 @@ var ts; // This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set. // This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment // while a property access can. - if (container.kind === 151 /* MethodDeclaration */ && ts.getModifierFlags(container) & 256 /* Async */) { + if (container.kind === 151 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) { if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */; } @@ -34202,7 +34284,7 @@ var ts; // - In a static member function or static member accessor // topmost container must be something that is directly nested in the class declaration\object literal expression if (ts.isClassLike(container.parent) || container.parent.kind === 178 /* ObjectLiteralExpression */) { - if (ts.getModifierFlags(container) & 32 /* Static */) { + if (ts.hasModifier(container, 32 /* Static */)) { return container.kind === 151 /* MethodDeclaration */ || container.kind === 150 /* MethodSignature */ || container.kind === 153 /* GetAccessor */ || @@ -34832,10 +34914,7 @@ var ts; function isNumericComputedName(name) { // It seems odd to consider an expression of type Any to result in a numeric name, // but this behavior is consistent with checkIndexedAccess - return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), 84 /* NumberLike */); - } - function isTypeAnyOrAllConstituentTypesHaveKind(type, kind) { - return isTypeAny(type) || isTypeOfKind(type, kind); + return isTypeAssignableToKind(checkComputedPropertyName(name), 84 /* NumberLike */); } function isInfinityOrNaNString(name) { return name === "Infinity" || name === "-Infinity" || name === "NaN"; @@ -34870,7 +34949,9 @@ var ts; links.resolvedType = checkExpression(node.expression); // This will allow types number, string, symbol or any. It will also allow enums, the unknown // type, and any union of these types (like string | number). - if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 84 /* NumberLike */ | 262178 /* StringLike */ | 512 /* ESSymbol */)) { + if (links.resolvedType.flags & 6144 /* Nullable */ || + !isTypeAssignableToKind(links.resolvedType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */) && + !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -35484,9 +35565,7 @@ var ts; * emptyObjectType if there is no "prop" in the element instance type */ function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) { - if (!elementType) { - elementType = checkExpression(openingLikeElement.tagName); - } + if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); } if (elementType.flags & 65536 /* Union */) { var types = elementType.types; return getUnionType(types.map(function (type) { @@ -35607,11 +35686,12 @@ var ts; */ function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) { var links = getNodeLinks(node); - if (!links.resolvedJsxElementAttributesType) { + var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { var elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); } - return links.resolvedJsxElementAttributesType; + return links[linkLocation]; } /** * Get all possible attributes type, especially from an overload stateless function component, of the given JSX opening-like element. @@ -36084,7 +36164,7 @@ var ts; if (prop && noUnusedIdentifiers && (prop.flags & 106500 /* ClassMember */) && - prop.valueDeclaration && (ts.getModifierFlags(prop.valueDeclaration) & 8 /* Private */)) { + prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8 /* Private */)) { if (ts.getCheckFlags(prop) & 1 /* Instantiated */) { getSymbolLinks(prop).target.isReferenced = true; } @@ -36407,8 +36487,8 @@ var ts; return undefined; } // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec) - function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper) { - var context = createInferenceContext(signature, 1 /* InferUnionTypes */); + function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) { + var context = createInferenceContext(signature, 1 /* InferUnionTypes */, compareTypes); forEachMatchingParameterType(contextualSignature, signature, function (source, target) { // Type parameters from outer context referenced by source type are fixed by instantiation of the source type inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); @@ -36780,7 +36860,7 @@ var ts; return getLiteralType(element.name.text); case 144 /* ComputedPropertyName */: var nameType = checkComputedPropertyName(element.name); - if (isTypeOfKind(nameType, 512 /* ESSymbol */)) { + if (isTypeAssignableToKind(nameType, 512 /* ESSymbol */)) { return nameType; } else { @@ -36921,9 +37001,10 @@ var ts; // // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. + var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; var excludeArgument; var excludeCount = 0; - if (!isDecorator) { + if (!isDecorator && !isSingleNonGenericCandidate) { // We do not need to call `getEffectiveArgumentCount` here as it only // applies when calculating the number of arguments for a decorator. for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { @@ -37068,6 +37149,17 @@ var ts; if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; + if (isSingleNonGenericCandidate) { + var candidate = candidates[0]; + if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + return undefined; + } + if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { + candidateForArgumentError = candidate; + return undefined; + } + return candidate; + } for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { var originalCandidate = candidates[candidateIndex]; if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { @@ -37230,7 +37322,7 @@ var ts; // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && ts.getModifierFlags(valueDecl) & 128 /* Abstract */) { + if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) { error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -37277,9 +37369,9 @@ var ts; return true; } var declaration = signature.declaration; - var modifiers = ts.getModifierFlags(declaration); + var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */); // Public constructor is accessible. - if (!(modifiers & 24 /* NonPublicAccessibilityModifier */)) { + if (!modifiers) { return true; } var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); @@ -37546,11 +37638,33 @@ var ts; if (moduleSymbol) { var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); } } return createPromiseReturnType(node, anyType); } + function getTypeWithSyntheticDefaultImportType(type, symbol) { + if (allowSyntheticDefaultImports && type && type !== unknownType) { + var synthType = type; + if (!synthType.syntheticType) { + if (!getPropertyOfType(type, "default" /* Default */)) { + var memberTable = ts.createSymbolTable(); + var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */); + newSymbol.target = resolveSymbol(symbol); + memberTable.set("default" /* Default */, newSymbol); + var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */); + var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + anonymousSymbol.type = defaultContainingObject; + synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + } + else { + synthType.syntheticType = type; + } + } + return synthType.syntheticType; + } + return type; + } function isCommonJsRequire(node) { if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { return false; @@ -37675,15 +37789,15 @@ var ts; } // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push // the destructured type into the contained binding elements. - function assignBindingElementTypes(node) { - if (ts.isBindingPattern(node.name)) { - for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) { - var element = _a[_i]; - if (!ts.isOmittedExpression(element)) { - if (element.name.kind === 71 /* Identifier */) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); - } - assignBindingElementTypes(element); + function assignBindingElementTypes(pattern) { + for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (!ts.isOmittedExpression(element)) { + if (element.name.kind === 71 /* Identifier */) { + getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + } + else { + assignBindingElementTypes(element.name); } } } @@ -37692,13 +37806,14 @@ var ts; var links = getSymbolLinks(parameter); if (!links.type) { links.type = contextualType; - var name = ts.getNameOfDeclaration(parameter.valueDeclaration); - // if inference didn't come up with anything but {}, fall back to the binding pattern if present. - if (links.type === emptyObjectType && - (name.kind === 174 /* ObjectBindingPattern */ || name.kind === 175 /* ArrayBindingPattern */)) { - links.type = getTypeFromBindingPattern(name); + var decl = parameter.valueDeclaration; + if (decl.name.kind !== 71 /* Identifier */) { + // if inference didn't come up with anything but {}, fall back to the binding pattern if present. + if (links.type === emptyObjectType) { + links.type = getTypeFromBindingPattern(decl.name); + } + assignBindingElementTypes(decl.name); } - assignBindingElementTypes(parameter.valueDeclaration); } } function createPromiseType(promisedType) { @@ -37934,16 +38049,16 @@ var ts; } function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) { ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node)); - // Grammar checking - var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); - if (!hasGrammarError && node.kind === 186 /* FunctionExpression */) { - checkGrammarForGenerator(node); - } // The identityMapper object is used to indicate that function expressions are wildcards if (checkMode === 1 /* SkipContextSensitive */ && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } + // Grammar checking + var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); + if (!hasGrammarError && node.kind === 186 /* FunctionExpression */) { + checkGrammarForGenerator(node); + } var links = getNodeLinks(node); var type = getTypeOfSymbol(node.symbol); // Check if function expression is contextually typed and assign parameter types if so. @@ -38028,7 +38143,7 @@ var ts; } } function checkArithmeticOperandType(operand, type, diagnostic) { - if (!isTypeAnyOrAllConstituentTypesHaveKind(type, 84 /* NumberLike */)) { + if (!isTypeAssignableToKind(type, 84 /* NumberLike */)) { error(operand, diagnostic); return false; } @@ -38129,8 +38244,13 @@ var ts; if (operandType === silentNeverType) { return silentNeverType; } - if (node.operator === 38 /* MinusToken */ && node.operand.kind === 8 /* NumericLiteral */) { - return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + if (node.operand.kind === 8 /* NumericLiteral */) { + if (node.operator === 38 /* MinusToken */) { + return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + } + else if (node.operator === 37 /* PlusToken */) { + return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text)); + } } switch (node.operator) { case 37 /* PlusToken */: @@ -38186,33 +38306,22 @@ var ts; } return false; } - // Return true if type is of the given kind. A union type is of a given kind if all constituent types - // are of the given kind. An intersection type is of a given kind if at least one constituent type is - // of the given kind. - function isTypeOfKind(type, kind) { - if (type.flags & kind) { - return true; - } - if (type.flags & 65536 /* Union */) { - var types = type.types; - for (var _i = 0, types_18 = types; _i < types_18.length; _i++) { - var t = types_18[_i]; - if (!isTypeOfKind(t, kind)) { - return false; - } - } + function isTypeAssignableToKind(source, kind, strict) { + if (source.flags & kind) { return true; } - if (type.flags & 131072 /* Intersection */) { - var types = type.types; - for (var _a = 0, types_19 = types; _a < types_19.length; _a++) { - var t = types_19[_a]; - if (isTypeOfKind(t, kind)) { - return true; - } - } + if (strict && source.flags & (1 /* Any */ | 1024 /* Void */ | 2048 /* Undefined */ | 4096 /* Null */)) { + return false; } - return false; + return (kind & 84 /* NumberLike */ && isTypeAssignableTo(source, numberType)) || + (kind & 262178 /* StringLike */ && isTypeAssignableTo(source, stringType)) || + (kind & 136 /* BooleanLike */ && isTypeAssignableTo(source, booleanType)) || + (kind & 1024 /* Void */ && isTypeAssignableTo(source, voidType)) || + (kind & 8192 /* Never */ && isTypeAssignableTo(source, neverType)) || + (kind & 4096 /* Null */ && isTypeAssignableTo(source, nullType)) || + (kind & 2048 /* Undefined */ && isTypeAssignableTo(source, undefinedType)) || + (kind & 512 /* ESSymbol */ && isTypeAssignableTo(source, esSymbolType)) || + (kind & 16777216 /* NonPrimitive */ && isTypeAssignableTo(source, nonPrimitiveType)); } function isConstEnumObjectType(type) { return getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && isConstEnumSymbol(type.symbol); @@ -38229,7 +38338,7 @@ var ts; // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature. // The result is always of the Boolean primitive type. // NOTE: do not raise error if leftType is unknown as related error was already reported - if (isTypeOfKind(leftType, 8190 /* Primitive */)) { + if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190 /* Primitive */)) { error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } // NOTE: do not raise error if right is unknown as related error was already reported @@ -38251,18 +38360,18 @@ var ts; // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, // and the right operand to be of type Any, an object type, or a type parameter type. // The result is always of the Boolean primitive type. - if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, 84 /* NumberLike */ | 512 /* ESSymbol */))) { + if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 /* NumberLike */ | 512 /* ESSymbol */))) { error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 /* Object */ | 540672 /* TypeVariable */ | 16777216 /* NonPrimitive */)) { + if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) { error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; } function checkObjectLiteralAssignment(node, sourceType) { var properties = node.properties; - for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { - var p = properties_6[_i]; + for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) { + var p = properties_7[_i]; checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties); } return sourceType; @@ -38541,30 +38650,28 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (!isTypeOfKind(leftType, 1 /* Any */ | 262178 /* StringLike */) && !isTypeOfKind(rightType, 1 /* Any */ | 262178 /* StringLike */)) { + if (!isTypeAssignableToKind(leftType, 262178 /* StringLike */) && !isTypeAssignableToKind(rightType, 262178 /* StringLike */)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } var resultType = void 0; - if (isTypeOfKind(leftType, 84 /* NumberLike */) && isTypeOfKind(rightType, 84 /* NumberLike */)) { + if (isTypeAssignableToKind(leftType, 84 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 84 /* NumberLike */, /*strict*/ true)) { // Operands of an enum type are treated as having the primitive type Number. // If both operands are of the Number primitive type, the result is of the Number primitive type. resultType = numberType; } - else { - if (isTypeOfKind(leftType, 262178 /* StringLike */) || isTypeOfKind(rightType, 262178 /* StringLike */)) { - // If one or both operands are of the String primitive type, the result is of the String primitive type. - resultType = stringType; - } - else if (isTypeAny(leftType) || isTypeAny(rightType)) { - // Otherwise, the result is of type Any. - // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. - resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; - } - // Symbols are not allowed at all in arithmetic expressions - if (resultType && !checkForDisallowedESSymbolOperand(operator)) { - return resultType; - } + else if (isTypeAssignableToKind(leftType, 262178 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 262178 /* StringLike */, /*strict*/ true)) { + // If one or both operands are of the String primitive type, the result is of the String primitive type. + resultType = stringType; + } + else if (isTypeAny(leftType) || isTypeAny(rightType)) { + // Otherwise, the result is of type Any. + // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. + resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; + } + // Symbols are not allowed at all in arithmetic expressions + if (resultType && !checkForDisallowedESSymbolOperand(operator)) { + return resultType; } if (!resultType) { reportOperatorError(); @@ -38749,13 +38856,12 @@ var ts; return getBestChoiceType(type1, type2); } function checkLiteralExpression(node) { - if (node.kind === 8 /* NumericLiteral */) { - checkGrammarNumericLiteral(node); - } switch (node.kind) { + case 13 /* NoSubstitutionTemplateLiteral */: case 9 /* StringLiteral */: return getFreshTypeOfLiteralType(getLiteralType(node.text)); case 8 /* NumericLiteral */: + checkGrammarNumericLiteral(node); return getFreshTypeOfLiteralType(getLiteralType(+node.text)); case 101 /* TrueKeyword */: return trueType; @@ -38951,6 +39057,7 @@ var ts; return checkSuperExpression(node); case 95 /* NullKeyword */: return nullWideningType; + case 13 /* NoSubstitutionTemplateLiteral */: case 9 /* StringLiteral */: case 8 /* NumericLiteral */: case 101 /* TrueKeyword */: @@ -38958,8 +39065,6 @@ var ts; return checkLiteralExpression(node); case 196 /* TemplateExpression */: return checkTemplateExpression(node); - case 13 /* NoSubstitutionTemplateLiteral */: - return stringType; case 12 /* RegularExpressionLiteral */: return globalRegExpType; case 177 /* ArrayLiteralExpression */: @@ -39058,7 +39163,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); checkVariableLikeDeclaration(node); var func = ts.getContainingFunction(node); - if (ts.getModifierFlags(node) & 92 /* ParameterPropertyModifier */) { + if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { func = ts.getContainingFunction(node); if (!(func.kind === 152 /* Constructor */ && ts.nodeIsPresent(func.body))) { error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -39264,7 +39369,7 @@ var ts; } } else { - var isStatic = ts.getModifierFlags(member) & 32 /* Static */; + var isStatic = ts.hasModifier(member, 32 /* Static */); var names = isStatic ? staticNames : instanceNames; var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); if (memberName) { @@ -39320,7 +39425,7 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var memberNameNode = member.name; - var isStatic = ts.getModifierFlags(member) & 32 /* Static */; + var isStatic = ts.hasModifier(member, 32 /* Static */); if (isStatic && memberNameNode) { var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -39418,7 +39523,7 @@ var ts; checkFunctionOrMethodDeclaration(node); // Abstract methods cannot have an implementation. // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node. - if (ts.getModifierFlags(node) & 128 /* Abstract */ && node.body) { + if (ts.hasModifier(node, 128 /* Abstract */) && node.body) { error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } @@ -39458,17 +39563,9 @@ var ts; } return ts.forEachChild(n, containsSuperCall); } - function markThisReferencesAsErrors(n) { - if (n.kind === 99 /* ThisKeyword */) { - error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location); - } - else if (n.kind !== 186 /* FunctionExpression */ && n.kind !== 228 /* FunctionDeclaration */) { - ts.forEachChild(n, markThisReferencesAsErrors); - } - } function isInstancePropertyWithInitializer(n) { return n.kind === 149 /* PropertyDeclaration */ && - !(ts.getModifierFlags(n) & 32 /* Static */) && + !ts.hasModifier(n, 32 /* Static */) && !!n.initializer; } // TS 1.0 spec (April 2014): 8.3.2 @@ -39488,8 +39585,8 @@ var ts; // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. - var superCallShouldBeFirst = ts.forEach(node.parent.members, isInstancePropertyWithInitializer) || - ts.forEach(node.parameters, function (p) { return ts.getModifierFlags(p) & 92 /* ParameterPropertyModifier */; }); + var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) || + ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); }); // Skip past any prologue directives to find the first statement // to ensure that it was a super call. if (superCallShouldBeFirst) { @@ -39540,10 +39637,12 @@ var ts; var otherKind = node.kind === 153 /* GetAccessor */ ? 154 /* SetAccessor */ : 153 /* GetAccessor */; var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if ((ts.getModifierFlags(node) & 28 /* AccessibilityModifier */) !== (ts.getModifierFlags(otherAccessor) & 28 /* AccessibilityModifier */)) { + var nodeFlags = ts.getModifierFlags(node); + var otherFlags = ts.getModifierFlags(otherAccessor); + if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) { error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (ts.hasModifier(node, 128 /* Abstract */) !== ts.hasModifier(otherAccessor, 128 /* Abstract */)) { + if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) { error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } // TypeScript 1.0 spec (April 2014): 4.5 @@ -39600,7 +39699,17 @@ var ts; ts.forEach(node.typeArguments, checkSourceElement); if (produceDiagnostics) { var symbol = getNodeLinks(node).resolvedSymbol; - var typeParameters = symbol.flags & 524288 /* TypeAlias */ ? getSymbolLinks(symbol).typeParameters : type.target.localTypeParameters; + if (!symbol) { + // There is no resolved symbol cached if the type resolved to a builtin + // via JSDoc type reference resolution (eg, Boolean became boolean), none + // of which are generic when they have no associated symbol + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return; + } + var typeParameters = symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters; + if (!typeParameters && getObjectFlags(type) & 4 /* Reference */) { + typeParameters = type.target.localTypeParameters; + } checkTypeArgumentConstraints(typeParameters, node.typeArguments); } } @@ -39647,7 +39756,7 @@ var ts; } // Check if we're indexing with a numeric type and the object type is a generic // type with a constraint that has a numeric index signature. - if (maybeTypeOfKind(objectType, 540672 /* TypeVariable */) && isTypeOfKind(indexType, 84 /* NumberLike */)) { + if (maybeTypeOfKind(objectType, 540672 /* TypeVariable */) && isTypeAssignableToKind(indexType, 84 /* NumberLike */)) { var constraint = getBaseConstraintOfType(objectType); if (constraint && getIndexInfoOfType(constraint, 1 /* Number */)) { return type; @@ -39657,6 +39766,8 @@ var ts; return type; } function checkIndexedAccessType(node) { + checkSourceElement(node.objectType); + checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } function checkMappedType(node) { @@ -39667,7 +39778,7 @@ var ts; checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); } function isPrivateWithinAmbient(node) { - return (ts.getModifierFlags(node) & 8 /* Private */) && ts.isInAmbientContext(node); + return ts.hasModifier(node, 8 /* Private */) && ts.isInAmbientContext(node); } function getEffectiveDeclarationFlags(n, flagsToCheck) { var flags = ts.getCombinedModifierFlags(n); @@ -39767,13 +39878,13 @@ var ts; (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { var reportError = (node.kind === 151 /* MethodDeclaration */ || node.kind === 150 /* MethodSignature */) && - (ts.getModifierFlags(node) & 32 /* Static */) !== (ts.getModifierFlags(subsequentNode) & 32 /* Static */); + ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */); // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { - var diagnostic = ts.getModifierFlags(node) & 32 /* Static */ ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; + var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode_1, diagnostic); } return; @@ -39791,7 +39902,7 @@ var ts; else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. - if (ts.getModifierFlags(node) & 128 /* Abstract */) { + if (ts.hasModifier(node, 128 /* Abstract */)) { error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -39801,8 +39912,8 @@ var ts; } var duplicateFunctionDeclaration = false; var multipleConstructorImplementation = false; - for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { - var current = declarations_5[_i]; + for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { + var current = declarations_4[_i]; var node = current; var inAmbientContext = ts.isInAmbientContext(node); var inAmbientContextOrInterface = node.parent.kind === 230 /* InterfaceDeclaration */ || node.parent.kind === 163 /* TypeLiteral */ || inAmbientContext; @@ -39859,7 +39970,7 @@ var ts; } // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(ts.getModifierFlags(lastSeenNonAmbientDeclaration) & 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) { + !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } if (hasOverloads) { @@ -40569,14 +40680,14 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 151 /* MethodDeclaration */ || member.kind === 149 /* PropertyDeclaration */) { - if (!member.symbol.isReferenced && ts.getModifierFlags(member) & 8 /* Private */) { + if (!member.symbol.isReferenced && ts.hasModifier(member, 8 /* Private */)) { error(member.name, ts.Diagnostics._0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(member.symbol.escapedName)); } } else if (member.kind === 152 /* Constructor */) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; - if (!parameter.symbol.isReferenced && ts.getModifierFlags(parameter) & 8 /* Private */) { + if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) { error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(parameter.symbol.escapedName)); } } @@ -40997,7 +41108,7 @@ var ts; 128 /* Abstract */ | 64 /* Readonly */ | 32 /* Static */; - return (ts.getModifierFlags(left) & interestingFlags) === (ts.getModifierFlags(right) & interestingFlags); + return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); @@ -41162,7 +41273,7 @@ var ts; } // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 /* Object */ | 540672 /* TypeVariable */ | 16777216 /* NonPrimitive */)) { + if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) { error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } checkSourceElement(node.statement); @@ -41662,7 +41773,7 @@ var ts; // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, // and properties with literal names were already checked. - if (!(ts.getModifierFlags(member) & 32 /* Static */) && ts.hasDynamicName(member)) { + if (!ts.hasModifier(member, 32 /* Static */) && ts.hasDynamicName(member)) { var propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */); @@ -41773,8 +41884,8 @@ var ts; if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) { // Report an error on every conflicting declaration. var name = symbolToString(symbol); - for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { - var declaration = declarations_6[_i]; + for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { + var declaration = declarations_5[_i]; error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } @@ -41783,8 +41894,8 @@ var ts; function areTypeParametersIdentical(declarations, typeParameters) { var maxTypeArgumentCount = ts.length(typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { - var declaration = declarations_7[_i]; + for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { + var declaration = declarations_6[_i]; // If this declaration has too few or too many type parameters, we report an error var numTypeParameters = ts.length(declaration.typeParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { @@ -41827,7 +41938,7 @@ var ts; registerForUnusedIdentifiersCheck(node); } function checkClassDeclaration(node) { - if (!node.name && !(ts.getModifierFlags(node) & 512 /* Default */)) { + if (!node.name && !ts.hasModifier(node, 512 /* Default */)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -41925,7 +42036,7 @@ var ts; var signatures = getSignaturesOfType(type, 1 /* Construct */); if (signatures.length) { var declaration = signatures[0].declaration; - if (declaration && ts.getModifierFlags(declaration) & 8 /* Private */) { + if (declaration && ts.hasModifier(declaration, 8 /* Private */)) { var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); @@ -41981,7 +42092,7 @@ var ts; // It is an error to inherit an abstract member without implementing it or being declared abstract. // If there is no declaration for the derived class (as in the case of class expressions), // then the class cannot be declared abstract. - if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !(ts.getModifierFlags(derivedClassDecl) & 128 /* Abstract */))) { + if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) { if (derivedClassDecl.kind === 199 /* ClassExpression */) { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } @@ -42032,8 +42143,8 @@ var ts; for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) { var base = baseTypes_2[_i]; var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); - for (var _a = 0, properties_7 = properties; _a < properties_7.length; _a++) { - var prop = properties_7[_a]; + for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) { + var prop = properties_8[_a]; var existing = seen.get(prop.escapedName); if (!existing) { seen.set(prop.escapedName, { prop: prop, containingType: base }); @@ -42307,8 +42418,8 @@ var ts; } function getFirstNonAmbientClassOrFunctionDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { - var declaration = declarations_8[_i]; + for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { + var declaration = declarations_7[_i]; if ((declaration.kind === 229 /* ClassDeclaration */ || (declaration.kind === 228 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) && !ts.isInAmbientContext(declaration)) { @@ -42558,7 +42669,7 @@ var ts; // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -42586,7 +42697,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (ts.getModifierFlags(node) & 1 /* Export */) { + if (ts.hasModifier(node, 1 /* Export */)) { markExportAsReferenced(node); } if (ts.isInternalModuleImportEqualsDeclaration(node)) { @@ -42617,7 +42728,7 @@ var ts; // If we hit an export in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { @@ -42682,7 +42793,7 @@ var ts; return; } // Grammar checking - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === 71 /* Identifier */) { @@ -42736,8 +42847,8 @@ var ts; return; } if (exportedDeclarationsCount > 1) { - for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { - var declaration = declarations_9[_i]; + for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { + var declaration = declarations_8[_i]; if (isNotOverload(declaration)) { diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } @@ -43046,7 +43157,7 @@ var ts; return []; } var symbols = ts.createSymbolTable(); - var memberFlags = 0 /* None */; + var isStatic = false; populateSymbols(); return symbolsToArray(symbols); function populateSymbols() { @@ -43075,7 +43186,7 @@ var ts; // add the type parameters into the symbol table // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol. // Note: that the memberFlags come from previous iteration. - if (!(memberFlags & 32 /* Static */)) { + if (!isStatic) { copySymbols(getSymbolOfNode(location).members, meaning & 793064 /* Type */); } break; @@ -43089,7 +43200,7 @@ var ts; if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } - memberFlags = ts.getModifierFlags(location); + isStatic = ts.hasModifier(location, 32 /* Static */); location = location.parent; } copySymbols(globals, meaning); @@ -43487,7 +43598,7 @@ var ts; */ function getParentTypeOfClassElement(node) { var classSymbol = getSymbolOfNode(node.parent); - return ts.getModifierFlags(node) & 32 /* Static */ + return ts.hasModifier(node, 32 /* Static */) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -43769,13 +43880,13 @@ var ts; return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && - !(ts.getModifierFlags(parameter) & 92 /* ParameterPropertyModifier */); + !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */); } function isOptionalUninitializedParameterProperty(parameter) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - !!(ts.getModifierFlags(parameter) & 92 /* ParameterPropertyModifier */); + ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */); } function getNodeCheckFlags(node) { return getNodeLinks(node).flags; @@ -43835,22 +43946,22 @@ var ts; else if (type.flags & 1 /* Any */) { return ts.TypeReferenceSerializationKind.ObjectType; } - else if (isTypeOfKind(type, 1024 /* Void */ | 6144 /* Nullable */ | 8192 /* Never */)) { + else if (isTypeAssignableToKind(type, 1024 /* Void */ | 6144 /* Nullable */ | 8192 /* Never */)) { return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } - else if (isTypeOfKind(type, 136 /* BooleanLike */)) { + else if (isTypeAssignableToKind(type, 136 /* BooleanLike */)) { return ts.TypeReferenceSerializationKind.BooleanType; } - else if (isTypeOfKind(type, 84 /* NumberLike */)) { + else if (isTypeAssignableToKind(type, 84 /* NumberLike */)) { return ts.TypeReferenceSerializationKind.NumberLikeType; } - else if (isTypeOfKind(type, 262178 /* StringLike */)) { + else if (isTypeAssignableToKind(type, 262178 /* StringLike */)) { return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } - else if (isTypeOfKind(type, 512 /* ESSymbol */)) { + else if (isTypeAssignableToKind(type, 512 /* ESSymbol */)) { return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { @@ -44346,7 +44457,7 @@ var ts; node.kind !== 154 /* SetAccessor */) { return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === 229 /* ClassDeclaration */ && ts.getModifierFlags(node.parent) & 128 /* Abstract */)) { + if (!(node.parent.kind === 229 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) { return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & 32 /* Static */) { @@ -44547,7 +44658,7 @@ var ts; if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (ts.getModifierFlags(parameter) !== 0) { + if (ts.hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -44850,10 +44961,10 @@ var ts; else if (ts.isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(ts.getModifierFlags(accessor) & 128 /* Abstract */)) { + else if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) { return grammarErrorAtPos(ts.getSourceFileOfNode(accessor), accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } - else if (accessor.body && ts.getModifierFlags(accessor) & 128 /* Abstract */) { + else if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) { return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { @@ -45196,7 +45307,7 @@ var ts; node.kind === 244 /* ExportDeclaration */ || node.kind === 243 /* ExportAssignment */ || node.kind === 236 /* NamespaceExportDeclaration */ || - ts.getModifierFlags(node) & (2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) { + ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) { return false; } return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); @@ -48142,7 +48253,7 @@ var ts; function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) { var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; if (property === firstAccessor) { - var properties_8 = []; + var properties_9 = []; if (getAccessor) { var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, /*asteriskToken*/ undefined, @@ -48152,7 +48263,7 @@ var ts; ts.setTextRange(getterFunction, getAccessor); ts.setOriginalNode(getterFunction, getAccessor); var getter = ts.createPropertyAssignment("get", getterFunction); - properties_8.push(getter); + properties_9.push(getter); } if (setAccessor) { var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, @@ -48163,15 +48274,15 @@ var ts; ts.setTextRange(setterFunction, setAccessor); ts.setOriginalNode(setterFunction, setAccessor); var setter = ts.createPropertyAssignment("set", setterFunction); - properties_8.push(setter); + properties_9.push(setter); } - properties_8.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); - properties_8.push(ts.createPropertyAssignment("configurable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue())); var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ receiver, createExpressionForPropertyName(property.name), - ts.createObjectLiteral(properties_8, multiLine) + ts.createObjectLiteral(properties_9, multiLine) ]), /*location*/ firstAccessor); return ts.aggregateTransformFlags(expression); @@ -50628,11 +50739,14 @@ var ts; : numElements, location), /*reuseIdentifierExpressions*/ false, location); } - else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)) { + else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0) + || ts.every(elements, ts.isOmittedExpression)) { // For anything other than a single-element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. Additionally, if we have zero elements // we need to emit *something* to ensure that in case a 'var' keyword was already emitted, // so in that case, we'll intentionally create that temporary. + // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]", + // then we will create temporary variable. var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } @@ -50919,7 +51033,16 @@ var ts; if (ts.hasModifier(node, 2 /* Ambient */)) { break; } - recordEmittedDeclarationInScope(node); + // Record these declarations provided that they have a name. + if (node.name) { + recordEmittedDeclarationInScope(node); + } + else { + // These nodes should always have names unless they are default-exports; + // however, class declaration parsing allows for undefined names, so syntactically invalid + // programs may also have an undefined name. + ts.Debug.assert(node.kind === 229 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */)); + } break; } } @@ -51748,8 +51871,8 @@ var ts; * @param receiver The receiver on which each property should be assigned. */ function addInitializedPropertyStatements(statements, properties, receiver) { - for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) { - var property = properties_9[_i]; + for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { + var property = properties_10[_i]; var statement = ts.createStatement(transformInitializedProperty(property, receiver)); ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); ts.setCommentRange(statement, property); @@ -51764,8 +51887,8 @@ var ts; */ function generateInitializedPropertyExpressions(properties, receiver) { var expressions = []; - for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { - var property = properties_10[_i]; + for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { + var property = properties_11[_i]; var expression = transformInitializedProperty(property, receiver); expression.startsOnNewLine = true; ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); @@ -52928,33 +53051,30 @@ var ts; /** * Records that a declaration was emitted in the current scope, if it was the first * declaration for the provided symbol. - * - * NOTE: if there is ever a transformation above this one, we may not be able to rely - * on symbol names. */ function recordEmittedDeclarationInScope(node) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - if (!currentScopeFirstDeclarationsOfName) { - currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); - } - if (!currentScopeFirstDeclarationsOfName.has(name)) { - currentScopeFirstDeclarationsOfName.set(name, node); - } + if (!currentScopeFirstDeclarationsOfName) { + currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); + } + var name = declaredNameInScope(node); + if (!currentScopeFirstDeclarationsOfName.has(name)) { + currentScopeFirstDeclarationsOfName.set(name, node); } } /** - * Determines whether a declaration is the first declaration with the same name emitted - * in the current scope. + * Determines whether a declaration is the first declaration with + * the same name emitted in the current scope. */ function isFirstEmittedDeclarationInScope(node) { if (currentScopeFirstDeclarationsOfName) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - return currentScopeFirstDeclarationsOfName.get(name) === node; - } + var name = declaredNameInScope(node); + return currentScopeFirstDeclarationsOfName.get(name) === node; } - return false; + return true; + } + function declaredNameInScope(node) { + ts.Debug.assertNode(node.name, ts.isIdentifier); + return node.name.escapedText; } /** * Adds a leading VariableStatement for a enum or module declaration. @@ -53021,7 +53141,7 @@ var ts; if (!shouldEmitModuleDeclaration(node)) { return ts.createNotEmittedStatement(node); } - ts.Debug.assert(ts.isIdentifier(node.name), "TypeScript module should have an Identifier name."); + ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name."); enableSubstitutionForNamespaceExports(); var statements = []; // We request to be advised when the printer is about to print this node. This allows @@ -54050,6 +54170,8 @@ var ts; return visitExpressionStatement(node); case 185 /* ParenthesizedExpression */: return visitParenthesizedExpression(node, noDestructuringValue); + case 260 /* CatchClause */: + return visitCatchClause(node); default: return ts.visitEachChild(node, visitor, context); } @@ -54130,6 +54252,12 @@ var ts; function visitParenthesizedExpression(node, noDestructuringValue) { return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context); } + function visitCatchClause(node) { + if (!node.variableDeclaration) { + return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock)); + } + return ts.visitEachChild(node, visitor, context); + } /** * Visits a BinaryExpression that contains a destructuring assignment. * @@ -54674,7 +54802,7 @@ var ts; objectProperties = ts.createAssignHelper(context, segments); } } - var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.filter(ts.map(children, transformJsxChildToExpression), ts.isDefined), node, location); + var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } @@ -55378,7 +55506,7 @@ var ts; function shouldVisitNode(node) { return (node.transformFlags & 128 /* ContainsES2015 */) !== 0 || convertedLoopState !== undefined - || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && ts.isStatement(node)) + || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */))) || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)) || isTypeScriptClassWrapper(node); } @@ -55733,10 +55861,12 @@ var ts; var outer = ts.createPartiallyEmittedExpression(inner); outer.end = ts.skipTrivia(currentText, node.pos); ts.setEmitFlags(outer, 1536 /* NoComments */); - return ts.createParen(ts.createCall(outer, + var result = ts.createParen(ts.createCall(outer, /*typeArguments*/ undefined, extendsClauseElement ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)] : [])); + ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class "); + return result; } /** * Transforms a ClassExpression or ClassDeclaration into a function body. @@ -56654,13 +56784,14 @@ var ts; ts.setTextRange(declarationList, node); ts.setCommentRange(declarationList, node); if (node.transformFlags & 8388608 /* ContainsBindingPattern */ - && (ts.isBindingPattern(node.declarations[0].name) - || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { + && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { // If the first or last declaration is a binding pattern, we need to modify // the source map range for the declaration list. var firstDeclaration = ts.firstOrUndefined(declarations); - var lastDeclaration = ts.lastOrUndefined(declarations); - ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + if (firstDeclaration) { + var lastDeclaration = ts.lastOrUndefined(declarations); + ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + } } return declarationList; } @@ -57405,6 +57536,7 @@ var ts; function visitCatchClause(node) { var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */); var updated; + ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (ts.isBindingPattern(node.variableDeclaration.name)) { var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); var newVariableDeclaration = ts.createVariableDeclaration(temp); @@ -59979,9 +60111,6 @@ var ts; var block = endBlock(); markLabel(block.endLabel); } - function isWithBlock(block) { - return block.kind === 1 /* With */; - } /** * Begins a code block for a generated `try` statement. */ @@ -60065,9 +60194,6 @@ var ts; emitNop(); exception.state = 3 /* Done */; } - function isExceptionBlock(block) { - return block.kind === 0 /* Exception */; - } /** * Begins a code block that supports `break` or `continue` statements that are defined in * the source tree and not from generated code. @@ -60301,7 +60427,7 @@ var ts; * @param location An optional source map location for the statement. */ function createInlineBreak(label, location) { - ts.Debug.assert(label > 0, "Invalid label: " + label); + ts.Debug.assertLessThan(0, label, "Invalid label"); return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3 /* Break */), createLabel(label) @@ -60642,31 +60768,33 @@ var ts; for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { var block = blocks[blockIndex]; var blockAction = blockActions[blockIndex]; - if (isExceptionBlock(block)) { - if (blockAction === 0 /* Open */) { - if (!exceptionBlockStack) { - exceptionBlockStack = []; + switch (block.kind) { + case 0 /* Exception */: + if (blockAction === 0 /* Open */) { + if (!exceptionBlockStack) { + exceptionBlockStack = []; + } + if (!statements) { + statements = []; + } + exceptionBlockStack.push(currentExceptionBlock); + currentExceptionBlock = block; } - if (!statements) { - statements = []; + else if (blockAction === 1 /* Close */) { + currentExceptionBlock = exceptionBlockStack.pop(); } - exceptionBlockStack.push(currentExceptionBlock); - currentExceptionBlock = block; - } - else if (blockAction === 1 /* Close */) { - currentExceptionBlock = exceptionBlockStack.pop(); - } - } - else if (isWithBlock(block)) { - if (blockAction === 0 /* Open */) { - if (!withBlockStack) { - withBlockStack = []; + break; + case 1 /* With */: + if (blockAction === 0 /* Open */) { + if (!withBlockStack) { + withBlockStack = []; + } + withBlockStack.push(block); } - withBlockStack.push(block); - } - else if (blockAction === 1 /* Close */) { - withBlockStack.pop(); - } + else if (blockAction === 1 /* Close */) { + withBlockStack.pop(); + } + break; } } } @@ -64580,14 +64708,14 @@ var ts; writer.writeLine(); } } - function emitTrailingCommentsOfPosition(pos) { + function emitTrailingCommentsOfPosition(pos, prefixSpace) { if (disabled) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeEmitTrailingCommentsOfPosition"); } - forEachTrailingCommentToEmit(pos, emitTrailingCommentOfPosition); + forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition); if (extendedDiagnostics) { ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); } @@ -64676,17 +64804,7 @@ var ts; * @return true if the comment is a triple-slash comment else false */ function isTripleSlashComment(commentPos, commentEnd) { - // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text - // so that we don't end up computing comment string and doing match for all // comments - if (currentText.charCodeAt(commentPos + 1) === 47 /* slash */ && - commentPos + 2 < commentEnd && - currentText.charCodeAt(commentPos + 2) === 47 /* slash */) { - var textSubStr = currentText.substring(commentPos, commentEnd); - return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || - textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ? - true : false; - } - return false; + return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd); } } ts.createCommentWriter = createCommentWriter; @@ -65898,6 +66016,10 @@ var ts; return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); }); } function writeVariableStatement(node) { + // If binding pattern doesn't have name, then there is nothing to be emitted for declaration file i.e. const [,] = [1,2]. + if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) { + return; + } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isLet(node.declarationList)) { @@ -67437,7 +67559,9 @@ var ts; if (!(ts.getEmitFlags(node) & 131072 /* NoIndentation */)) { var dotRangeStart = node.expression.end; var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1; - var dotToken = { kind: 23 /* DotToken */, pos: dotRangeStart, end: dotRangeEnd }; + var dotToken = ts.createToken(23 /* DotToken */); + dotToken.pos = dotRangeStart; + dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } @@ -67566,7 +67690,9 @@ var ts; var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right); emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); + emitLeadingCommentsOfPosition(node.operatorToken.pos); writeTokenNode(node.operatorToken); + emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); decreaseIndentIf(indentBeforeOperator, indentAfterOperator); @@ -67760,8 +67886,19 @@ var ts; emitWithPrefix(" ", node.label); write(";"); } + function emitTokenWithComment(token, pos, contextNode) { + var node = contextNode && ts.getParseTreeNode(contextNode); + if (node && node.kind === contextNode.kind) { + pos = ts.skipTrivia(currentSourceFile.text, pos); + } + pos = writeToken(token, pos, /*contextNode*/ contextNode); + if (node && node.kind === contextNode.kind) { + emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true); + } + return pos; + } function emitReturnStatement(node) { - writeToken(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node); + emitTokenWithComment(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node); emitExpressionWithPrefix(" ", node.expression); write(";"); } @@ -68237,10 +68374,12 @@ var ts; function emitCatchClause(node) { var openParenPos = writeToken(74 /* CatchKeyword */, node.pos); write(" "); - writeToken(19 /* OpenParenToken */, openParenPos); - emit(node.variableDeclaration); - writeToken(20 /* CloseParenToken */, node.variableDeclaration ? node.variableDeclaration.end : openParenPos); - write(" "); + if (node.variableDeclaration) { + writeToken(19 /* OpenParenToken */, openParenPos); + emit(node.variableDeclaration); + writeToken(20 /* CloseParenToken */, node.variableDeclaration.end); + write(" "); + } emit(node.block); } // @@ -69520,6 +69659,14 @@ var ts; var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; }; resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); }; } + // Map from a stringified PackageId to the source file with that id. + // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile). + // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around. + var packageIdToSourceFile = ts.createMap(); + // Maps from a SourceFile's `.path` to the name of the package it was imported with. + var sourceFileToPackageName = ts.createMap(); + // See `sourceFileIsRedirectedTo`. + var redirectTargetsSet = ts.createMap(); var filesByName = ts.createMap(); // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing @@ -69588,6 +69735,8 @@ var ts; isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker, getSourceFileFromReference: getSourceFileFromReference, + sourceFileToPackageName: sourceFileToPackageName, + redirectTargetsSet: redirectTargetsSet, }; verifyCompilerOptions(); ts.performance.mark("afterProgram"); @@ -69780,17 +69929,57 @@ var ts; var filePaths = []; var modifiedSourceFiles = []; oldProgram.structureIsReused = 2 /* Completely */; - for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) { - var oldSourceFile = _a[_i]; + var oldSourceFiles = oldProgram.getSourceFiles(); + var SeenPackageName; + (function (SeenPackageName) { + SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists"; + SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified"; + })(SeenPackageName || (SeenPackageName = {})); + var seenPackageNames = ts.createMap(); + for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { + var oldSourceFile = oldSourceFiles_1[_i]; var newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target) : host.getSourceFile(oldSourceFile.fileName, options.target); if (!newSourceFile) { return oldProgram.structureIsReused = 0 /* Not */; } + ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); + var fileChanged = void 0; + if (oldSourceFile.redirectInfo) { + // We got `newSourceFile` by path, so it is actually for the unredirected file. + // This lets us know if the unredirected file has changed. If it has we should break the redirect. + if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { + // Underlying file has changed. Might not redirect anymore. Must rebuild program. + return oldProgram.structureIsReused = 0 /* Not */; + } + fileChanged = false; + newSourceFile = oldSourceFile; // Use the redirect. + } + else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) { + // If a redirected-to source file changes, the redirect may be broken. + if (newSourceFile !== oldSourceFile) { + return oldProgram.structureIsReused = 0 /* Not */; + } + fileChanged = false; + } + else { + fileChanged = newSourceFile !== oldSourceFile; + } newSourceFile.path = oldSourceFile.path; filePaths.push(newSourceFile.path); - if (oldSourceFile !== newSourceFile) { + var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); + if (packageName !== undefined) { + // If there are 2 different source files for the same package name and at least one of them changes, + // they might become redirects. So we must rebuild the program. + var prevKind = seenPackageNames.get(packageName); + var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */; + if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) { + return oldProgram.structureIsReused = 0 /* Not */; + } + seenPackageNames.set(packageName, newKind); + } + if (fileChanged) { // The `newSourceFile` object was created for the new program. if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { // value of no-default-lib has changed @@ -69831,8 +70020,8 @@ var ts; } modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; }); // try to verify results of module resolution - for (var _b = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _b < modifiedSourceFiles_1.length; _b++) { - var _c = modifiedSourceFiles_1[_b], oldSourceFile = _c.oldFile, newSourceFile = _c.newFile; + for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) { + var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile; var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { var moduleNames = ts.map(ts.concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral); @@ -69875,8 +70064,8 @@ var ts; if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) { return oldProgram.structureIsReused = 1 /* SafeModules */; } - for (var _d = 0, _e = oldProgram.getMissingFilePaths(); _d < _e.length; _d++) { - var p = _e[_d]; + for (var _c = 0, _d = oldProgram.getMissingFilePaths(); _c < _d.length; _c++) { + var p = _d[_c]; filesByName.set(p, undefined); } // update fileName -> file mapping @@ -69885,11 +70074,13 @@ var ts; } files = newSourceFiles; fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics(); - for (var _f = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _f < modifiedSourceFiles_2.length; _f++) { - var modifiedFile = modifiedSourceFiles_2[_f]; + for (var _e = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _e < modifiedSourceFiles_2.length; _e++) { + var modifiedFile = modifiedSourceFiles_2[_e]; fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile); } resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives(); + sourceFileToPackageName = oldProgram.sourceFileToPackageName; + redirectTargetsSet = oldProgram.redirectTargetsSet; return oldProgram.structureIsReused = 2 /* Completely */; } function getEmitHost(writeFileCallback) { @@ -70436,7 +70627,7 @@ var ts; } /** This has side effects through `findSourceFile`. */ function processSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd) { - getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd); }, function (diagnostic) { + getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, /*packageId*/ undefined); }, function (diagnostic) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; @@ -70453,8 +70644,25 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } } + function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) { + var redirect = Object.create(redirectTarget); + redirect.fileName = fileName; + redirect.path = path; + redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected }; + Object.defineProperties(redirect, { + id: { + get: function () { return this.redirectInfo.redirectTarget.id; }, + set: function (value) { this.redirectInfo.redirectTarget.id = value; }, + }, + symbol: { + get: function () { return this.redirectInfo.redirectTarget.symbol; }, + set: function (value) { this.redirectInfo.redirectTarget.symbol = value; }, + }, + }); + return redirect; + } // Get source file from normalized fileName - function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd) { + function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) { if (filesByName.has(path)) { var file_1 = filesByName.get(path); // try to check if we've already seen this file but with a different casing in path @@ -70490,6 +70698,25 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); + if (packageId) { + var packageIdKey = packageId.name + "@" + packageId.version; + var fileFromPackageId = packageIdToSourceFile.get(packageIdKey); + if (fileFromPackageId) { + // Some other SourceFile already exists with this package name and version. + // Instead of creating a duplicate, just redirect to the existing one. + var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path); + redirectTargetsSet.set(fileFromPackageId.path, true); + filesByName.set(path, dupFile); + sourceFileToPackageName.set(path, packageId.name); + files.push(dupFile); + return dupFile; + } + else if (file) { + // This is the first source file to have this packageId. + packageIdToSourceFile.set(packageIdKey, file); + sourceFileToPackageName.set(path, packageId.name); + } + } filesByName.set(path, file); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); @@ -70630,7 +70857,7 @@ var ts; else if (shouldAddFile) { var path = toPath(resolvedFileName); var pos = ts.skipTrivia(file.text, file.imports[i].pos); - findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end); + findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end, resolution.packageId); } if (isFromNodeModulesSearch) { currentNodeModulesDepth--; @@ -70785,8 +71012,8 @@ var ts; } // there has to be common source directory if user specified --outdir || --sourceRoot // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted - if (options.outDir || - options.sourceRoot || + if (options.outDir || // there is --outDir specified + options.sourceRoot || // there is --sourceRoot specified options.mapRoot) { // Precalculate and cache the common source directory var dir = getCommonSourceDirectory(); @@ -71349,6 +71576,12 @@ var ts; category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "preserveSymlinks", + type: "boolean", + category: ts.Diagnostics.Module_Resolution_Options, + description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, + }, // Source Maps { name: "sourceRoot", @@ -72006,7 +72239,7 @@ var ts; if (option && typeof option.type !== "string") { var customOption = option; // Validate custom option type - if (!customOption.type.has(text)) { + if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } @@ -72306,13 +72539,10 @@ var ts; } } else { - // If no includes were specified, exclude common package folders and the outDir - var specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; var outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"]; if (outDir) { - specs.push(outDir); + excludeSpecs = [outDir]; } - excludeSpecs = specs; } if (fileNames === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; @@ -72573,7 +72803,7 @@ var ts; return value; } else if (typeof option.type !== "string") { - return option.type.get(value); + return option.type.get(typeof value === "string" ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } @@ -72748,23 +72978,13 @@ var ts; }; } function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { - var validSpecs = []; - for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) { - var spec = specs_1[_i]; - if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidMultipleRecursionPatterns.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else { - validSpecs.push(spec); + return specs.filter(function (spec) { + var diag = specToDiagnostic(spec, allowTrailingRecursion); + if (diag !== undefined) { + errors.push(createDiagnostic(diag, spec)); } - } - return validSpecs; + return diag === undefined; + }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { @@ -72782,6 +73002,17 @@ var ts; return ts.createCompilerDiagnostic(message, spec); } } + function specToDiagnostic(spec, allowTrailingRecursion) { + if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + else if (invalidMultipleRecursionPatterns.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; + } + else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + } /** * Gets directories in a set of include patterns that should be watched for changes. */ @@ -72945,7 +73176,7 @@ var ts; (function (ts) { var ScriptSnapshot; (function (ScriptSnapshot) { - var StringScriptSnapshot = (function () { + var StringScriptSnapshot = /** @class */ (function () { function StringScriptSnapshot(text) { this.text = text; } @@ -72969,7 +73200,7 @@ var ts; } ScriptSnapshot.fromString = fromString; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); - var TextChange = (function () { + var TextChange = /** @class */ (function () { function TextChange() { } return TextChange; @@ -73858,7 +74089,7 @@ var ts; // if this is the case - then we should assume that token in question is located in previous child. if (position < child.end && (nodeHasTokens(child) || child.kind === 10 /* JsxText */)) { var start = child.getStart(sourceFile, includeJsDoc); - var lookInPreviousChild = (start >= position) || + var lookInPreviousChild = (start >= position) || // cursor in the leading trivia (child.kind === 10 /* JsxText */ && start === child.end); // whitespace only JsxText if (lookInPreviousChild) { // actual start of the node is past the position - previous token should be at the end of previous child @@ -74357,6 +74588,7 @@ var ts; } ts.symbolToDisplayParts = symbolToDisplayParts; function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) { + flags |= 65536 /* UseAliasDefinedOutsideCurrentScope */; return mapToDisplayParts(function (writer) { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); @@ -74666,11 +74898,11 @@ var ts; templateStack.pop(); } else { - ts.Debug.assert(token === 15 /* TemplateMiddle */, "Should have been a template middle. Was " + token); + ts.Debug.assertEqual(token, 15 /* TemplateMiddle */, "Should have been a template middle."); } } else { - ts.Debug.assert(lastTemplateStackToken === 17 /* OpenBraceToken */, "Should have been an open brace. Was: " + token); + ts.Debug.assertEqual(lastTemplateStackToken, 17 /* OpenBraceToken */, "Should have been an open brace"); templateStack.pop(); } } @@ -76652,7 +76884,7 @@ var ts; if (!typeForObject) return false; // In a binding pattern, get only known properties. Everywhere else we will get all possible properties. - typeMembers = typeChecker.getPropertiesOfType(typeForObject); + typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */); }); existingMembers = objectLikeContainer.elements; } } @@ -76916,11 +77148,11 @@ var ts; return containingNodeKind === 226 /* VariableDeclaration */ || containingNodeKind === 227 /* VariableDeclarationList */ || containingNodeKind === 208 /* VariableStatement */ || - containingNodeKind === 232 /* EnumDeclaration */ || + containingNodeKind === 232 /* EnumDeclaration */ || // enum a { foo, | isFunctionLikeButNotConstructor(containingNodeKind) || - containingNodeKind === 230 /* InterfaceDeclaration */ || - containingNodeKind === 175 /* ArrayBindingPattern */ || - containingNodeKind === 231 /* TypeAliasDeclaration */ || + containingNodeKind === 230 /* InterfaceDeclaration */ || // interface A undefined); => should get use to the declaration in file "./foo" + // + // function bar(onfulfilled: (value: T) => void) { //....} + // interface Test { + // pr/*destination*/op1: number + // } + // bar(({pr/*goto*/op1})=>{}); + if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) && + (node === (node.parent.propertyName || node.parent.name))) { + var type = typeChecker.getTypeAtLocation(node.parent.parent); + if (type) { + var propSymbols = ts.getPropertySymbolsFromType(type, node); + if (propSymbols) { + return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); }); + } + } + } // If the current location we want to find its definition is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. // For example @@ -80614,7 +80877,7 @@ var ts; "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console" ]; - var nodeCoreModules = ts.arrayToMap(JsTyping.nodeCoreModuleList, function (x) { return x; }); + var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList); function loadSafeList(host, safeListPath) { var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); }); return ts.createMapFromTemplate(result.config); @@ -80812,8 +81075,8 @@ var ts; if (!matches) { return; // continue to next named declarations } - for (var _i = 0, declarations_12 = declarations; _i < declarations_12.length; _i++) { - var declaration = declarations_12[_i]; + for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { + var declaration = declarations_11[_i]; // It was a match! If the pattern has dots in it, then also see if the // declaration container matches as well. if (patternMatcher.patternContainsDots) { @@ -82760,8 +83023,8 @@ var ts; var nameToDeclarations = sourceFile.getNamedDeclarations(); var declarations = nameToDeclarations.get(name.text); if (declarations) { - for (var _b = 0, declarations_13 = declarations; _b < declarations_13.length; _b++) { - var declaration = declarations_13[_b]; + for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) { + var declaration = declarations_12[_b]; var symbol = declaration.symbol; if (symbol) { var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration); @@ -82820,7 +83083,9 @@ var ts; } var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 /* TypeArguments */ : 1 /* CallArguments */; var argumentCount = getArgumentCount(list); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var argumentsSpan = getApplicableSpanForArguments(list, sourceFile); return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount }; } @@ -82942,7 +83207,9 @@ var ts; var argumentCount = tagExpression.template.kind === 13 /* NoSubstitutionTemplateLiteral */ ? 1 : tagExpression.template.templateSpans.length + 1; - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } return { kind: 2 /* TaggedTemplateArguments */, invocation: tagExpression, @@ -83060,7 +83327,9 @@ var ts; tags: candidateSignature.getJsDocTags() }; }); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var selectedItemIndex = candidates.indexOf(resolvedSignature); ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function. return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount }; @@ -83288,12 +83557,12 @@ var ts; hasAddedSymbolInfo = true; } } - else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || + else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration (location.kind === 123 /* ConstructorKeyword */ && location.parent.kind === 152 /* Constructor */)) { // get the signature from the declaration and write it var functionDeclaration_1 = location.parent; // Use function declaration to write the signatures only if the symbol corresponding to this declaration - var locationIsSymbolDeclaration = ts.findDeclaration(symbol, function (declaration) { + var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) { return declaration === (location.kind === 123 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1); }); if (locationIsSymbolDeclaration) { @@ -83676,11 +83945,11 @@ var ts; getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; }, writeFile: function (name, text) { if (ts.fileExtensionIs(name, ".map")) { - ts.Debug.assert(sourceMapText === undefined, "Unexpected multiple source map outputs for the file '" + name + "'"); + ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); sourceMapText = text; } else { - ts.Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: '" + name + "'"); + ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); outputText = text; } }, @@ -84005,7 +84274,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var FormattingContext = (function () { + var FormattingContext = /** @class */ (function () { function FormattingContext(sourceFile, formattingRequestKind, options) { this.sourceFile = sourceFile; this.formattingRequestKind = formattingRequestKind; @@ -84104,7 +84373,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var Rule = (function () { + var Rule = /** @class */ (function () { function Rule(Descriptor, Operation, Flag) { if (Flag === void 0) { Flag = 0 /* None */; } this.Descriptor = Descriptor; @@ -84142,7 +84411,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RuleDescriptor = (function () { + var RuleDescriptor = /** @class */ (function () { function RuleDescriptor(LeftTokenRange, RightTokenRange) { this.LeftTokenRange = LeftTokenRange; this.RightTokenRange = RightTokenRange; @@ -84187,7 +84456,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RuleOperation = (function () { + var RuleOperation = /** @class */ (function () { function RuleOperation(Context, Action) { this.Context = Context; this.Action = Action; @@ -84213,7 +84482,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RuleOperationContext = (function () { + var RuleOperationContext = /** @class */ (function () { function RuleOperationContext() { var funcs = []; for (var _i = 0; _i < arguments.length; _i++) { @@ -84248,7 +84517,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var Rules = (function () { + var Rules = /** @class */ (function () { function Rules() { /// /// Common Rules @@ -84407,6 +84676,7 @@ var ts; // Insert space after opening and before closing nonempty parenthesis this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */)); this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */)); + this.SpaceBetweenOpenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */)); this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */)); this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */)); this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */)); @@ -84486,7 +84756,7 @@ var ts; this.SpaceAfterComma, this.NoSpaceAfterComma, this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword, this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl, - this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, + this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace, this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail, @@ -84825,7 +85095,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RulesMap = (function () { + var RulesMap = /** @class */ (function () { function RulesMap() { this.map = []; this.mapRowLength = 0; @@ -84895,7 +85165,7 @@ var ts; RulesPosition[RulesPosition["NoContextRulesSpecific"] = MaskBitSize * 4] = "NoContextRulesSpecific"; RulesPosition[RulesPosition["NoContextRulesAny"] = MaskBitSize * 5] = "NoContextRulesAny"; })(RulesPosition = formatting.RulesPosition || (formatting.RulesPosition = {})); - var RulesBucketConstructionState = (function () { + var RulesBucketConstructionState = /** @class */ (function () { function RulesBucketConstructionState() { //// The Rules list contains all the inserted rules into a rulebucket in the following order: //// 1- Ignore rules with specific token combination @@ -84936,7 +85206,7 @@ var ts; return RulesBucketConstructionState; }()); formatting.RulesBucketConstructionState = RulesBucketConstructionState; - var RulesBucket = (function () { + var RulesBucket = /** @class */ (function () { function RulesBucket() { this.rules = []; } @@ -84985,7 +85255,7 @@ var ts; for (var token = 0 /* FirstToken */; token <= 142 /* LastToken */; token++) { allTokens.push(token); } - var TokenValuesAccess = (function () { + var TokenValuesAccess = /** @class */ (function () { function TokenValuesAccess(tokens) { if (tokens === void 0) { tokens = []; } this.tokens = tokens; @@ -84999,7 +85269,7 @@ var ts; TokenValuesAccess.prototype.isSpecific = function () { return true; }; return TokenValuesAccess; }()); - var TokenSingleValueAccess = (function () { + var TokenSingleValueAccess = /** @class */ (function () { function TokenSingleValueAccess(token) { this.token = token; } @@ -85012,7 +85282,7 @@ var ts; TokenSingleValueAccess.prototype.isSpecific = function () { return true; }; return TokenSingleValueAccess; }()); - var TokenAllAccess = (function () { + var TokenAllAccess = /** @class */ (function () { function TokenAllAccess() { } TokenAllAccess.prototype.GetTokens = function () { @@ -85027,7 +85297,7 @@ var ts; TokenAllAccess.prototype.isSpecific = function () { return false; }; return TokenAllAccess; }()); - var TokenAllExceptAccess = (function () { + var TokenAllExceptAccess = /** @class */ (function () { function TokenAllExceptAccess(except) { this.except = except; } @@ -85119,7 +85389,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RulesProvider = (function () { + var RulesProvider = /** @class */ (function () { function RulesProvider() { this.globalRules = new formatting.Rules(); var activeRules = this.globalRules.HighPriorityCommonRules.slice(0).concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules); @@ -86633,6 +86903,12 @@ var ts; } return false; } + var ChangeKind; + (function (ChangeKind) { + ChangeKind[ChangeKind["Remove"] = 0] = "Remove"; + ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode"; + ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes"; + })(ChangeKind || (ChangeKind = {})); function getSeparatorCharacter(separator) { return ts.tokenToString(separator.kind); } @@ -86666,13 +86942,11 @@ var ts; } textChanges.getAdjustedStartPosition = getAdjustedStartPosition; function getAdjustedEndPosition(sourceFile, node, options) { - if (options.useNonAdjustedEndPosition) { + if (options.useNonAdjustedEndPosition || ts.isExpression(node)) { return node.getEnd(); } var end = node.getEnd(); var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true); - // check if last character before newPos is linebreak - // if yes - considered all skipped trivia to be trailing trivia of the node return newEnd !== end && ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)) ? newEnd : end; @@ -86691,7 +86965,10 @@ var ts; } return s; } - var ChangeTracker = (function () { + function getNewlineKind(context) { + return context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */; + } + var ChangeTracker = /** @class */ (function () { function ChangeTracker(newLine, rulesProvider, validator) { this.newLine = newLine; this.rulesProvider = rulesProvider; @@ -86700,24 +86977,24 @@ var ts; this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine }); } ChangeTracker.fromCodeFixContext = function (context) { - return new ChangeTracker(context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */, context.rulesProvider); + return new ChangeTracker(getNewlineKind(context), context.rulesProvider); + }; + ChangeTracker.prototype.deleteRange = function (sourceFile, range) { + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range }); + return this; }; ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, node, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); - return this; - }; - ChangeTracker.prototype.deleteRange = function (sourceFile, range) { - this.changes.push({ sourceFile: sourceFile, range: range }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) { @@ -86756,33 +87033,68 @@ var ts; }; ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, range: range, options: options, node: newNode }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode }); return this; }; ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); }; ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); + }; + ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, + sourceFile: sourceFile, + options: options, + node: newNode, + range: { pos: startPosition, end: endPosition } + }); + return this; + }; + ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithMultipleNodes, + sourceFile: sourceFile, + options: options, + nodes: newNodes, + range: { pos: startPosition, end: endPosition } + }); return this; }; + ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) { + return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options); + }; + ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); return this; }; ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: startPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options); }; ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) { if (options === void 0) { options = {}; } @@ -86794,6 +87106,7 @@ var ts; // if not - insert semicolon to preserve the code from changing the meaning due to ASI if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: {}, range: { pos: after.end, end: after.end }, @@ -86802,8 +87115,7 @@ var ts; } } var endPosition = getAdjustedEndPosition(sourceFile, after, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: endPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options); }; /** * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range, @@ -86869,10 +87181,10 @@ var ts; startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile); } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) }, node: newNode, - useIndentationFromFile: true, options: { prefix: prefix, // write separator and leading trivia of the next element as suffix @@ -86911,6 +87223,7 @@ var ts; if (multilineList) { // insert separator immediately following the 'after' node to preserve comments in trailing trivia this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: ts.createToken(separator), @@ -86924,6 +87237,7 @@ var ts; insertPos--; } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: insertPos, end: insertPos }, node: newNode, @@ -86932,6 +87246,7 @@ var ts; } else { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: newNode, @@ -86973,33 +87288,45 @@ var ts; return ts.createTextSpanFromBounds(change.range.pos, change.range.end); }; ChangeTracker.prototype.computeNewText = function (change, sourceFile) { - if (!change.node) { + var _this = this; + if (change.kind === ChangeKind.Remove) { // deletion case return ""; } var options = change.options || {}; - var nonFormattedText = getNonformattedText(change.node, sourceFile, this.newLine); + var text; + var pos = change.range.pos; + var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; + if (change.kind === ChangeKind.ReplaceWithMultipleNodes) { + var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); }); + text = parts.join(change.options.nodeSeparator); + } + else { + ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode"); + text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options); + } + // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line + text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, ""); + return (options.prefix || "") + text + (options.suffix || ""); + }; + ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) { + var nonformattedText = getNonformattedText(node, sourceFile, this.newLine); if (this.validator) { - this.validator(nonFormattedText); + this.validator(nonformattedText); } var formatOptions = this.rulesProvider.getFormatOptions(); - var pos = change.range.pos; var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; - var initialIndentation = change.options.indentation !== undefined - ? change.options.indentation - : change.useIndentationFromFile - ? ts.formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix === this.newLineCharacter)) + var initialIndentation = options.indentation !== undefined + ? options.indentation + : (options.useIndentationFromFile !== false) + ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) : 0; - var delta = change.options.delta !== undefined - ? change.options.delta - : ts.formatting.SmartIndenter.shouldIndentChildNode(change.node) - ? formatOptions.indentSize + var delta = options.delta !== undefined + ? options.delta + : ts.formatting.SmartIndenter.shouldIndentChildNode(node) + ? (formatOptions.indentSize || 0) : 0; - var text = applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, this.rulesProvider); - // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line - // however keep indentation if it is was forced - text = posStartsLine || change.options.indentation !== undefined ? text : text.replace(/^\s+/, ""); - return (options.prefix || "") + text + (options.suffix || ""); + return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); }; ChangeTracker.normalize = function (changes) { // order changes by start position @@ -87065,7 +87392,7 @@ var ts; nodeArray.end = getEnd(nodes); return nodeArray; } - var Writer = (function () { + var Writer = /** @class */ (function () { function Writer(newLine) { var _this = this; this.lastNonTriviaPosition = 0; @@ -87948,7 +88275,7 @@ var ts; ModuleSpecifierComparison[ModuleSpecifierComparison["Equal"] = 1] = "Equal"; ModuleSpecifierComparison[ModuleSpecifierComparison["Worse"] = 2] = "Worse"; })(ModuleSpecifierComparison || (ModuleSpecifierComparison = {})); - var ImportCodeActionMap = (function () { + var ImportCodeActionMap = /** @class */ (function () { function ImportCodeActionMap() { this.symbolIdToActionMap = []; } @@ -88061,7 +88388,7 @@ var ts; } else if (ts.isJsxOpeningLikeElement(token.parent) && token.parent.tagName === token) { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. - symbol = checker.getAliasedSymbol(checker.resolveNameAtLocation(token, checker.getJsxNamespace(), 107455 /* Value */)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), token.parent.tagName, 107455 /* Value */)); symbolName = symbol.name; } else { @@ -88086,7 +88413,7 @@ var ts; if (localSymbol && localSymbol.escapedName === name && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) { // check if this symbol is already used var symbolId = getUniqueSymbolId(localSymbol); - symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name, /*isDefault*/ true)); + symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name, /*isNamespaceImport*/ true)); } } // "default" is a keyword and not a legal identifier for the import, so we don't expect it here @@ -88162,8 +88489,8 @@ var ts; var namespaceImportDeclaration; var namedImportDeclaration; var existingModuleSpecifier; - for (var _i = 0, declarations_14 = declarations; _i < declarations_14.length; _i++) { - var declaration = declarations_14[_i]; + for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) { + var declaration = declarations_13[_i]; if (declaration.kind === 238 /* ImportDeclaration */) { var namedBindings = declaration.importClause && declaration.importClause.namedBindings; if (namedBindings && namedBindings.kind === 240 /* NamespaceImport */) { @@ -88273,9 +88600,11 @@ var ts; : isNamespaceImport ? ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(ts.createIdentifier(symbolName))) : ts.createImportClause(/*name*/ undefined, ts.createNamedImports([ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(symbolName))])); - var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, ts.createLiteral(moduleSpecifierWithoutQuotes)); + var moduleSpecifierLiteral = ts.createLiteral(moduleSpecifierWithoutQuotes); + moduleSpecifierLiteral.singleQuote = getSingleQuoteStyleFromExistingImports(); + var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, moduleSpecifierLiteral); if (!lastImportDeclaration) { - changeTracker.insertNodeAt(sourceFile, sourceFile.getStart(), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); + changeTracker.insertNodeAt(sourceFile, getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); } else { changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: context.newLineCharacter }); @@ -88284,6 +88613,46 @@ var ts; // between the only import statement and user code. Otherwise just insert the statement because chances // are there are already a new line seperating code and import statements. return createCodeAction(ts.Diagnostics.Import_0_from_1, [symbolName, "\"" + moduleSpecifierWithoutQuotes + "\""], changeTracker.getChanges(), "NewImport", moduleSpecifierWithoutQuotes); + function getSourceFileImportLocation(node) { + // For a source file, it is possible there are detached comments we should not skip + var text = node.text; + var ranges = ts.getLeadingCommentRanges(text, 0); + if (!ranges) + return 0; + var position = 0; + // However we should still skip a pinned comment at the top + if (ranges.length && ranges[0].kind === 3 /* MultiLineCommentTrivia */ && ts.isPinnedComment(text, ranges[0])) { + position = ranges[0].end + 1; + ranges = ranges.slice(1); + } + // As well as any triple slash references + for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) { + var range = ranges_1[_i]; + if (range.kind === 2 /* SingleLineCommentTrivia */ && ts.isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { + position = range.end + 1; + continue; + } + break; + } + return position; + } + function getSingleQuoteStyleFromExistingImports() { + var firstModuleSpecifier = ts.forEach(sourceFile.statements, function (node) { + if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) { + if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { + return node.moduleSpecifier; + } + } + else if (ts.isImportEqualsDeclaration(node)) { + if (ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) { + return node.moduleReference.expression; + } + } + }); + if (firstModuleSpecifier) { + return sourceFile.text.charCodeAt(firstModuleSpecifier.getStart()) === 39 /* singleQuote */; + } + } function getModuleSpecifierForNewImport() { var fileName = sourceFile.fileName; var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName; @@ -88415,8 +88784,8 @@ var ts; } function getNodeModulePathParts(fullPath) { // If fullPath can't be valid module file within node_modules, returns undefined. - // Example of expected pattern: /base/path/node_modules/[otherpackage/node_modules/]package/[subdirectory/]file.js - // Returns indices: ^ ^ ^ ^ + // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js + // Returns indices: ^ ^ ^ ^ var topLevelNodeModulesIndex = 0; var topLevelPackageNameIndex = 0; var packageRootIndex = 0; @@ -88425,7 +88794,8 @@ var ts; (function (States) { States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; States[States["NodeModules"] = 1] = "NodeModules"; - States[States["PackageContent"] = 2] = "PackageContent"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; })(States || (States = {})); var partStart = 0; var partEnd = 0; @@ -88442,15 +88812,21 @@ var ts; } break; case 1 /* NodeModules */: - packageRootIndex = partEnd; - state = 2 /* PackageContent */; + case 2 /* Scope */: + if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { + state = 2 /* Scope */; + } + else { + packageRootIndex = partEnd; + state = 3 /* PackageContent */; + } break; - case 2 /* PackageContent */: + case 3 /* PackageContent */: if (fullPath.indexOf("/node_modules/", partStart) === partStart) { state = 1 /* NodeModules */; } else { - state = 2 /* PackageContent */; + state = 3 /* PackageContent */; } break; } @@ -88807,231 +89183,1211 @@ var ts; (function (ts) { var refactor; (function (refactor) { - var actionName = "convert"; - var convertFunctionToES6Class = { - name: "Convert to ES2015 class", - description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, - getEditsForAction: getEditsForAction, - getAvailableActions: getAvailableActions - }; - refactor.registerRefactor(convertFunctionToES6Class); - function getAvailableActions(context) { - if (!ts.isInJavaScriptFile(context.file)) { - return undefined; - } - var start = context.startPosition; - var node = ts.getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); - var checker = context.program.getTypeChecker(); - var symbol = checker.getSymbolAtLocation(node); - if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { - symbol = symbol.valueDeclaration.initializer.symbol; + var convertFunctionToES6Class; + (function (convertFunctionToES6Class_1) { + var actionName = "convert"; + var convertFunctionToES6Class = { + name: "Convert to ES2015 class", + description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, + getEditsForAction: getEditsForAction, + getAvailableActions: getAvailableActions + }; + refactor.registerRefactor(convertFunctionToES6Class); + function getAvailableActions(context) { + if (!ts.isInJavaScriptFile(context.file)) { + return undefined; + } + var start = context.startPosition; + var node = ts.getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); + var checker = context.program.getTypeChecker(); + var symbol = checker.getSymbolAtLocation(node); + if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = symbol.valueDeclaration.initializer.symbol; + } + if (symbol && (symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) { + return [ + { + name: convertFunctionToES6Class.name, + description: convertFunctionToES6Class.description, + actions: [ + { + description: convertFunctionToES6Class.description, + name: actionName + } + ] + } + ]; + } } - if (symbol && (symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) { - return [ - { - name: convertFunctionToES6Class.name, - description: convertFunctionToES6Class.description, - actions: [ - { - description: convertFunctionToES6Class.description, - name: actionName + function getEditsForAction(context, action) { + // Somehow wrong action got invoked? + if (actionName !== action) { + return undefined; + } + var start = context.startPosition; + var sourceFile = context.file; + var checker = context.program.getTypeChecker(); + var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + var ctorSymbol = checker.getSymbolAtLocation(token); + var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; + var deletedNodes = []; + var deletes = []; + if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) { + return undefined; + } + var ctorDeclaration = ctorSymbol.valueDeclaration; + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + var precedingNode; + var newClassDeclaration; + switch (ctorDeclaration.kind) { + case 228 /* FunctionDeclaration */: + precedingNode = ctorDeclaration; + deleteNode(ctorDeclaration); + newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); + break; + case 226 /* VariableDeclaration */: + precedingNode = ctorDeclaration.parent.parent; + if (ctorDeclaration.parent.declarations.length === 1) { + deleteNode(precedingNode); + } + else { + deleteNode(ctorDeclaration, /*inList*/ true); + } + newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); + break; + } + if (!newClassDeclaration) { + return undefined; + } + // Because the preceding node could be touched, we need to insert nodes before delete nodes. + changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); + for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { + var deleteCallback = deletes_1[_i]; + deleteCallback(); + } + return { + edits: changeTracker.getChanges() + }; + function deleteNode(node, inList) { + if (inList === void 0) { inList = false; } + if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { + // Parent node has already been deleted; do nothing + return; + } + deletedNodes.push(node); + if (inList) { + deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + } + else { + deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + } + } + function createClassElementsFromSymbol(symbol) { + var memberElements = []; + // all instance members are stored in the "member" array of symbol + if (symbol.members) { + symbol.members.forEach(function (member) { + var memberElement = createClassElement(member, /*modifiers*/ undefined); + if (memberElement) { + memberElements.push(memberElement); } - ] + }); } - ]; - } - } - function getEditsForAction(context, action) { - // Somehow wrong action got invoked? - if (actionName !== action) { - return undefined; + // all static members are stored in the "exports" array of symbol + if (symbol.exports) { + symbol.exports.forEach(function (member) { + var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]); + if (memberElement) { + memberElements.push(memberElement); + } + }); + } + return memberElements; + function shouldConvertDeclaration(_target, source) { + // Right now the only thing we can convert are function expressions - other values shouldn't get + // transformed. We can update this once ES public class properties are available. + return ts.isFunctionLike(source); + } + function createClassElement(symbol, modifiers) { + // both properties and methods are bound as property symbols + if (!(symbol.flags & 4 /* Property */)) { + return; + } + var memberDeclaration = symbol.valueDeclaration; + var assignmentBinaryExpression = memberDeclaration.parent; + if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { + return; + } + // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end + var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 /* ExpressionStatement */ + ? assignmentBinaryExpression.parent : assignmentBinaryExpression; + deleteNode(nodeToDelete); + if (!assignmentBinaryExpression.right) { + return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, + /*type*/ undefined, /*initializer*/ undefined); + } + switch (assignmentBinaryExpression.right.kind) { + case 186 /* FunctionExpression */: { + var functionExpression = assignmentBinaryExpression.right; + var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, + /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); + copyComments(assignmentBinaryExpression, method); + return method; + } + case 187 /* ArrowFunction */: { + var arrowFunction = assignmentBinaryExpression.right; + var arrowFunctionBody = arrowFunction.body; + var bodyBlock = void 0; + // case 1: () => { return [1,2,3] } + if (arrowFunctionBody.kind === 207 /* Block */) { + bodyBlock = arrowFunctionBody; + } + else { + var expression = arrowFunctionBody; + bodyBlock = ts.createBlock([ts.createReturn(expression)]); + } + var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, + /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); + copyComments(assignmentBinaryExpression, method); + return method; + } + default: { + // Don't try to declare members in JavaScript files + if (ts.isSourceFileJavaScript(sourceFile)) { + return; + } + var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, + /*type*/ undefined, assignmentBinaryExpression.right); + copyComments(assignmentBinaryExpression.parent, prop); + return prop; + } + } + } + } + function copyComments(sourceNode, targetNode) { + ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { + if (kind === 3 /* MultiLineCommentTrivia */) { + // Remove leading /* + pos += 2; + // Remove trailing */ + end -= 2; + } + else { + // Remove leading // + pos += 2; + } + ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); + }); + } + function createClassFromVariableDeclaration(node) { + var initializer = node.initializer; + if (!initializer || initializer.kind !== 186 /* FunctionExpression */) { + return undefined; + } + if (node.name.kind !== 71 /* Identifier */) { + return undefined; + } + var memberElements = createClassElementsFromSymbol(initializer.symbol); + if (initializer.body) { + memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); + } + var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, + /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); + // Don't call copyComments here because we'll already leave them in place + return cls; + } + function createClassFromFunctionDeclaration(node) { + var memberElements = createClassElementsFromSymbol(ctorSymbol); + if (node.body) { + memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); + } + var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, + /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); + // Don't call copyComments here because we'll already leave them in place + return cls; + } } - var start = context.startPosition; - var sourceFile = context.file; - var checker = context.program.getTypeChecker(); - var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); - var ctorSymbol = checker.getSymbolAtLocation(token); - var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; - var deletedNodes = []; - var deletes = []; - if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) { - return undefined; + })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {})); + })(refactor = ts.refactor || (ts.refactor = {})); +})(ts || (ts = {})); +/// +/// +/* @internal */ +var ts; +(function (ts) { + var refactor; + (function (refactor) { + var extractMethod; + (function (extractMethod_1) { + var extractMethod = { + name: "Extract Method", + description: ts.Diagnostics.Extract_function.message, + getAvailableActions: getAvailableActions, + getEditsForAction: getEditsForAction, + }; + refactor.registerRefactor(extractMethod); + /** Compute the associated code actions */ + function getAvailableActions(context) { + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: context.endPosition - context.startPosition }); + var targetRange = rangeToExtract.targetRange; + if (targetRange === undefined) { + return undefined; + } + var extractions = getPossibleExtractions(targetRange, context); + if (extractions === undefined) { + // No extractions possible + return undefined; + } + var actions = []; + var usedNames = ts.createMap(); + var i = 0; + for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { + var extr = extractions_1[_i]; + // Skip these since we don't have a way to report errors yet + if (extr.errors && extr.errors.length) { + continue; + } + // Don't issue refactorings with duplicated names. + // Scopes come back in "innermost first" order, so extractions will + // preferentially go into nearer scopes + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + if (!usedNames.has(description)) { + usedNames.set(description, true); + actions.push({ + description: description, + name: "scope_" + i + }); + } + // *do* increment i anyway because we'll look for the i-th scope + // later when actually doing the refactoring if the user requests it + i++; + } + if (actions.length === 0) { + return undefined; + } + return [{ + name: extractMethod.name, + description: extractMethod.description, + inlineable: true, + actions: actions + }]; } - var ctorDeclaration = ctorSymbol.valueDeclaration; - var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); - var precedingNode; - var newClassDeclaration; - switch (ctorDeclaration.kind) { - case 228 /* FunctionDeclaration */: - precedingNode = ctorDeclaration; - deleteNode(ctorDeclaration); - newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); - break; - case 226 /* VariableDeclaration */: - precedingNode = ctorDeclaration.parent.parent; - if (ctorDeclaration.parent.declarations.length === 1) { - deleteNode(precedingNode); + function getEditsForAction(context, actionName) { + var length = context.endPosition === undefined ? 0 : context.endPosition - context.startPosition; + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: length }); + var targetRange = rangeToExtract.targetRange; + var parsedIndexMatch = /^scope_(\d+)$/.exec(actionName); + ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); + var index = +parsedIndexMatch[1]; + ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); + var extractions = getPossibleExtractions(targetRange, context, index); + // Scope is no longer valid from when the user issued the refactor (??) + ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); + return ({ edits: extractions[0].changes }); + } + // Move these into diagnostic messages if they become user-facing + var Messages; + (function (Messages) { + function createMessage(message) { + return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message }; + } + Messages.CannotExtractFunction = createMessage("Cannot extract function."); + Messages.StatementOrExpressionExpected = createMessage("Statement or expression expected."); + Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements."); + Messages.CannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement."); + Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); + Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); + Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); + Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); + Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); + Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); + Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); + Messages.CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); + })(Messages || (Messages = {})); + var RangeFacts; + (function (RangeFacts) { + RangeFacts[RangeFacts["None"] = 0] = "None"; + RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn"; + RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator"; + RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; + RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; + /** + * The range is in a function which needs the 'static' modifier in a class + */ + RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; + })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + /** + * getRangeToExtract takes a span inside a text file and returns either an expression or an array + * of statements representing the minimum set of nodes needed to extract the entire span. This + * process may fail, in which case a set of errors is returned instead (these are currently + * not shown to the user, but can be used by us diagnostically) + */ + function getRangeToExtract(sourceFile, span) { + var length = span.length || 0; + // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. + // This may fail (e.g. you select two statements in the root of a source file) + var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span); + // Do the same for the ending position + var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span); + var declarations = []; + // We'll modify these flags as we walk the tree to collect data + // about what things need to be done as part of the extraction. + var rangeFacts = RangeFacts.None; + if (!start || !end) { + // cannot find either start or end node + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractFunction)] }; + } + if (start.parent !== end.parent) { + // handle cases like 1 + [2 + 3] + 4 + // user selection is marked with []. + // in this case 2 + 3 does not belong to the same tree node + // instead the shape of the tree looks like this: + // + + // / \ + // + 4 + // / \ + // + 3 + // / \ + // 1 2 + // in this case there is no such one node that covers ends of selection and is located inside the selection + // to handle this we check if both start and end of the selection belong to some binary operation + // and start node is parented by the parent of the end node + // if this is the case - expand the selection to the entire parent of end node (in this case it will be [1 + 2 + 3] + 4) + var startParent = ts.skipParentheses(start.parent); + var endParent = ts.skipParentheses(end.parent); + if (ts.isBinaryExpression(startParent) && ts.isBinaryExpression(endParent) && ts.isNodeDescendantOf(startParent, endParent)) { + start = end = endParent; } else { - deleteNode(ctorDeclaration, /*inList*/ true); + // start and end nodes belong to different subtrees + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); } - newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); - break; + } + if (start !== end) { + // start and end should be statements and parent should be either block or a source file + if (!isBlockLike(start.parent)) { + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); + } + var statements = []; + for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) { + var statement = _a[_i]; + if (statement === start || statements.length) { + var errors = checkNode(statement); + if (errors) { + return { errors: errors }; + } + statements.push(statement); + } + if (statement === end) { + break; + } + } + return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } }; + } + else { + // We have a single node (start) + var errors = checkRootNode(start) || checkNode(start); + if (errors) { + return { errors: errors }; + } + // If our selection is the expression in an ExpressionStatement, expand + // the selection to include the enclosing Statement (this stops us + // from trying to care about the return value of the extracted function + // and eliminates double semicolon insertion in certain scenarios) + var range = ts.isStatement(start) + ? [start] + : start.parent && start.parent.kind === 210 /* ExpressionStatement */ + ? [start.parent] + : start; + return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + } + function createErrorResult(sourceFile, start, length, message) { + return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; + } + function checkRootNode(node) { + if (ts.isIdentifier(node)) { + return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; + } + return undefined; + } + function checkForStaticContext(nodeToCheck, containingClass) { + var current = nodeToCheck; + while (current !== containingClass) { + if (current.kind === 149 /* PropertyDeclaration */) { + if (ts.hasModifier(current, 32 /* Static */)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 146 /* Parameter */) { + var ctorOrMethod = ts.getContainingFunction(current); + if (ctorOrMethod.kind === 152 /* Constructor */) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 151 /* MethodDeclaration */) { + if (ts.hasModifier(current, 32 /* Static */)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + } + current = current.parent; + } + } + // Verifies whether we can actually extract this node or not. + function checkNode(nodeToCheck) { + var PermittedJumps; + (function (PermittedJumps) { + PermittedJumps[PermittedJumps["None"] = 0] = "None"; + PermittedJumps[PermittedJumps["Break"] = 1] = "Break"; + PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue"; + PermittedJumps[PermittedJumps["Return"] = 4] = "Return"; + })(PermittedJumps || (PermittedJumps = {})); + if (!ts.isStatement(nodeToCheck) && !(ts.isExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)]; + } + if (ts.isInAmbientContext(nodeToCheck)) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)]; + } + // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default) + var containingClass = ts.getContainingClass(nodeToCheck); + if (containingClass) { + checkForStaticContext(nodeToCheck, containingClass); + } + var errors; + var permittedJumps = 4 /* Return */; + var seenLabels; + visit(nodeToCheck); + return errors; + function visit(node) { + if (errors) { + // already found an error - can stop now + return true; + } + if (ts.isDeclaration(node)) { + var declaringNode = (node.kind === 226 /* VariableDeclaration */) ? node.parent.parent : node; + if (ts.hasModifier(declaringNode, 1 /* Export */)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + return true; + } + declarations.push(node.symbol); + } + // Some things can't be extracted in certain situations + switch (node.kind) { + case 238 /* ImportDeclaration */: + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + case 97 /* SuperKeyword */: + // For a super *constructor call*, we have to be extracting the entire class, + // but a super *method call* simply implies a 'this' reference + if (node.parent.kind === 181 /* CallExpression */) { + // Super constructor call + var containingClass_1 = ts.getContainingClass(node); + if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + } + } + else { + rangeFacts |= RangeFacts.UsesThis; + } + break; + } + if (!node || ts.isFunctionLike(node) || ts.isClassLike(node)) { + switch (node.kind) { + case 228 /* FunctionDeclaration */: + case 229 /* ClassDeclaration */: + if (node.parent.kind === 265 /* SourceFile */ && node.parent.externalModuleIndicator === undefined) { + // You cannot extract global declarations + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope)); + } + break; + } + // do not dive into functions or classes + return false; + } + var savedPermittedJumps = permittedJumps; + if (node.parent) { + switch (node.parent.kind) { + case 211 /* IfStatement */: + if (node.parent.thenStatement === node || node.parent.elseStatement === node) { + // forbid all jumps inside thenStatement or elseStatement + permittedJumps = 0 /* None */; + } + break; + case 224 /* TryStatement */: + if (node.parent.tryBlock === node) { + // forbid all jumps inside try blocks + permittedJumps = 0 /* None */; + } + else if (node.parent.finallyBlock === node) { + // allow unconditional returns from finally blocks + permittedJumps = 4 /* Return */; + } + break; + case 260 /* CatchClause */: + if (node.parent.block === node) { + // forbid all jumps inside the block of catch clause + permittedJumps = 0 /* None */; + } + break; + case 257 /* CaseClause */: + if (node.expression !== node) { + // allow unlabeled break inside case clauses + permittedJumps |= 1 /* Break */; + } + break; + default: + if (ts.isIterationStatement(node.parent, /*lookInLabeledStatements*/ false)) { + if (node.parent.statement === node) { + // allow unlabeled break/continue inside loops + permittedJumps |= 1 /* Break */ | 2 /* Continue */; + } + } + break; + } + } + switch (node.kind) { + case 169 /* ThisType */: + case 99 /* ThisKeyword */: + rangeFacts |= RangeFacts.UsesThis; + break; + case 222 /* LabeledStatement */: + { + var label = node.label; + (seenLabels || (seenLabels = [])).push(label.escapedText); + ts.forEachChild(node, visit); + seenLabels.pop(); + break; + } + case 218 /* BreakStatement */: + case 217 /* ContinueStatement */: + { + var label = node.label; + if (label) { + if (!ts.contains(seenLabels, label.escapedText)) { + // attempts to jump to label that is not in range to be extracted + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); + } + } + else { + if (!(permittedJumps & (218 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) { + // attempt to break or continue in a forbidden context + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements)); + } + } + break; + } + case 191 /* AwaitExpression */: + rangeFacts |= RangeFacts.IsAsyncFunction; + break; + case 197 /* YieldExpression */: + rangeFacts |= RangeFacts.IsGenerator; + break; + case 219 /* ReturnStatement */: + if (permittedJumps & 4 /* Return */) { + rangeFacts |= RangeFacts.HasReturn; + } + else { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement)); + } + break; + default: + ts.forEachChild(node, visit); + break; + } + permittedJumps = savedPermittedJumps; + } + } } - if (!newClassDeclaration) { - return undefined; + extractMethod_1.getRangeToExtract = getRangeToExtract; + function isValidExtractionTarget(node) { + // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method + return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); + } + /** + * Computes possible places we could extract the function into. For example, + * you may be able to extract into a class method *or* local closure *or* namespace function, + * depending on what's in the extracted body. + */ + function collectEnclosingScopes(range) { + var current = isReadonlyArray(range.range) ? ts.firstOrUndefined(range.range) : range.range; + if (range.facts & RangeFacts.UsesThis) { + // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class + var containingClass = ts.getContainingClass(current); + if (containingClass) { + return [containingClass]; + } + } + var start = current; + var scopes = undefined; + while (current) { + // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of. + // Walk up to the closest parent of a place where we can logically put a sibling: + // * Function declaration + // * Class declaration or expression + // * Module/namespace or source file + if (current !== start && isValidExtractionTarget(current)) { + (scopes = scopes || []).push(current); + } + // A function parameter's initializer is actually in the outer scope, not the function declaration + if (current && current.parent && current.parent.kind === 146 /* Parameter */) { + // Skip all the way to the outer scope of the function that declared this parameter + current = ts.findAncestor(current, function (parent) { return ts.isFunctionLike(parent); }).parent; + } + else { + current = current.parent; + } + } + return scopes; } - // Because the preceding node could be touched, we need to insert nodes before delete nodes. - changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); - for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { - var deleteCallback = deletes_1[_i]; - deleteCallback(); + extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; + /** + * Given a piece of text to extract ('targetRange'), computes a list of possible extractions. + * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes + * or an error explaining why we can't extract into that scope. + */ + function getPossibleExtractions(targetRange, context, requestedChangesIndex) { + if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + var sourceFile = context.file; + if (targetRange === undefined) { + return undefined; + } + var scopes = collectEnclosingScopes(targetRange); + if (scopes === undefined) { + return undefined; + } + var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); + var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; + context.cancellationToken.throwIfCancellationRequested(); + if (requestedChangesIndex !== undefined) { + if (errorsPerScope[requestedChangesIndex].length) { + return undefined; + } + return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; + } + else { + return scopes.map(function (scope, i) { + var errors = errorsPerScope[i]; + if (errors.length) { + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + errors: errors + }; + } + return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; + }); + } } - return { - edits: changeTracker.getChanges() - }; - function deleteNode(node, inList) { - if (inList === void 0) { inList = false; } - if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { - // Parent node has already been deleted; do nothing - return; + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getDescriptionForScope(scope) { + if (ts.isFunctionLike(scope)) { + switch (scope.kind) { + case 152 /* Constructor */: + return "constructor"; + case 186 /* FunctionExpression */: + return scope.name + ? "function expression " + scope.name.getText() + : "anonymous function expression"; + case 228 /* FunctionDeclaration */: + return "function " + scope.name.getText(); + case 187 /* ArrowFunction */: + return "arrow function"; + case 151 /* MethodDeclaration */: + return "method " + scope.name.getText(); + case 153 /* GetAccessor */: + return "get " + scope.name.getText(); + case 154 /* SetAccessor */: + return "set " + scope.name.getText(); + } + } + else if (isModuleBlock(scope)) { + return "namespace " + scope.parent.name.getText(); + } + else if (ts.isClassLike(scope)) { + return scope.kind === 229 /* ClassDeclaration */ + ? "class " + scope.name.text + : scope.name.text + ? "class expression " + scope.name.text + : "anonymous class expression"; } - deletedNodes.push(node); - if (inList) { - deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + else if (ts.isSourceFile(scope)) { + return "file '" + scope.fileName + "'"; } else { - deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + return "unknown"; } } - function createClassElementsFromSymbol(symbol) { - var memberElements = []; - // all instance members are stored in the "member" array of symbol - if (symbol.members) { - symbol.members.forEach(function (member) { - var memberElement = createClassElement(member, /*modifiers*/ undefined); - if (memberElement) { - memberElements.push(memberElement); + function getUniqueName(isNameOkay) { + var functionNameText = "newFunction"; + if (isNameOkay(functionNameText)) { + return functionNameText; + } + var i = 1; + while (!isNameOkay(functionNameText = "newFunction_" + i)) { + i++; + } + return functionNameText; + } + function extractFunctionInScope(node, scope, _a, range, context) { + var usagesInScope = _a.usages, substitutions = _a.substitutions; + var checker = context.program.getTypeChecker(); + // Make a unique name for the extracted function + var file = scope.getSourceFile(); + var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var isJS = ts.isInJavaScriptFile(scope); + var functionName = ts.createIdentifier(functionNameText); + var functionReference = ts.createIdentifier(functionNameText); + var returnType = undefined; + var parameters = []; + var callArguments = []; + var writes; + usagesInScope.forEach(function (usage, name) { + var typeNode = undefined; + if (!isJS) { + var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); + // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" + type = checker.getBaseTypeOfLiteralType(type); + typeNode = checker.typeToTypeNode(type, node, ts.NodeBuilderFlags.NoTruncation); + } + var paramDecl = ts.createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + /*name*/ name, + /*questionToken*/ undefined, typeNode); + parameters.push(paramDecl); + if (usage.usage === 2 /* Write */) { + (writes || (writes = [])).push(usage); + } + callArguments.push(ts.createIdentifier(name)); + }); + // Provide explicit return types for contexutally-typed functions + // to avoid problems when there are literal types present + if (ts.isExpression(node) && !isJS) { + var contextualType = checker.getContextualType(node); + returnType = checker.typeToTypeNode(contextualType); + } + var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var newFunction; + if (ts.isClassLike(scope)) { + // always create private method in TypeScript files + var modifiers = isJS ? [] : [ts.createToken(112 /* PrivateKeyword */)]; + if (range.facts & RangeFacts.InStaticRegion) { + modifiers.push(ts.createToken(115 /* StaticKeyword */)); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + modifiers.push(ts.createToken(120 /* AsyncKeyword */)); + } + newFunction = ts.createMethod( + /*decorators*/ undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, + /*questionToken*/ undefined, + /*typeParameters*/ [], parameters, returnType, body); + } + else { + newFunction = ts.createFunctionDeclaration( + /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, + /*typeParameters*/ [], parameters, returnType, body); + } + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + // insert function at the end of the scope + changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); + var newNodes = []; + // replace range with function call + var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, + /*typeArguments*/ undefined, callArguments); + if (range.facts & RangeFacts.IsGenerator) { + call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + call = ts.createAwait(call); + } + if (writes) { + if (returnValueProperty) { + // has both writes and return, need to create variable declaration to hold return value; + newNodes.push(ts.createVariableStatement( + /*modifiers*/ undefined, [ts.createVariableDeclaration(returnValueProperty, ts.createKeywordTypeNode(119 /* AnyKeyword */))])); + } + var assignments = getPropertyAssignmentsForWrites(writes); + if (returnValueProperty) { + assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty)); + } + // propagate writes back + if (assignments.length === 1) { + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); + } + else { + newNodes.push(ts.createStatement(ts.createBinary(assignments[0].name, 58 /* EqualsToken */, call))); + } + } + else { + // emit e.g. + // { a, b, __return } = newFunction(a, b); + // return __return; + newNodes.push(ts.createStatement(ts.createBinary(ts.createObjectLiteral(assignments), 58 /* EqualsToken */, call))); + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); } + } + } + else { + if (range.facts & RangeFacts.HasReturn) { + newNodes.push(ts.createReturn(call)); + } + else if (isReadonlyArray(range.range)) { + newNodes.push(ts.createStatement(call)); + } + else { + newNodes.push(call); + } + } + if (isReadonlyArray(range.range)) { + changeTracker.replaceNodesWithNodes(context.file, range.range, newNodes, { + nodeSeparator: context.newLineCharacter, + suffix: context.newLineCharacter // insert newline only when replacing statements }); } - // all static members are stored in the "exports" array of symbol - if (symbol.exports) { - symbol.exports.forEach(function (member) { - var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]); - if (memberElement) { - memberElements.push(memberElement); + else { + changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); + } + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + changes: changeTracker.getChanges() + }; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); + } + function generateReturnValueProperty() { + return "__return"; + } + function transformFunctionBody(body) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + // already block, no writes to propagate back, no substitutions - can use node as is + return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { + // add return at the end to propagate writes back in case if control flow falls out of the function body + // it is ok to know that range has at least one return since it we only allow unconditional returns + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); + } + } + return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 /* ReturnStatement */ && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = generateReturnValueProperty(); + } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); + } + else { + return ts.createReturn(ts.createObjectLiteral(assignments)); + } + } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } + } + } + } + extractMethod_1.extractFunctionInScope = extractFunctionInScope; + function isModuleBlock(n) { + return n.kind === 234 /* ModuleBlock */; + } + function isReadonlyArray(v) { + return ts.isArray(v); + } + /** + * Produces a range that spans the entirety of nodes, given a selection + * that might start/end in the middle of nodes. + * + * For example, when the user makes a selection like this + * v---v + * var someThing = foo + bar; + * this returns ^-------^ + */ + function getEnclosingTextRange(targetRange, sourceFile) { + return isReadonlyArray(targetRange.range) + ? { pos: targetRange.range[0].getStart(sourceFile), end: targetRange.range[targetRange.range.length - 1].getEnd() } + : targetRange.range; + } + var Usage; + (function (Usage) { + // value should be passed to extracted method + Usage[Usage["Read"] = 1] = "Read"; + // value should be passed to extracted method and propagated back + Usage[Usage["Write"] = 2] = "Write"; + })(Usage || (Usage = {})); + function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker) { + var usagesPerScope = []; + var substitutionsPerScope = []; + var errorsPerScope = []; + var visibleDeclarationsInExtractedRange = []; + // initialize results + for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) { + var _ = scopes_1[_i]; + usagesPerScope.push({ usages: ts.createMap(), substitutions: ts.createMap() }); + substitutionsPerScope.push(ts.createMap()); + errorsPerScope.push([]); + } + var seenUsages = ts.createMap(); + var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range; + var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] : ts.getEnclosingBlockScopeContainer(scopes[0]); + collectUsages(target); + var _loop_8 = function (i) { + var hasWrite = false; + var readonlyClassPropertyWrite = undefined; + usagesPerScope[i].usages.forEach(function (value) { + if (value.usage === 2 /* Write */) { + hasWrite = true; + if (value.symbol.flags & 106500 /* ClassMember */ && + value.symbol.valueDeclaration && + ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) { + readonlyClassPropertyWrite = value.symbol.valueDeclaration; + } } }); + if (hasWrite && !isReadonlyArray(targetRange.range) && ts.isExpression(targetRange.range)) { + errorsPerScope[i].push(ts.createDiagnosticForNode(targetRange.range, Messages.CannotCombineWritesAndReturns)); + } + else if (readonlyClassPropertyWrite && i > 0) { + errorsPerScope[i].push(ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotCombineWritesAndReturns)); + } + }; + for (var i = 0; i < scopes.length; i++) { + _loop_8(i); + } + // If there are any declarations in the extracted block that are used in the same enclosing + // lexical scope, we can't move the extraction "up" as those declarations will become unreachable + if (visibleDeclarationsInExtractedRange.length) { + ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); + } + return { target: target, usagesPerScope: usagesPerScope, errorsPerScope: errorsPerScope }; + function collectUsages(node, valueUsage) { + if (valueUsage === void 0) { valueUsage = 1 /* Read */; } + if (ts.isDeclaration(node) && node.symbol) { + visibleDeclarationsInExtractedRange.push(node.symbol); + } + if (ts.isAssignmentExpression(node)) { + // use 'write' as default usage for values + collectUsages(node.left, 2 /* Write */); + collectUsages(node.right); + } + else if (ts.isUnaryExpressionWithWrite(node)) { + collectUsages(node.operand, 2 /* Write */); + } + else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) { + // use 'write' as default usage for values + ts.forEachChild(node, collectUsages); + } + else if (ts.isIdentifier(node)) { + if (!node.parent) { + return; + } + if (ts.isQualifiedName(node.parent) && node !== node.parent.left) { + return; + } + if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { + return; + } + recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node)); + } + else { + ts.forEachChild(node, collectUsages); + } } - return memberElements; - function shouldConvertDeclaration(_target, source) { - // Right now the only thing we can convert are function expressions - other values shouldn't get - // transformed. We can update this once ES public class properties are available. - return ts.isFunctionLike(source); + function recordUsage(n, usage, isTypeNode) { + var symbolId = recordUsagebySymbol(n, usage, isTypeNode); + if (symbolId) { + for (var i = 0; i < scopes.length; i++) { + // push substitution from map to map to simplify rewriting + var substitition = substitutionsPerScope[i].get(symbolId); + if (substitition) { + usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitition); + } + } + } } - function createClassElement(symbol, modifiers) { - // both properties and methods are bound as property symbols - if (!(symbol.flags & 4 /* Property */)) { - return; + function recordUsagebySymbol(identifier, usage, isTypeName) { + var symbol = checker.getSymbolAtLocation(identifier); + if (!symbol) { + // cannot find symbol - do nothing + return undefined; } - var memberDeclaration = symbol.valueDeclaration; - var assignmentBinaryExpression = memberDeclaration.parent; - if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { - return; + var symbolId = ts.getSymbolId(symbol).toString(); + var lastUsage = seenUsages.get(symbolId); + // there are two kinds of value usages + // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter + // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and + // returned as a return value + // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read' + // since all information is already recorded + if (lastUsage && lastUsage >= usage) { + return symbolId; + } + seenUsages.set(symbolId, usage); + if (lastUsage) { + // if we get here this means that we are trying to handle 'write' and 'read' was already processed + // walk scopes and update existing records. + for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) { + var perScope = usagesPerScope_1[_i]; + var prevEntry = perScope.usages.get(identifier.text); + if (prevEntry) { + perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); + } + } + return symbolId; + } + // find first declaration in this file + var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; }); + if (!declInFile) { + return undefined; } - // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end - var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 /* ExpressionStatement */ - ? assignmentBinaryExpression.parent : assignmentBinaryExpression; - deleteNode(nodeToDelete); - if (!assignmentBinaryExpression.right) { - return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, - /*type*/ undefined, /*initializer*/ undefined); - } - switch (assignmentBinaryExpression.right.kind) { - case 186 /* FunctionExpression */: { - var functionExpression = assignmentBinaryExpression.right; - var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, - /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); - copyComments(assignmentBinaryExpression, method); - return method; - } - case 187 /* ArrowFunction */: { - var arrowFunction = assignmentBinaryExpression.right; - var arrowFunctionBody = arrowFunction.body; - var bodyBlock = void 0; - // case 1: () => { return [1,2,3] } - if (arrowFunctionBody.kind === 207 /* Block */) { - bodyBlock = arrowFunctionBody; + if (ts.rangeContainsRange(enclosingTextRange, declInFile)) { + // declaration is located in range to be extracted - do nothing + return undefined; + } + if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) { + // this is write to a reference located outside of the target scope and range is extracted into generator + // currently this is unsupported scenario + for (var _a = 0, errorsPerScope_1 = errorsPerScope; _a < errorsPerScope_1.length; _a++) { + var errors = errorsPerScope_1[_a]; + errors.push(ts.createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators)); + } + } + for (var i = 0; i < scopes.length; i++) { + var scope = scopes[i]; + var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + if (resolvedSymbol === symbol) { + continue; + } + if (!substitutionsPerScope[i].has(symbolId)) { + var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName); + if (substitution) { + substitutionsPerScope[i].set(symbolId, substitution); } - else { - var expression = arrowFunctionBody; - bodyBlock = ts.createBlock([ts.createReturn(expression)]); + else if (isTypeName) { + errorsPerScope[i].push(ts.createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope)); } - var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, - /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); - copyComments(assignmentBinaryExpression, method); - return method; - } - default: { - // Don't try to declare members in JavaScript files - if (ts.isSourceFileJavaScript(sourceFile)) { - return; + else { + usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } - var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, - /*type*/ undefined, assignmentBinaryExpression.right); - copyComments(assignmentBinaryExpression.parent, prop); - return prop; } } + return symbolId; } - } - function copyComments(sourceNode, targetNode) { - ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { - if (kind === 3 /* MultiLineCommentTrivia */) { - // Remove leading /* - pos += 2; - // Remove trailing */ - end -= 2; + function checkForUsedDeclarations(node) { + // If this node is entirely within the original extraction range, we don't need to do anything. + if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) { + return; + } + // Otherwise check and recurse. + var sym = checker.getSymbolAtLocation(node); + if (sym && visibleDeclarationsInExtractedRange.some(function (d) { return d === sym; })) { + for (var _i = 0, errorsPerScope_2 = errorsPerScope; _i < errorsPerScope_2.length; _i++) { + var scope = errorsPerScope_2[_i]; + scope.push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + } + return true; } else { - // Remove leading // - pos += 2; + ts.forEachChild(node, checkForUsedDeclarations); } - ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); - }); + } + function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) { + if (!symbol) { + return undefined; + } + if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) { + return ts.createIdentifier(symbol.name); + } + var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); + if (prefix === undefined) { + return undefined; + } + return isTypeNode ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name)) : ts.createPropertyAccess(prefix, symbol.name); + } } - function createClassFromVariableDeclaration(node) { - var initializer = node.initializer; - if (!initializer || initializer.kind !== 186 /* FunctionExpression */) { + function getParentNodeInSpan(node, file, span) { + if (!node) return undefined; + while (node.parent) { + if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { + return node; + } + node = node.parent; } - if (node.name.kind !== 71 /* Identifier */) { - return undefined; + } + function spanContainsNode(span, node, file) { + return ts.textSpanContainsPosition(span, node.getStart(file)) && + node.getEnd() <= ts.textSpanEnd(span); + } + /** + * Computes whether or not a node represents an expression in a position where it could + * be extracted. + * The isExpression() in utilities.ts returns some false positives we need to handle, + * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression + * in the sense of something that you could extract on + */ + function isExtractableExpression(node) { + switch (node.parent.kind) { + case 264 /* EnumMember */: + return false; } - var memberElements = createClassElementsFromSymbol(initializer.symbol); - if (initializer.body) { - memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); + switch (node.kind) { + case 9 /* StringLiteral */: + return node.parent.kind !== 238 /* ImportDeclaration */ && + node.parent.kind !== 242 /* ImportSpecifier */; + case 198 /* SpreadElement */: + case 174 /* ObjectBindingPattern */: + case 176 /* BindingElement */: + return false; + case 71 /* Identifier */: + return node.parent.kind !== 176 /* BindingElement */ && + node.parent.kind !== 242 /* ImportSpecifier */ && + node.parent.kind !== 246 /* ExportSpecifier */; } - var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, - /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); - // Don't call copyComments here because we'll already leave them in place - return cls; + return true; } - function createClassFromFunctionDeclaration(node) { - var memberElements = createClassElementsFromSymbol(ctorSymbol); - if (node.body) { - memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); + function isBlockLike(node) { + switch (node.kind) { + case 207 /* Block */: + case 265 /* SourceFile */: + case 234 /* ModuleBlock */: + case 257 /* CaseClause */: + return true; + default: + return false; } - var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, - /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); - // Don't call copyComments here because we'll already leave them in place - return cls; } - } + })(extractMethod = refactor.extractMethod || (refactor.extractMethod = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /// +/// /// /// /// @@ -89074,7 +90430,7 @@ var ts; node.parent = parent; return node; } - var NodeObject = (function () { + var NodeObject = /** @class */ (function () { function NodeObject(kind, pos, end) { this.pos = pos; this.end = end; @@ -89227,7 +90583,7 @@ var ts; }; return NodeObject; }()); - var TokenOrIdentifierObject = (function () { + var TokenOrIdentifierObject = /** @class */ (function () { function TokenOrIdentifierObject(pos, end) { // Set properties in same order as NodeObject this.pos = pos; @@ -89282,7 +90638,7 @@ var ts; }; return TokenOrIdentifierObject; }()); - var SymbolObject = (function () { + var SymbolObject = /** @class */ (function () { function SymbolObject(flags, name) { this.flags = flags; this.escapedName = name; @@ -89320,7 +90676,7 @@ var ts; }; return SymbolObject; }()); - var TokenObject = (function (_super) { + var TokenObject = /** @class */ (function (_super) { __extends(TokenObject, _super); function TokenObject(kind, pos, end) { var _this = _super.call(this, pos, end) || this; @@ -89329,7 +90685,7 @@ var ts; } return TokenObject; }(TokenOrIdentifierObject)); - var IdentifierObject = (function (_super) { + var IdentifierObject = /** @class */ (function (_super) { __extends(IdentifierObject, _super); function IdentifierObject(_kind, pos, end) { return _super.call(this, pos, end) || this; @@ -89344,7 +90700,7 @@ var ts; return IdentifierObject; }(TokenOrIdentifierObject)); IdentifierObject.prototype.kind = 71 /* Identifier */; - var TypeObject = (function () { + var TypeObject = /** @class */ (function () { function TypeObject(checker, flags) { this.checker = checker; this.flags = flags; @@ -89386,7 +90742,7 @@ var ts; }; return TypeObject; }()); - var SignatureObject = (function () { + var SignatureObject = /** @class */ (function () { function SignatureObject(checker) { this.checker = checker; } @@ -89416,7 +90772,7 @@ var ts; }; return SignatureObject; }()); - var SourceFileObject = (function (_super) { + var SourceFileObject = /** @class */ (function (_super) { __extends(SourceFileObject, _super); function SourceFileObject(kind, pos, end) { return _super.call(this, kind, pos, end) || this; @@ -89587,7 +90943,7 @@ var ts; }; return SourceFileObject; }(NodeObject)); - var SourceMapSourceObject = (function () { + var SourceMapSourceObject = /** @class */ (function () { function SourceMapSourceObject(fileName, text, skipTrivia) { this.fileName = fileName; this.text = text; @@ -89656,7 +91012,7 @@ var ts; // Cache host information about script Should be refreshed // at each language service public entry point, since we don't know when // the set of scripts handled by the host changes. - var HostCache = (function () { + var HostCache = /** @class */ (function () { function HostCache(host, getCanonicalFileName) { this.host = host; // script id => script index @@ -89718,7 +91074,7 @@ var ts; }; return HostCache; }()); - var SyntaxTreeCache = (function () { + var SyntaxTreeCache = /** @class */ (function () { function SyntaxTreeCache(host) { this.host = host; } @@ -89813,7 +91169,7 @@ var ts; return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind); } ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile; - var CancellationTokenObject = (function () { + var CancellationTokenObject = /** @class */ (function () { function CancellationTokenObject(cancellationToken) { this.cancellationToken = cancellationToken; } @@ -89829,7 +91185,7 @@ var ts; }()); /* @internal */ /** A cancellation that throttles calls to the host */ - var ThrottledCancellationToken = (function () { + var ThrottledCancellationToken = /** @class */ (function () { function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) { if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; } this.hostCancellationToken = hostCancellationToken; @@ -89980,8 +91336,8 @@ var ts; if (program) { var oldSourceFiles = program.getSourceFiles(); var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings); - for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { - var oldSourceFile = oldSourceFiles_1[_i]; + for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) { + var oldSourceFile = oldSourceFiles_2[_i]; if (!newProgram.getSourceFile(oldSourceFile.fileName) || shouldCreateNewSourceFiles) { documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey); } @@ -90038,7 +91394,7 @@ var ts; // We do not support the scenario where a host can modify a registered // file's script kind, i.e. in one project some file is treated as ".ts" // and in another as ".js" - ts.Debug.assert(hostFileInformation.scriptKind === oldSourceFile.scriptKind, "Registered script kind (" + oldSourceFile.scriptKind + ") should match new script kind (" + hostFileInformation.scriptKind + ") for file: " + path); + ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path); return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind); } // We didn't already have the file. Fall through and acquire it from the registry. @@ -90777,12 +92133,17 @@ var ts; function getPropertySymbolsFromContextualType(typeChecker, node) { var objectLiteral = node.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(node.name)); - if (name && contextualType) { + return getPropertySymbolsFromType(contextualType, node.name); + } + ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + /* @internal */ + function getPropertySymbolsFromType(type, propName) { + var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName)); + if (name && type) { var result_10 = []; - var symbol = contextualType.getProperty(name); - if (contextualType.flags & 65536 /* Union */) { - ts.forEach(contextualType.types, function (t) { + var symbol = type.getProperty(name); + if (type.flags & 65536 /* Union */) { + ts.forEach(type.types, function (t) { var symbol = t.getProperty(name); if (symbol) { result_10.push(symbol); @@ -90797,7 +92158,7 @@ var ts; } return undefined; } - ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + ts.getPropertySymbolsFromType = getPropertySymbolsFromType; function isArgumentOfElementAccessExpression(node) { return node && node.parent && @@ -91352,7 +92713,7 @@ var ts; } } function spanInOpenParenToken(node) { - if (node.parent.kind === 212 /* DoStatement */ || + if (node.parent.kind === 212 /* DoStatement */ || // Go to while keyword and do action instead node.parent.kind === 181 /* CallExpression */ || node.parent.kind === 182 /* NewExpression */) { return spanInPreviousNode(node); @@ -91471,7 +92832,7 @@ var ts; logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message); } } - var ScriptSnapshotShimAdapter = (function () { + var ScriptSnapshotShimAdapter = /** @class */ (function () { function ScriptSnapshotShimAdapter(scriptSnapshotShim) { this.scriptSnapshotShim = scriptSnapshotShim; } @@ -91499,7 +92860,7 @@ var ts; }; return ScriptSnapshotShimAdapter; }()); - var LanguageServiceShimHostAdapter = (function () { + var LanguageServiceShimHostAdapter = /** @class */ (function () { function LanguageServiceShimHostAdapter(shimHost) { var _this = this; this.shimHost = shimHost; @@ -91623,7 +92984,7 @@ var ts; return LanguageServiceShimHostAdapter; }()); ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter; - var CoreServicesShimHostAdapter = (function () { + var CoreServicesShimHostAdapter = /** @class */ (function () { function CoreServicesShimHostAdapter(shimHost) { var _this = this; this.shimHost = shimHost; @@ -91688,7 +93049,7 @@ var ts; return JSON.stringify({ error: err }); } } - var ShimBase = (function () { + var ShimBase = /** @class */ (function () { function ShimBase(factory) { this.factory = factory; factory.registerShim(this); @@ -91712,7 +93073,7 @@ var ts; code: diagnostic.code }; } - var LanguageServiceShimObject = (function (_super) { + var LanguageServiceShimObject = /** @class */ (function (_super) { __extends(LanguageServiceShimObject, _super); function LanguageServiceShimObject(factory, host, languageService) { var _this = _super.call(this, factory) || this; @@ -91985,7 +93346,7 @@ var ts; function convertClassifications(classifications) { return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState }; } - var ClassifierShimObject = (function (_super) { + var ClassifierShimObject = /** @class */ (function (_super) { __extends(ClassifierShimObject, _super); function ClassifierShimObject(factory, logger) { var _this = _super.call(this, factory) || this; @@ -92012,7 +93373,7 @@ var ts; }; return ClassifierShimObject; }(ShimBase)); - var CoreServicesShimObject = (function (_super) { + var CoreServicesShimObject = /** @class */ (function (_super) { __extends(CoreServicesShimObject, _super); function CoreServicesShimObject(factory, logger, host) { var _this = _super.call(this, factory) || this; @@ -92119,7 +93480,7 @@ var ts; }; return CoreServicesShimObject; }(ShimBase)); - var TypeScriptServicesFactory = (function () { + var TypeScriptServicesFactory = /** @class */ (function () { function TypeScriptServicesFactory() { this._shims = []; } diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 392b7e36a07f9..c41b2e65a9552 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1210,7 +1210,7 @@ declare namespace ts { interface CatchClause extends Node { kind: SyntaxKind.CatchClause; parent?: TryStatement; - variableDeclaration: VariableDeclaration; + variableDeclaration?: VariableDeclaration; block: Block; } type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; @@ -1496,38 +1496,39 @@ declare namespace ts { interface FlowLock { locked?: boolean; } - interface AfterFinallyFlow extends FlowNode, FlowLock { + interface AfterFinallyFlow extends FlowNodeBase, FlowLock { antecedent: FlowNode; } - interface PreFinallyFlow extends FlowNode { + interface PreFinallyFlow extends FlowNodeBase { antecedent: FlowNode; lock: FlowLock; } - interface FlowNode { + type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + interface FlowNodeBase { flags: FlowFlags; id?: number; } - interface FlowStart extends FlowNode { + interface FlowStart extends FlowNodeBase { container?: FunctionExpression | ArrowFunction | MethodDeclaration; } - interface FlowLabel extends FlowNode { + interface FlowLabel extends FlowNodeBase { antecedents: FlowNode[]; } - interface FlowAssignment extends FlowNode { + interface FlowAssignment extends FlowNodeBase { node: Expression | VariableDeclaration | BindingElement; antecedent: FlowNode; } - interface FlowCondition extends FlowNode { + interface FlowCondition extends FlowNodeBase { expression: Expression; antecedent: FlowNode; } - interface FlowSwitchClause extends FlowNode { + interface FlowSwitchClause extends FlowNodeBase { switchStatement: SwitchStatement; clauseStart: number; clauseEnd: number; antecedent: FlowNode; } - interface FlowArrayMutation extends FlowNode { + interface FlowArrayMutation extends FlowNodeBase { node: CallExpression | BinaryExpression; antecedent: FlowNode; } @@ -1795,6 +1796,7 @@ declare namespace ts { AddUndefined = 8192, WriteClassExpressionAsTypeLiteral = 16384, InArrayType = 32768, + UseAliasDefinedOutsideCurrentScope = 65536, } enum SymbolFormatFlags { None = 0, @@ -2103,6 +2105,21 @@ declare namespace ts { NoDefault = 2, AnyDefault = 4, } + /** + * Ternary values are defined such that + * x & y is False if either x or y is False. + * x & y is Maybe if either x or y is Maybe, but neither x or y is False. + * x & y is True if both x and y are True. + * x | y is False if both x and y are False. + * x | y is Maybe if either x or y is Maybe, but neither x or y is True. + * x | y is True if either x or y is True. + */ + enum Ternary { + False = 0, + Maybe = 1, + True = -1, + } + type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary; interface JsFileExtensionInfo { extension: string; isMixedContent: boolean; @@ -2195,6 +2212,7 @@ declare namespace ts { outFile?: string; paths?: MapLike; preserveConstEnums?: boolean; + preserveSymlinks?: boolean; project?: string; reactNamespace?: string; jsxFactory?: string; @@ -2300,6 +2318,10 @@ declare namespace ts { readFile(fileName: string): string | undefined; trace?(s: string): void; directoryExists?(directoryName: string): boolean; + /** + * Resolve a symbolic link. + * @see https://nodejs.org/api/fs.html#fs_fs_realpathsync_path_options + */ realpath?(path: string): string; getCurrentDirectory?(): string; getDirectories?(path: string): string[]; @@ -2325,6 +2347,7 @@ declare namespace ts { /** * ResolvedModule with an explicitly provided `extension` property. * Prefer this over `ResolvedModule`. + * If changing this, remember to change `moduleResolutionIsEqualTo`. */ interface ResolvedModuleFull extends ResolvedModule { /** @@ -2332,6 +2355,21 @@ declare namespace ts { * This is optional for backwards-compatibility, but will be added if not provided. */ extension: Extension; + packageId?: PackageId; + } + /** + * Unique identifier with a package name and version. + * If changing this, remember to change `packageIdIsEqual`. + */ + interface PackageId { + /** + * Name of the package. + * Should not include `@types`. + * If accessing a non-index file, this should include its name e.g. "foo/bar". + */ + name: string; + /** Version of the package, e.g. "1.2.3" */ + version: string; } enum Extension { Ts = ".ts", @@ -2741,6 +2779,8 @@ declare namespace ts { function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; function isParameterPropertyDeclaration(node: Node): boolean; + function isEmptyBindingPattern(node: BindingName): node is BindingPattern; + function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; function getCombinedNodeFlags(node: Node): NodeFlags; /** @@ -3310,8 +3350,8 @@ declare namespace ts { function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray): DefaultClause; function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray): HeritageClause; function updateHeritageClause(node: HeritageClause, types: ReadonlyArray): HeritageClause; - function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block): CatchClause; - function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block): CatchClause; + function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; + function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index eb71a73ba466d..3b497d4c471b4 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -511,7 +511,7 @@ var ts; FlowFlags[FlowFlags["Label"] = 12] = "Label"; FlowFlags[FlowFlags["Condition"] = 96] = "Condition"; })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {})); - var OperationCanceledException = (function () { + var OperationCanceledException = /** @class */ (function () { function OperationCanceledException() { } return OperationCanceledException; @@ -575,6 +575,8 @@ var ts; TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined"; TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral"; TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType"; + TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope"; + // even though `T` can't be accessed in the current scope. })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {})); var SymbolFormatFlags; (function (SymbolFormatFlags) { @@ -860,6 +862,21 @@ var ts; InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault"; InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault"; })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {})); + /** + * Ternary values are defined such that + * x & y is False if either x or y is False. + * x & y is Maybe if either x or y is Maybe, but neither x or y is False. + * x & y is True if both x and y are True. + * x | y is False if both x and y are False. + * x | y is Maybe if either x or y is Maybe, but neither x or y is True. + * x | y is True if either x or y is True. + */ + var Ternary; + (function (Ternary) { + Ternary[Ternary["False"] = 0] = "False"; + Ternary[Ternary["Maybe"] = 1] = "Maybe"; + Ternary[Ternary["True"] = -1] = "True"; + })(Ternary = ts.Ternary || (ts.Ternary = {})); /* @internal */ var SpecialPropertyAssignmentKind; (function (SpecialPropertyAssignmentKind) { @@ -1331,25 +1348,10 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); /* @internal */ (function (ts) { - /** - * Ternary values are defined such that - * x & y is False if either x or y is False. - * x & y is Maybe if either x or y is Maybe, but neither x or y is False. - * x & y is True if both x and y are True. - * x | y is False if both x and y are False. - * x | y is Maybe if either x or y is Maybe, but neither x or y is True. - * x | y is True if either x or y is True. - */ - var Ternary; - (function (Ternary) { - Ternary[Ternary["False"] = 0] = "False"; - Ternary[Ternary["Maybe"] = 1] = "Maybe"; - Ternary[Ternary["True"] = -1] = "True"; - })(Ternary = ts.Ternary || (ts.Ternary = {})); // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined; // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". @@ -1403,7 +1405,7 @@ var ts; var MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); // Keep the class inside a function so it doesn't get compiled if it's not used. function shimMap() { - var MapIterator = (function () { + var MapIterator = /** @class */ (function () { function MapIterator(data, selector) { this.index = 0; this.data = data; @@ -1420,7 +1422,7 @@ var ts; }; return MapIterator; }()); - return (function () { + return /** @class */ (function () { function class_1() { this.data = createDictionaryObject(); this.size = 0; @@ -1668,10 +1670,9 @@ var ts; ts.removeWhere = removeWhere; function filterMutate(array, f) { var outIndex = 0; - for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { - var item = array_3[_i]; - if (f(item)) { - array[outIndex] = item; + for (var i = 0; i < array.length; i++) { + if (f(array[i], i, array)) { + array[outIndex] = array[i]; outIndex++; } } @@ -1722,8 +1723,8 @@ var ts; var result; if (array) { result = []; - for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { - var v = array_4[_i]; + for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { + var v = array_3[_i]; if (v) { if (isArray(v)) { addRange(result, v); @@ -1799,11 +1800,13 @@ var ts; ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; - for (var i = 0; i < array.length; i++) { - var item = array[i]; - var mapped = mapFn(item, i); - if (mapped !== undefined) { - result.push(mapped); + if (array) { + for (var i = 0; i < array.length; i++) { + var item = array[i]; + var mapped = mapFn(item, i); + if (mapped !== undefined) { + result.push(mapped); + } } } return result; @@ -1882,8 +1885,8 @@ var ts; function some(array, predicate) { if (array) { if (predicate) { - for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { - var v = array_5[_i]; + for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { + var v = array_4[_i]; if (predicate(v)) { return true; } @@ -1909,8 +1912,8 @@ var ts; var result; if (array) { result = []; - loop: for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { - var item = array_6[_i]; + loop: for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { + var item = array_5[_i]; for (var _a = 0, result_1 = result; _a < result_1.length; _a++) { var res = result_1[_a]; if (areEqual ? areEqual(res, item) : res === item) { @@ -2003,8 +2006,8 @@ var ts; ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; - for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { - var v = array_7[_i]; + for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { + var v = array_6[_i]; // Note: we need the following type assertion because of GH #17069 result += v[prop]; } @@ -2336,8 +2339,8 @@ var ts; ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); - for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { - var value = array_8[_i]; + for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { + var value = array_7[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; @@ -2502,11 +2505,11 @@ var ts; ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { var end = start + length; - Debug.assert(start >= 0, "start must be non-negative, is " + start); - Debug.assert(length >= 0, "length must be non-negative, is " + length); + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); if (file) { - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + Debug.assertLessThanOrEqual(start, file.text.length); + Debug.assertLessThanOrEqual(end, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { @@ -3055,14 +3058,43 @@ var ts; // proof. var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42 /* asterisk */, 63 /* question */]; - /** - * Matches any single directory segment unless it is the last segment and a .min.js file - * Breakdown: - * [^./] # matches everything up to the first . character (excluding directory seperators) - * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension - */ - var singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; - var singleAsteriskRegexFragmentOther = "[^/]*"; + /* @internal */ + ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; + var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; + var filesMatcher = { + /** + * Matches any single directory segment unless it is the last segment and a .min.js file + * Breakdown: + * [^./] # matches everything up to the first . character (excluding directory seperators) + * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension + */ + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + /** + * Regex for the ** wildcard. Matches any number of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } + }; + var directoriesMatcher = { + singleAsteriskRegexFragment: "[^/]*", + /** + * Regex for the ** wildcard. Matches any number of subdirectories. When used for including + * files or directories, does not match subdirectories that start with a . character + */ + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } + }; + var excludeMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } + }; + var wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher + }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { @@ -3078,15 +3110,8 @@ var ts; if (specs === undefined || specs.length === 0) { return undefined; } - var replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther; - var singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther; - /** - * Regex for the ** wildcard. Matches any number of subdirectories. When used for including - * files or directories, does not match subdirectories that start with a . character - */ - var doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; return flatMap(specs, function (spec) { - return spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); + return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } /** @@ -3097,7 +3122,8 @@ var ts; return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; - function getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter) { + function getSubPatternFromSpec(spec, basePath, usage, _a) { + var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; @@ -3131,19 +3157,33 @@ var ts; subpattern += ts.directorySeparator; } if (usage !== "exclude") { + var componentPattern = ""; // The * and ? wildcards should not match directories or files that start with . if they // appear first in a component. Dotted directories and files can be included explicitly // like so: **/.*/.* if (component.charCodeAt(0) === 42 /* asterisk */) { - subpattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63 /* question */) { - subpattern += "[^./]"; + componentPattern += "[^./]"; component = component.substr(1); } + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + // Patterns should not include subfolders like node_modules unless they are + // explicitly included as part of the path. + // + // As an optimization, if the component pattern is the same as the component, + // then there definitely were no wildcard characters and we do not need to + // add the exclusion pattern. + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } hasWrittenComponent = true; } @@ -3153,12 +3193,6 @@ var ts; } return subpattern; } - function replaceWildCardCharacterFiles(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentFiles); - } - function replaceWildCardCharacterOther(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentOther); - } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } @@ -3319,14 +3353,7 @@ var ts; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } - var extensions = allSupportedExtensions.slice(0); - for (var _i = 0, extraFileExtensions_1 = extraFileExtensions; _i < extraFileExtensions_1.length; _i++) { - var extInfo = extraFileExtensions_1[_i]; - if (extensions.indexOf(extInfo.extension) === -1) { - extensions.push(extInfo.extension); - } - } - return extensions; + return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; }))); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { @@ -3481,12 +3508,37 @@ var ts; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + verboseDebugInfo(); + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; + function assertEqual(a, b, msg, msg2) { + if (a !== b) { + var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; + fail("Expected " + a + " === " + b + ". " + message); + } + } + Debug.assertEqual = assertEqual; + function assertLessThan(a, b, msg) { + if (a >= b) { + fail("Expected " + a + " < " + b + ". " + (msg || "")); + } + } + Debug.assertLessThan = assertLessThan; + function assertLessThanOrEqual(a, b) { + if (a > b) { + fail("Expected " + a + " <= " + b); + } + } + Debug.assertLessThanOrEqual = assertLessThanOrEqual; + function assertGreaterThanOrEqual(a, b) { + if (a < b) { + fail("Expected " + a + " >= " + b); + } + } + Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); @@ -3652,6 +3704,10 @@ var ts; Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; + function isAnySupportedFileExtension(path) { + return tryGetExtensionFromPath(path) !== undefined; + } + ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } @@ -3664,6 +3720,18 @@ var ts; /// var ts; (function (ts) { + /** + * Set a high stack trace limit to provide more information in case of an error. + * Called for command-line and server use cases. + * Not called if TypeScript is used as a library. + */ + /* @internal */ + function setStackTraceLimit() { + if (Error.stackTraceLimit < 100) { + Error.stackTraceLimit = 100; + } + } + ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; @@ -3714,7 +3782,7 @@ var ts; watcher.referenceCount += 1; return; } - watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); + watcher = _fs.watch(dirPath || ".", { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; @@ -4569,6 +4637,7 @@ var ts; Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), + Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), @@ -4756,6 +4825,7 @@ var ts; Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), + Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), @@ -5009,6 +5079,8 @@ var ts; Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), + Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), }; })(ts || (ts = {})); /// @@ -6812,19 +6884,6 @@ var ts; return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; - function findDeclaration(symbol, predicate) { - var declarations = symbol.declarations; - if (declarations) { - for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { - var declaration = declarations_2[_i]; - if (predicate(declaration)) { - return declaration; - } - } - } - return undefined; - } - ts.findDeclaration = findDeclaration; var stringWriter = createSingleLineStringWriter(); var stringWriterAcquired = false; function createSingleLineStringWriter() { @@ -6886,19 +6945,20 @@ var ts; sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective); } ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective; - /* @internal */ function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && - oldResolution.resolvedFileName === newResolution.resolvedFileName; + oldResolution.resolvedFileName === newResolution.resolvedFileName && + packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; - /* @internal */ + function packageIdIsEqual(a, b) { + return a === b || a && b && a.name === b.name && a.version === b.version; + } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo; - /* @internal */ function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) { ts.Debug.assert(names.length === newResolutions.length); for (var i = 0; i < names.length; i++) { @@ -6968,14 +7028,6 @@ var ts; return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; - function getStartPosOfNode(node) { - return node.pos; - } - ts.getStartPosOfNode = getStartPosOfNode; - function isDefined(value) { - return value !== undefined; - } - ts.isDefined = isDefined; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); @@ -7025,6 +7077,32 @@ var ts; return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; + /** + * Determine if the given comment is a triple-slash + * + * @return true if the comment is a triple-slash comment else false + */ + function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { + // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text + // so that we don't end up computing comment string and doing match for all // comments + if (text.charCodeAt(commentPos + 1) === 47 /* slash */ && + commentPos + 2 < commentEnd && + text.charCodeAt(commentPos + 2) === 47 /* slash */) { + var textSubStr = text.substring(commentPos, commentEnd); + return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || + textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || + textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || + textSubStr.match(defaultLibReferenceRegEx) ? + true : false; + } + return false; + } + ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; + function isPinnedComment(text, comment) { + return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && + text.charCodeAt(comment.pos + 2) === 33 /* exclamation */; + } + ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't* // want to skip trivia because this will launch us forward to the next token. @@ -7094,15 +7172,20 @@ var ts; // or a (possibly escaped) quoted form of the original text if it's string-like. switch (node.kind) { case 9 /* StringLiteral */: - return '"' + escapeText(node.text) + '"'; + if (node.singleQuote) { + return "'" + escapeText(node.text, 39 /* singleQuote */) + "'"; + } + else { + return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"'; + } case 13 /* NoSubstitutionTemplateLiteral */: - return "`" + escapeText(node.text) + "`"; + return "`" + escapeText(node.text, 96 /* backtick */) + "`"; case 14 /* TemplateHead */: - return "`" + escapeText(node.text) + "${"; + return "`" + escapeText(node.text, 96 /* backtick */) + "${"; case 15 /* TemplateMiddle */: - return "}" + escapeText(node.text) + "${"; + return "}" + escapeText(node.text, 96 /* backtick */) + "${"; case 16 /* TemplateTail */: - return "}" + escapeText(node.text) + "`"; + return "}" + escapeText(node.text, 96 /* backtick */) + "`"; case 8 /* NumericLiteral */: return node.text; } @@ -7191,6 +7274,7 @@ var ts; return ts.isExternalModule(node) || compilerOptions.isolatedModules; } ts.isEffectiveExternalModule = isEffectiveExternalModule; + /* @internal */ function isBlockScope(node, parentNode) { switch (node.kind) { case 265 /* SourceFile */: @@ -7384,10 +7468,6 @@ var ts; return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos); } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; - function getLeadingCommentRangesOfNodeFromText(node, text) { - return ts.getLeadingCommentRanges(text, node.pos); - } - ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 146 /* Parameter */ || node.kind === 145 /* TypeParameter */ || @@ -7395,7 +7475,7 @@ var ts; node.kind === 187 /* ArrowFunction */ || node.kind === 185 /* ParenthesizedExpression */) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); + ts.getLeadingCommentRanges(text, node.pos); // True if the comment starts with '/**' but not if it is '/**/' return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && @@ -7405,8 +7485,9 @@ var ts; } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; + var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; + var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (158 /* FirstTypeNode */ <= node.kind && node.kind <= 173 /* LastTypeNode */) { return true; @@ -7660,21 +7741,11 @@ var ts; } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { - while (true) { - node = node.parent; - if (!node || ts.isFunctionLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { - while (true) { - node = node.parent; - if (!node || ts.isClassLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { @@ -8570,14 +8641,14 @@ var ts; ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*/gim; + var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim"); if (simpleReferenceRegEx.test(comment)) { if (isNoDefaultLibRegEx.test(comment)) { return { isNoDefaultLib: true }; } else { var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment); - var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); var match = refMatchResult || refLibResult; if (match) { var pos = commentRange.pos + match[1].length + match[2].length; @@ -8782,10 +8853,6 @@ var ts; return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; - function getOriginalSourceFiles(sourceFiles) { - return ts.sameMap(sourceFiles, getOriginalSourceFile); - } - ts.getOriginalSourceFiles = getOriginalSourceFiles; var Associativity; (function (Associativity) { Associativity[Associativity["Left"] = 0] = "Left"; @@ -9029,7 +9096,9 @@ var ts; // the language service. These characters should be escaped when printing, and if any characters are added, // the map below must be updated. Note that this regexp *does not* include the 'delete' character. // There is no reason for this other than that JSON.stringify does not handle it either. - var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", @@ -9040,6 +9109,8 @@ var ts; "\n": "\\n", "\\": "\\\\", "\"": "\\\"", + "\'": "\\\'", + "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" // nextLine @@ -9049,7 +9120,10 @@ var ts; * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine) * Note that this doesn't actually wrap the input in double quotes. */ - function escapeString(s) { + function escapeString(s, quoteChar) { + var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp : + quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp : + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } ts.escapeString = escapeString; @@ -9069,8 +9143,8 @@ var ts; return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; - function escapeNonAsciiString(s) { - s = escapeString(s); + function escapeNonAsciiString(s, quoteChar) { + s = escapeString(s, quoteChar); // Replace non-ASCII characters with '\uNNNN' escapes if any exist. // Otherwise just return the original string. return nonAsciiCharacters.test(s) ? @@ -9455,7 +9529,7 @@ var ts; // // var x = 10; if (node.pos === 0) { - leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment); + leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { @@ -9495,9 +9569,8 @@ var ts; } } return currentDetachedCommentInfo; - function isPinnedComment(comment) { - return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && - text.charCodeAt(comment.pos + 2) === 33 /* exclamation */; + function isPinnedCommentLocal(comment) { + return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; @@ -9593,9 +9666,13 @@ var ts; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { - return (getModifierFlags(node) & flags) !== 0; + return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; + function getSelectedModifierFlags(node, flags) { + return getModifierFlags(node) & flags; + } + ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) { return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */; @@ -9673,23 +9750,6 @@ var ts; return false; } ts.isDestructuringAssignment = isDestructuringAssignment; - // Returns false if this heritage clause element's expression contains something unsupported - // (i.e. not a name or dotted name). - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 71 /* Identifier */) { - return true; - } - else if (ts.isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } - } function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } @@ -9816,78 +9876,6 @@ var ts; return carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; - /** - * Tests whether a node and its subtree is simple enough to have its position - * information ignored when emitting source maps in a destructuring assignment. - * - * @param node The expression to test. - */ - function isSimpleExpression(node) { - return isSimpleExpressionWorker(node, 0); - } - ts.isSimpleExpression = isSimpleExpression; - function isSimpleExpressionWorker(node, depth) { - if (depth <= 5) { - var kind = node.kind; - if (kind === 9 /* StringLiteral */ - || kind === 8 /* NumericLiteral */ - || kind === 12 /* RegularExpressionLiteral */ - || kind === 13 /* NoSubstitutionTemplateLiteral */ - || kind === 71 /* Identifier */ - || kind === 99 /* ThisKeyword */ - || kind === 97 /* SuperKeyword */ - || kind === 101 /* TrueKeyword */ - || kind === 86 /* FalseKeyword */ - || kind === 95 /* NullKeyword */) { - return true; - } - else if (kind === 179 /* PropertyAccessExpression */) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 180 /* ElementAccessExpression */) { - return isSimpleExpressionWorker(node.expression, depth + 1) - && isSimpleExpressionWorker(node.argumentExpression, depth + 1); - } - else if (kind === 192 /* PrefixUnaryExpression */ - || kind === 193 /* PostfixUnaryExpression */) { - return isSimpleExpressionWorker(node.operand, depth + 1); - } - else if (kind === 194 /* BinaryExpression */) { - return node.operatorToken.kind !== 40 /* AsteriskAsteriskToken */ - && isSimpleExpressionWorker(node.left, depth + 1) - && isSimpleExpressionWorker(node.right, depth + 1); - } - else if (kind === 195 /* ConditionalExpression */) { - return isSimpleExpressionWorker(node.condition, depth + 1) - && isSimpleExpressionWorker(node.whenTrue, depth + 1) - && isSimpleExpressionWorker(node.whenFalse, depth + 1); - } - else if (kind === 190 /* VoidExpression */ - || kind === 189 /* TypeOfExpression */ - || kind === 188 /* DeleteExpression */) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 177 /* ArrayLiteralExpression */) { - return node.elements.length === 0; - } - else if (kind === 178 /* ObjectLiteralExpression */) { - return node.properties.length === 0; - } - else if (kind === 181 /* CallExpression */) { - if (!isSimpleExpressionWorker(node.expression, depth + 1)) { - return false; - } - for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { - var argument = _a[_i]; - if (!isSimpleExpressionWorker(argument, depth + 1)) { - return false; - } - } - return true; - } - } - return false; - } /** * Formats an enum value as a string for debugging and debug assertions. */ @@ -9959,24 +9947,6 @@ var ts; return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true); } ts.formatObjectFlags = formatObjectFlags; - function getRangePos(range) { - return range ? range.pos : -1; - } - ts.getRangePos = getRangePos; - function getRangeEnd(range) { - return range ? range.end : -1; - } - ts.getRangeEnd = getRangeEnd; - /** - * Increases (or decreases) a position by the provided amount. - * - * @param pos The position. - * @param value The delta. - */ - function movePos(pos, value) { - return ts.positionIsSynthesized(pos) ? -1 : pos + value; - } - ts.movePos = movePos; /** * Creates a new TextRange from the provided pos and end. * @@ -10034,26 +10004,6 @@ var ts; return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; - /** - * Creates a new TextRange from a provided range with its end position collapsed to its - * start position. - * - * @param range A TextRange. - */ - function collapseRangeToStart(range) { - return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos); - } - ts.collapseRangeToStart = collapseRangeToStart; - /** - * Creates a new TextRange from a provided range with its start position collapsed to its - * end position. - * - * @param range A TextRange. - */ - function collapseRangeToEnd(range) { - return isCollapsedRange(range) ? range : moveRangePos(range, range.end); - } - ts.collapseRangeToEnd = collapseRangeToEnd; /** * Creates a new TextRange for a token at the provides start position. * @@ -10116,31 +10066,6 @@ var ts; function isInitializedVariable(node) { return node.initializer !== undefined; } - /** - * Gets a value indicating whether a node is merged with a class declaration in the same scope. - */ - function isMergedWithClass(node) { - if (node.symbol) { - for (var _i = 0, _a = node.symbol.declarations; _i < _a.length; _i++) { - var declaration = _a[_i]; - if (declaration.kind === 229 /* ClassDeclaration */ && declaration !== node) { - return true; - } - } - } - return false; - } - ts.isMergedWithClass = isMergedWithClass; - /** - * Gets a value indicating whether a node is the first declaration of its kind. - * - * @param node A Declaration node. - * @param kind The SyntaxKind to find among related declarations. - */ - function isFirstDeclarationOfKind(node, kind) { - return node.symbol && getDeclarationOfKind(node.symbol, kind) === node; - } - ts.isFirstDeclarationOfKind = isFirstDeclarationOfKind; function isWatchSet(options) { // Firefox has Object.prototype.watch return options.watch && options.hasOwnProperty("watch"); @@ -10434,6 +10359,20 @@ var ts; return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && node.parent.kind === 152 /* Constructor */ && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function isEmptyBindingPattern(node) { + if (ts.isBindingPattern(node)) { + return ts.every(node.elements, isEmptyBindingElement); + } + return false; + } + ts.isEmptyBindingPattern = isEmptyBindingPattern; + function isEmptyBindingElement(node) { + if (ts.isOmittedExpression(node)) { + return true; + } + return isEmptyBindingPattern(node.name); + } + ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 176 /* BindingElement */ || ts.isBindingPattern(node))) { node = node.parent; @@ -11618,6 +11557,19 @@ var ts; return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; + /* @internal */ + function isUnaryExpressionWithWrite(expr) { + switch (expr.kind) { + case 193 /* PostfixUnaryExpression */: + return true; + case 192 /* PrefixUnaryExpression */: + return expr.operator === 43 /* PlusPlusToken */ || + expr.operator === 44 /* MinusMinusToken */; + default: + return false; + } + } + ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; function isExpressionKind(kind) { return kind === 195 /* ConditionalExpression */ || kind === 197 /* YieldExpression */ @@ -11824,9 +11776,19 @@ var ts; var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) - || kind === 207 /* Block */; + || isBlockStatement(node); } ts.isStatement = isStatement; + function isBlockStatement(node) { + if (node.kind !== 207 /* Block */) + return false; + if (node.parent !== undefined) { + if (node.parent.kind === 224 /* TryStatement */ || node.parent.kind === 260 /* CatchClause */) { + return false; + } + } + return !ts.isFunctionBlock(node); + } // Module references /* @internal */ function isModuleReference(node) { @@ -14207,11 +14169,31 @@ var ts; var node = parseTokenNode(); return token() === 23 /* DotToken */ ? undefined : node; } - function parseLiteralTypeNode() { + function parseLiteralTypeNode(negative) { var node = createNode(173 /* LiteralType */); - node.literal = parseSimpleUnaryExpression(); - finishNode(node); - return node; + var unaryMinusExpression; + if (negative) { + unaryMinusExpression = createNode(192 /* PrefixUnaryExpression */); + unaryMinusExpression.operator = 38 /* MinusToken */; + nextToken(); + } + var expression; + switch (token()) { + case 9 /* StringLiteral */: + case 8 /* NumericLiteral */: + expression = parseLiteralLikeNode(token()); + break; + case 101 /* TrueKeyword */: + case 86 /* FalseKeyword */: + expression = parseTokenNode(); + } + if (negative) { + unaryMinusExpression.operand = expression; + finishNode(unaryMinusExpression); + expression = unaryMinusExpression; + } + node.literal = expression; + return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8 /* NumericLiteral */; @@ -14244,7 +14226,7 @@ var ts; case 86 /* FalseKeyword */: return parseLiteralTypeNode(); case 38 /* MinusToken */: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference(); + return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); case 105 /* VoidKeyword */: case 95 /* NullKeyword */: return parseTokenNode(); @@ -14293,6 +14275,7 @@ var ts; case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 134 /* ObjectKeyword */: + case 39 /* AsteriskToken */: return true; case 38 /* MinusToken */: return lookAhead(nextTokenIsNumericLiteral); @@ -14721,7 +14704,7 @@ var ts; // Didn't appear to actually be a parenthesized arrow function. Just bail out. return undefined; } - var isAsync = !!(ts.getModifierFlags(arrowFunction) & 256 /* Async */); + var isAsync = ts.hasModifier(arrowFunction, 256 /* Async */); // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. var lastToken = token(); @@ -14879,7 +14862,7 @@ var ts; function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNode(187 /* ArrowFunction */); node.modifiers = parseModifiersForArrowFunction(); - var isAsync = (ts.getModifierFlags(node) & 256 /* Async */) ? 2 /* Await */ : 0 /* None */; + var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; // Arrow functions are never generators. // // If we're speculatively parsing a signature for a parenthesized arrow function, then @@ -15890,7 +15873,7 @@ var ts; parseExpected(89 /* FunctionKeyword */); node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */); var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */; - var isAsync = (ts.getModifierFlags(node) & 256 /* Async */) ? 2 /* Await */ : 0 /* None */; + var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : @@ -16132,10 +16115,14 @@ var ts; function parseCatchClause() { var result = createNode(260 /* CatchClause */); parseExpected(74 /* CatchKeyword */); - if (parseExpected(19 /* OpenParenToken */)) { + if (parseOptional(19 /* OpenParenToken */)) { result.variableDeclaration = parseVariableDeclaration(); + parseExpected(20 /* CloseParenToken */); + } + else { + // Keep shape of node to avoid degrading performance. + result.variableDeclaration = undefined; } - parseExpected(20 /* CloseParenToken */); result.block = parseBlock(/*ignoreMissingOpenBrace*/ false); return finishNode(result); } @@ -17036,8 +17023,8 @@ var ts; // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; - if (identifier || - token() === 39 /* AsteriskToken */ || + if (identifier || // import id + token() === 39 /* AsteriskToken */ || // import * token() === 17 /* OpenBraceToken */) { importDeclaration.importClause = parseImportClause(identifier, afterImportPos); parseExpected(140 /* FromKeyword */); @@ -17345,7 +17332,7 @@ var ts; JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; function parseIsolatedJSDocComment(content, start, length) { initializeState(content, 5 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */); - sourceFile = { languageVariant: 0 /* Standard */, text: content }; + sourceFile = { languageVariant: 0 /* Standard */, text: content }; // tslint:disable-line no-object-literal-type-assertion var jsDoc = parseJSDocCommentWorker(start, length); var diagnostics = parseDiagnostics; clearState(); @@ -18093,8 +18080,8 @@ var ts; array._children = undefined; array.pos += delta; array.end += delta; - for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { - var node = array_9[_i]; + for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { + var node = array_8[_i]; visitNode(node); } } @@ -18231,8 +18218,8 @@ var ts; array._children = undefined; // Adjust the pos or end (or both) of the intersecting array accordingly. adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (var _i = 0, array_10 = array; _i < array_10.length; _i++) { - var node = array_10[_i]; + for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { + var node = array_9[_i]; visitNode(node); } return; @@ -19201,40 +19188,23 @@ var ts; return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: flags, - expression: expression, - antecedent: antecedent - }; + return { flags: flags, expression: expression, antecedent: antecedent }; } function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) { if (!isNarrowingExpression(switchStatement.expression)) { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: 128 /* SwitchClause */, - switchStatement: switchStatement, - clauseStart: clauseStart, - clauseEnd: clauseEnd, - antecedent: antecedent - }; + return { flags: 128 /* SwitchClause */, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent }; } function createFlowAssignment(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 16 /* Assignment */, - antecedent: antecedent, - node: node - }; + return { flags: 16 /* Assignment */, antecedent: antecedent, node: node }; } function createFlowArrayMutation(antecedent, node) { setFlowNodeReferenced(antecedent); - return { - flags: 256 /* ArrayMutation */, - antecedent: antecedent, - node: node - }; + var res = { flags: 256 /* ArrayMutation */, antecedent: antecedent, node: node }; + return res; } function finishFlowLabel(flow) { var antecedents = flow.antecedents; @@ -20956,7 +20926,6 @@ var ts; } function computeParameter(node, subtreeFlags) { var transformFlags = subtreeFlags; - var modifierFlags = ts.getModifierFlags(node); var name = node.name; var initializer = node.initializer; var dotDotDotToken = node.dotDotDotToken; @@ -20969,7 +20938,7 @@ var ts; transformFlags |= 3 /* AssertTypeScript */; } // If a parameter has an accessibility modifier, then it is TypeScript syntax. - if (modifierFlags & 92 /* ParameterPropertyModifier */) { + if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { transformFlags |= 3 /* AssertTypeScript */ | 262144 /* ContainsParameterPropertyAssignments */; } // parameters with object rest destructuring are ES Next syntax @@ -21006,8 +20975,7 @@ var ts; } function computeClassDeclaration(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); - if (modifierFlags & 2 /* Ambient */) { + if (ts.hasModifier(node, 2 /* Ambient */)) { // An ambient declaration is TypeScript syntax. transformFlags = 3 /* AssertTypeScript */; } @@ -21068,7 +21036,10 @@ var ts; } function computeCatchClause(node, subtreeFlags) { var transformFlags = subtreeFlags; - if (node.variableDeclaration && ts.isBindingPattern(node.variableDeclaration.name)) { + if (!node.variableDeclaration) { + transformFlags |= 8 /* AssertESNext */; + } + else if (ts.isBindingPattern(node.variableDeclaration.name)) { transformFlags |= 192 /* AssertES2015 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; @@ -21283,10 +21254,9 @@ var ts; } function computeVariableStatement(node, subtreeFlags) { var transformFlags; - var modifierFlags = ts.getModifierFlags(node); var declarationListTransformFlags = node.declarationList.transformFlags; // An ambient declaration is TypeScript syntax. - if (modifierFlags & 2 /* Ambient */) { + if (ts.hasModifier(node, 2 /* Ambient */)) { transformFlags = 3 /* AssertTypeScript */; } else { @@ -21647,6 +21617,12 @@ var ts; return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; + function withPackageId(packageId, r) { + return r && { path: r.path, extension: r.ext, packageId: packageId }; + } + function noPackageId(r) { + return withPackageId(/*packageId*/ undefined, r); + } /** * Kinds of file that we are currently looking for. * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript. @@ -21667,13 +21643,12 @@ var ts; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { - resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport }, + resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } /** Reads from "main" or "types"/"typings" depending on `extensions`. */ - function tryReadPackageJsonFields(readTypes, packageJsonPath, baseDirectory, state) { - var jsonContent = readJson(packageJsonPath, state.host); + function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { @@ -21778,7 +21753,9 @@ var ts; } var resolvedTypeReferenceDirective; if (resolved) { - resolved = realpath(resolved, host, traceEnabled); + if (!options.preserveSymlinks) { + resolved = realpath(resolved, host, traceEnabled); + } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary); } @@ -22182,7 +22159,7 @@ var ts; if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); if (path_1 !== undefined) { - return { path: path_1, extension: extension }; + return { path: path_1, extension: extension, packageId: undefined }; } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); @@ -22209,7 +22186,7 @@ var ts; function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { - throw new Error("Could not resolve JS module " + moduleName + " starting at " + initialDir + ". Looked in: " + failedLookupLocations.join(", ")); + throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } @@ -22235,8 +22212,14 @@ var ts; trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); + if (!resolved_1) + return undefined; + var resolvedValue = resolved_1.value; + if (!compilerOptions.preserveSymlinks) { + resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); + } // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files. - return resolved_1 && { value: resolved_1.value && { resolved: { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }, isExternalLibraryImport: true } }; + return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); @@ -22271,7 +22254,7 @@ var ts; } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return resolvedFromFile; + return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { @@ -22291,6 +22274,9 @@ var ts; return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; + function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { + return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + } /** * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. @@ -22329,9 +22315,9 @@ var ts; case Extensions.JavaScript: return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */); } - function tryExtension(extension) { - var path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); - return path && { path: path, extension: extension }; + function tryExtension(ext) { + var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + return path && { path: path, ext: ext }; } } /** Return the file if it exists. */ @@ -22355,12 +22341,20 @@ var ts; function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); + var packageId; if (considerPackageJson) { var packageJsonPath = pathToPackageJson(candidate); if (directoryExists && state.host.fileExists(packageJsonPath)) { - var fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); + } + var jsonContent = readJson(packageJsonPath, state.host); + if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") { + packageId = { name: jsonContent.name, version: jsonContent.version }; + } + var fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { - return fromPackageJson; + return withPackageId(packageId, fromPackageJson); } } else { @@ -22371,13 +22365,10 @@ var ts; failedLookupLocations.push(packageJsonPath); } } - return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return withPackageId(packageId, loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state)); } - function loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); - } - var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { + var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } @@ -22395,12 +22386,17 @@ var ts; // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types" var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; // Don't do package.json lookup recursively, because Node.js' package lookup doesn't. - return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); + var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); + if (result) { + // It won't have a `packageId` set, because we disabled `considerPackageJson`. + ts.Debug.assert(result.packageId === undefined); + return { path: result.path, ext: result.extension }; + } } /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ function resolvedIfExtensionMatches(extensions, path) { - var extension = ts.tryGetExtensionFromPath(path); - return extension !== undefined && extensionIsOk(extensions, extension) ? { path: path, extension: extension } : undefined; + var ext = ts.tryGetExtensionFromPath(path); + return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } /** True if `extension` is one of the supported `extensions`. */ function extensionIsOk(extensions, extension) { @@ -22418,7 +22414,7 @@ var ts; } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || + return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { @@ -22497,7 +22493,7 @@ var ts; if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { @@ -22508,7 +22504,7 @@ var ts; var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations); function tryResolve(extensions) { - var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); + var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -22521,7 +22517,7 @@ var ts; return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); }); if (resolved_3) { return resolved_3; @@ -22533,7 +22529,7 @@ var ts; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); } } } @@ -22789,11 +22785,10 @@ var ts; getSuggestionForNonexistentProperty: function (node, type) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentProperty(node, type)); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return ts.unescapeLeadingUnderscores(getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning)); }, getBaseConstraintOfType: getBaseConstraintOfType, - getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, - resolveNameAtLocation: function (location, name, meaning) { - location = ts.getParseTreeNode(location); - return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, ts.escapeLeadingUnderscores(name)); + resolveName: function (name, location, meaning) { + return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); }, + getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, }; var tupleTypes = []; var unionTypes = ts.createMap(); @@ -23360,13 +23355,13 @@ var ts; current.parent.kind === 149 /* PropertyDeclaration */ && current.parent.initializer === current; if (initializerOfProperty) { - if (ts.getModifierFlags(current.parent) & 32 /* Static */) { + if (ts.hasModifier(current.parent, 32 /* Static */)) { if (declaration.kind === 151 /* MethodDeclaration */) { return true; } } else { - var isDeclarationInstanceProperty = declaration.kind === 149 /* PropertyDeclaration */ && !(ts.getModifierFlags(declaration) & 32 /* Static */); + var isDeclarationInstanceProperty = declaration.kind === 149 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */); if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } @@ -23480,7 +23475,7 @@ var ts; // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. - if (ts.isClassLike(location.parent) && !(ts.getModifierFlags(location) & 32 /* Static */)) { + if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32 /* Static */)) { var ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & 107455 /* Value */)) { @@ -23499,7 +23494,7 @@ var ts; result = undefined; break; } - if (lastLocation && ts.getModifierFlags(lastLocation) & 32 /* Static */) { + if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. @@ -23585,7 +23580,10 @@ var ts; lastLocation = location; location = location.parent; } - if (result && nameNotFoundMessage && noUnusedIdentifiers) { + // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. + // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself. + // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. + if (result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) { result.isReferenced = true; } if (!result) { @@ -23684,7 +23682,7 @@ var ts; } // No static member is present. // Check if we're in an instance method and look for a relevant instance member. - if (location === container && !(ts.getModifierFlags(location) & 32 /* Static */)) { + if (location === container && !ts.hasModifier(location, 32 /* Static */)) { var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -24186,7 +24184,7 @@ var ts; // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, // and an external module with no 'export =' declaration resolves to the module itself. function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) { - return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="), dontResolveAlias)) || moduleSymbol; + return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias)) || moduleSymbol; } // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export =' // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may @@ -24199,7 +24197,7 @@ var ts; return symbol; } function hasExportAssignmentSymbol(moduleSymbol) { - return moduleSymbol.exports.get("export=") !== undefined; + return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined; } function getExportsOfModuleAsArray(moduleSymbol) { return symbolsToArray(getExportsOfModule(moduleSymbol)); @@ -24461,7 +24459,7 @@ var ts; if (symbolFromSymbolTable.flags & 2097152 /* Alias */ && symbolFromSymbolTable.escapedName !== "export=" && !ts.getDeclarationOfKind(symbolFromSymbolTable, 246 /* ExportSpecifier */)) { - if (!useOnlyExternalAliasing || + if (!useOnlyExternalAliasing || // We can use any type of alias to get the name // Is this external alias, then use it to name ts.forEach(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration)) { var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable); @@ -24526,6 +24524,10 @@ var ts; } return false; } + function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) { + var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false); + return access.accessibility === 0 /* Accessible */; + } /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * @@ -24608,7 +24610,7 @@ var ts; // because these kind of aliases can be used to name types in declaration file var anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(ts.getModifierFlags(anyImportSyntax) & 1 /* Export */) && + !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types, // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time @@ -24817,8 +24819,7 @@ var ts; // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); } - if (!inTypeAlias && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === 0 /* Accessible */) { + if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { var name = symbolToTypeReferenceName(type.aliasSymbol); var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return ts.createTypeReferenceNode(name, typeArgumentNodes); @@ -24900,10 +24901,10 @@ var ts; return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */ && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32 /* Static */; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) && - (symbol.parent || + (symbol.parent || // is exported function symbol ts.forEach(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */; })); @@ -24914,10 +24915,8 @@ var ts; } } function createTypeNodeFromObjectType(type) { - if (type.objectFlags & 32 /* Mapped */) { - if (getConstraintTypeFromMappedType(type).flags & (16384 /* TypeParameter */ | 262144 /* Index */)) { - return createMappedTypeNodeFromType(type); - } + if (isGenericMappedType(type)) { + return createMappedTypeNodeFromType(type); } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -25505,7 +25504,7 @@ var ts; buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags); } else if (!(flags & 1024 /* InTypeAlias */) && type.aliasSymbol && - isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === 0 /* Accessible */) { + ((flags & 65536 /* UseAliasDefinedOutsideCurrentScope */) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { var typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags); } @@ -25667,9 +25666,7 @@ var ts; if (!symbolStack) { symbolStack = []; } - var isConstructorObject = type.flags & 32768 /* Object */ && - getObjectFlags(type) & 16 /* Anonymous */ && - type.symbol && type.symbol.flags & 32 /* Class */; + var isConstructorObject = type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */; if (isConstructorObject) { writeLiteralType(type, flags); } @@ -25685,17 +25682,17 @@ var ts; writeLiteralType(type, flags); } function shouldWriteTypeOfFunctionSymbol() { - var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */ && - ts.forEach(symbol.declarations, function (declaration) { return ts.getModifierFlags(declaration) & 32 /* Static */; })); + var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method + ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) && - (symbol.parent || - ts.forEach(symbol.declarations, function (declaration) { + (symbol.parent || // is exported function symbol + ts.some(symbol.declarations, function (declaration) { return declaration.parent.kind === 265 /* SourceFile */ || declaration.parent.kind === 234 /* ModuleBlock */; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return !!(flags & 4 /* UseTypeOfFunction */) || - (ts.contains(symbolStack, symbol)); // it is type of the symbol uses itself recursively + return !!(flags & 4 /* UseTypeOfFunction */) || // use typeof if format flags specify it + ts.contains(symbolStack, symbol); // it is type of the symbol uses itself recursively } } } @@ -25733,11 +25730,9 @@ var ts; return false; } function writeLiteralType(type, flags) { - if (type.objectFlags & 32 /* Mapped */) { - if (getConstraintTypeFromMappedType(type).flags & (16384 /* TypeParameter */ | 262144 /* Index */)) { - writeMappedType(type); - return; - } + if (isGenericMappedType(type)) { + writeMappedType(type); + return; } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -26113,7 +26108,7 @@ var ts; case 154 /* SetAccessor */: case 151 /* MethodDeclaration */: case 150 /* MethodSignature */: - if (ts.getModifierFlags(node) & (8 /* Private */ | 16 /* Protected */)) { + if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) { // Private/protected properties/methods are not visible return false; } @@ -26910,8 +26905,8 @@ var ts; // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set // in-place and returns the same array. function appendTypeParameters(typeParameters, declarations) { - for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { - var declaration = declarations_3[_i]; + for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { + var declaration = declarations_2[_i]; var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); if (!typeParameters) { typeParameters = [tp]; @@ -27221,7 +27216,9 @@ var ts; if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) { return unknownType; } - var declaration = ts.findDeclaration(symbol, function (d) { return d.kind === 283 /* JSDocTypedefTag */ || d.kind === 231 /* TypeAliasDeclaration */; }); + var declaration = ts.find(symbol.declarations, function (d) { + return d.kind === 283 /* JSDocTypedefTag */ || d.kind === 231 /* TypeAliasDeclaration */; + }); var type = getTypeFromTypeNode(declaration.kind === 283 /* JSDocTypedefTag */ ? declaration.typeExpression : declaration.type); if (popTypeResolution()) { var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -27883,8 +27880,7 @@ var ts; return getObjectFlags(type) & 32 /* Mapped */ && !!type.declaration.questionToken; } function isGenericMappedType(type) { - return getObjectFlags(type) & 32 /* Mapped */ && - maybeTypeOfKind(getConstraintTypeFromMappedType(type), 540672 /* TypeVariable */ | 262144 /* Index */); + return getObjectFlags(type) & 32 /* Mapped */ && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type) { if (!type.members) { @@ -27990,6 +27986,10 @@ var ts; return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } function getConstraintOfIndexedAccess(type) { + var transformed = getTransformedIndexedAccessType(type); + if (transformed) { + return transformed; + } var baseObjectType = getBaseConstraintOfType(type.objectType); var baseIndexType = getBaseConstraintOfType(type.indexType); return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; @@ -28057,11 +28057,18 @@ var ts; return stringType; } if (t.flags & 524288 /* IndexedAccess */) { + var transformed = getTransformedIndexedAccessType(t); + if (transformed) { + return getBaseConstraint(transformed); + } var baseObjectType = getBaseConstraint(t.objectType); var baseIndexType = getBaseConstraint(t.indexType); var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (isGenericMappedType(t)) { + return emptyObjectType; + } return t; } } @@ -28680,7 +28687,7 @@ var ts; function getIndexInfoOfSymbol(symbol, kind) { var declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, (ts.getModifierFlags(declaration) & 64 /* Readonly */) !== 0, declaration); + return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration); } return undefined; } @@ -28978,8 +28985,8 @@ var ts; function getTypeOfGlobalSymbol(symbol, arity) { function getTypeDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { - var declaration = declarations_4[_i]; + for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { + var declaration = declarations_3[_i]; switch (declaration.kind) { case 229 /* ClassDeclaration */: case 230 /* InterfaceDeclaration */: @@ -29475,11 +29482,11 @@ var ts; return getTypeOfSymbol(prop); } } - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */)) { + if (!(indexType.flags & 6144 /* Nullable */) && isTypeAssignableToKind(indexType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */)) { if (isTypeAny(objectType)) { return anyType; } - var indexInfo = isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || + var indexInfo = isTypeAssignableToKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || getIndexInfoOfType(objectType, 0 /* String */) || undefined; if (indexInfo) { @@ -29517,35 +29524,85 @@ var ts; return anyType; } function getIndexedAccessForMappedType(type, indexType, accessNode) { - var accessExpression = accessNode && accessNode.kind === 180 /* ElementAccessExpression */ ? accessNode : undefined; - if (accessExpression && ts.isAssignmentTarget(accessExpression) && type.declaration.readonlyToken) { - error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); - return unknownType; + if (accessNode) { + // Check if the index type is assignable to 'keyof T' for the object type. + if (!isTypeAssignableTo(indexType, getIndexType(type))) { + error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(type)); + return unknownType; + } + if (accessNode.kind === 180 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) && type.declaration.readonlyToken) { + error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type)); + return unknownType; + } } var mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]); var templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; return instantiateType(getTemplateTypeFromMappedType(type), templateMapper); } + function isGenericObjectType(type) { + return type.flags & 540672 /* TypeVariable */ ? true : + getObjectFlags(type) & 32 /* Mapped */ ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : + type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericObjectType) : + false; + } + function isGenericIndexType(type) { + return type.flags & (540672 /* TypeVariable */ | 262144 /* Index */) ? true : + type.flags & 196608 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericIndexType) : + false; + } + // Return true if the given type is a non-generic object type with a string index signature and no + // other members. + function isStringIndexOnlyType(type) { + if (type.flags & 32768 /* Object */ && !isGenericMappedType(type)) { + var t = resolveStructuredTypeMembers(type); + return t.properties.length === 0 && + t.callSignatures.length === 0 && t.constructSignatures.length === 0 && + t.stringIndexInfo && !t.numberIndexInfo; + } + return false; + } + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a + // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed + // access types with default property values as expressed by D. + function getTransformedIndexedAccessType(type) { + var objectType = type.objectType; + if (objectType.flags & 131072 /* Intersection */ && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) { + var regularTypes = []; + var stringIndexTypes = []; + for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) { + var t = _a[_i]; + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, 0 /* String */)); + } + else { + regularTypes.push(t); + } + } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + return undefined; + } function getIndexedAccessType(objectType, indexType, accessNode) { - // If the index type is generic, if the object type is generic and doesn't originate in an expression, - // or if the object type is a mapped type with a generic constraint, we are performing a higher-order - // index access where we cannot meaningfully access the properties of the object type. Note that for a - // generic T and a non-generic K, we eagerly resolve T[K] if it originates in an expression. This is to - // preserve backwards compatibility. For example, an element access 'this["foo"]' has always been resolved - // eagerly using the constraint type of 'this' at the given location. - if (maybeTypeOfKind(indexType, 540672 /* TypeVariable */ | 262144 /* Index */) || - maybeTypeOfKind(objectType, 540672 /* TypeVariable */) && !(accessNode && accessNode.kind === 180 /* ElementAccessExpression */) || - isGenericMappedType(objectType)) { + // If the object type is a mapped type { [P in K]: E }, where K is generic, we instantiate E using a mapper + // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we + // construct the type Box. + if (isGenericMappedType(objectType)) { + return getIndexedAccessForMappedType(objectType, indexType, accessNode); + } + // Otherwise, if the index type is generic, or if the object type is generic and doesn't originate in an + // expression, we are performing a higher-order index access where we cannot meaningfully access the properties + // of the object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates + // in an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]' + // has always been resolved eagerly using the constraint type of 'this' at the given location. + if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 180 /* ElementAccessExpression */) && isGenericObjectType(objectType)) { if (objectType.flags & 1 /* Any */) { return objectType; } - // If the object type is a mapped type { [P in K]: E }, we instantiate E using a mapper that substitutes - // the index type for P. For example, for an index access { [P in K]: Box }[X], we construct the - // type Box. - if (isGenericMappedType(objectType)) { - return getIndexedAccessForMappedType(objectType, indexType, accessNode); - } - // Otherwise we defer the operation by creating an indexed access type. + // Defer the operation by creating an indexed access type. var id = objectType.id + "," + indexType.id; var type = indexedAccessTypes.get(id); if (!type) { @@ -29759,7 +29816,7 @@ var ts; var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); var parent = container && container.parent; if (parent && (ts.isClassLike(parent) || parent.kind === 230 /* InterfaceDeclaration */)) { - if (!(ts.getModifierFlags(container) & 32 /* Static */) && + if (!ts.hasModifier(container, 32 /* Static */) && (container.kind !== 152 /* Constructor */ || ts.isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } @@ -29912,7 +29969,7 @@ var ts; } function cloneTypeMapper(mapper) { return mapper && isInferenceContext(mapper) ? - createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.inferences) : + createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.compareTypes, mapper.inferences) : mapper; } function identityMapper(type) { @@ -30222,16 +30279,16 @@ var ts; if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) { return true; } - // For arrow functions we now know we're not context sensitive. - if (node.kind === 187 /* ArrowFunction */) { - return false; + if (node.kind !== 187 /* ArrowFunction */) { + // If the first parameter is not an explicit 'this' parameter, then the function has + // an implicit 'this' parameter which is subject to contextual typing. + var parameter = ts.firstOrUndefined(node.parameters); + if (!(parameter && ts.parameterIsThisKeyword(parameter))) { + return true; + } } - // 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. - var parameter = ts.firstOrUndefined(node.parameters); - return !(parameter && ts.parameterIsThisKeyword(parameter)); + // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value. + return node.body.kind === 207 /* Block */ ? false : isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func) { return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); @@ -30317,7 +30374,7 @@ var ts; return 0 /* False */; } if (source.typeParameters) { - source = instantiateSignatureInContextOf(source, target); + source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } var result = -1 /* True */; var sourceThisType = getThisTypeOfSignature(source); @@ -30376,7 +30433,7 @@ var ts; // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions if (target.typePredicate) { if (source.typePredicate) { - result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes); + result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes); } else if (ts.isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { @@ -30395,7 +30452,7 @@ var ts; } return result; } - function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) { + function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) { if (source.kind !== target.kind) { if (reportErrors) { errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); @@ -30404,11 +30461,13 @@ var ts; return 0 /* False */; } if (source.kind === 1 /* Identifier */) { - var sourceIdentifierPredicate = source; - var targetIdentifierPredicate = target; - if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + var sourcePredicate = source; + var targetPredicate = target; + var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0); + var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0); + if (sourceIndex !== targetIndex) { if (reportErrors) { - errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0 /* False */; @@ -30697,11 +30756,21 @@ var ts; !(target.flags & 65536 /* Union */) && !isIntersectionConstituent && source !== globalObjectType && - getPropertiesOfType(source).length > 0 && + (getPropertiesOfType(source).length > 0 || + getSignaturesOfType(source, 0 /* Call */).length > 0 || + getSignaturesOfType(source, 1 /* Construct */).length > 0) && isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { - reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + var calls = getSignaturesOfType(source, 0 /* Call */); + var constructs = getSignaturesOfType(source, 1 /* Construct */); + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) { + reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target)); + } + else { + reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); + } } return 0 /* False */; } @@ -31411,6 +31480,11 @@ var ts; if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } + if (isGenericMappedType(source)) { + // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U } + // if T is related to U. + return kind === 0 /* String */ && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); + } if (isObjectLiteralType(source)) { var related = -1 /* True */; if (kind === 0 /* String */) { @@ -31444,8 +31518,8 @@ var ts; if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } - var sourceAccessibility = ts.getModifierFlags(sourceSignature.declaration) & 24 /* NonPublicAccessibilityModifier */; - var targetAccessibility = ts.getModifierFlags(targetSignature.declaration) & 24 /* NonPublicAccessibilityModifier */; + var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */); + var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */); // A public, protected and private signature is assignable to a private signature. if (targetAccessibility === 8 /* Private */) { return true; @@ -31509,7 +31583,7 @@ var ts; var symbol = type.symbol; if (symbol && symbol.flags & 32 /* Class */) { var declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && ts.getModifierFlags(declaration) & 128 /* Abstract */) { + if (declaration && ts.hasModifier(declaration, 128 /* Abstract */)) { return true; } } @@ -31960,13 +32034,14 @@ var ts; callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } } - function createInferenceContext(signature, flags, baseInferences) { + function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; + context.compareTypes = compareTypes || compareTypesAssignable; return context; function mapper(t) { for (var i = 0; i < inferences.length; i++) { @@ -32061,6 +32136,19 @@ var ts; return inference.candidates && getUnionType(inference.candidates, /*subtypeReduction*/ true); } } + function isPossiblyAssignableTo(source, target) { + var properties = getPropertiesOfObjectType(target); + for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { + var targetProp = properties_5[_i]; + if (!(targetProp.flags & (16777216 /* Optional */ | 4194304 /* Prototype */))) { + var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); + if (!sourceProp) { + return false; + } + } + } + return true; + } function inferTypes(inferences, originalSource, originalTarget, priority) { if (priority === void 0) { priority = 0; } var symbolStack; @@ -32257,15 +32345,19 @@ var ts; return; } } - inferFromProperties(source, target); - inferFromSignatures(source, target, 0 /* Call */); - inferFromSignatures(source, target, 1 /* Construct */); - inferFromIndexTypes(source, target); + // Infer from the members of source and target only if the two types are possibly related. We check + // in both directions because we may be inferring for a co-variant or a contra-variant position. + if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) { + inferFromProperties(source, target); + inferFromSignatures(source, target, 0 /* Call */); + inferFromSignatures(source, target, 1 /* Construct */); + inferFromIndexTypes(source, target); + } } function inferFromProperties(source, target) { var properties = getPropertiesOfObjectType(target); - for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { - var targetProp = properties_5[_i]; + for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { + var targetProp = properties_6[_i]; var sourceProp = getPropertyOfObjectType(source, targetProp.escapedName); if (sourceProp) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); @@ -32382,7 +32474,7 @@ var ts; var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); if (constraint) { var instantiatedConstraint = instantiateType(constraint, context); - if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } @@ -32440,16 +32532,6 @@ var ts; } return undefined; } - function getLeftmostIdentifierOrThis(node) { - switch (node.kind) { - case 71 /* Identifier */: - case 99 /* ThisKeyword */: - return node; - case 179 /* PropertyAccessExpression */: - return getLeftmostIdentifierOrThis(node.expression); - } - return undefined; - } function getBindingElementNameText(element) { if (element.parent.kind === 174 /* ObjectBindingPattern */) { var name = element.propertyName || element.name; @@ -32975,7 +33057,7 @@ var ts; parent.parent.operatorToken.kind === 58 /* EqualsToken */ && parent.parent.left === parent && !ts.isAssignmentTarget(parent.parent) && - isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */ | 2048 /* Undefined */); + isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */); return isLengthPushOrUnshift || isElementAssignment; } function maybeTypePredicateCall(node) { @@ -33143,7 +33225,7 @@ var ts; } else { var indexType = getTypeOfExpression(node.left.argumentExpression); - if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 84 /* NumberLike */ | 2048 /* Undefined */)) { + if (isTypeAssignableToKind(indexType, 84 /* NumberLike */)) { evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right); } } @@ -33978,7 +34060,7 @@ var ts; break; case 149 /* PropertyDeclaration */: case 148 /* PropertySignature */: - if (ts.getModifierFlags(container) & 32 /* Static */) { + if (ts.hasModifier(container, 32 /* Static */)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } @@ -34081,7 +34163,7 @@ var ts; if (!isCallExpression && container.kind === 152 /* Constructor */) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if ((ts.getModifierFlags(container) & 32 /* Static */) || isCallExpression) { + if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) { nodeCheckFlag = 512 /* SuperStatic */; } else { @@ -34144,7 +34226,7 @@ var ts; // This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set. // This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment // while a property access can. - if (container.kind === 151 /* MethodDeclaration */ && ts.getModifierFlags(container) & 256 /* Async */) { + if (container.kind === 151 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) { if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */; } @@ -34202,7 +34284,7 @@ var ts; // - In a static member function or static member accessor // topmost container must be something that is directly nested in the class declaration\object literal expression if (ts.isClassLike(container.parent) || container.parent.kind === 178 /* ObjectLiteralExpression */) { - if (ts.getModifierFlags(container) & 32 /* Static */) { + if (ts.hasModifier(container, 32 /* Static */)) { return container.kind === 151 /* MethodDeclaration */ || container.kind === 150 /* MethodSignature */ || container.kind === 153 /* GetAccessor */ || @@ -34832,10 +34914,7 @@ var ts; function isNumericComputedName(name) { // It seems odd to consider an expression of type Any to result in a numeric name, // but this behavior is consistent with checkIndexedAccess - return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), 84 /* NumberLike */); - } - function isTypeAnyOrAllConstituentTypesHaveKind(type, kind) { - return isTypeAny(type) || isTypeOfKind(type, kind); + return isTypeAssignableToKind(checkComputedPropertyName(name), 84 /* NumberLike */); } function isInfinityOrNaNString(name) { return name === "Infinity" || name === "-Infinity" || name === "NaN"; @@ -34870,7 +34949,9 @@ var ts; links.resolvedType = checkExpression(node.expression); // This will allow types number, string, symbol or any. It will also allow enums, the unknown // type, and any union of these types (like string | number). - if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 84 /* NumberLike */ | 262178 /* StringLike */ | 512 /* ESSymbol */)) { + if (links.resolvedType.flags & 6144 /* Nullable */ || + !isTypeAssignableToKind(links.resolvedType, 262178 /* StringLike */ | 84 /* NumberLike */ | 512 /* ESSymbol */) && + !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -35484,9 +35565,7 @@ var ts; * emptyObjectType if there is no "prop" in the element instance type */ function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) { - if (!elementType) { - elementType = checkExpression(openingLikeElement.tagName); - } + if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); } if (elementType.flags & 65536 /* Union */) { var types = elementType.types; return getUnionType(types.map(function (type) { @@ -35607,11 +35686,12 @@ var ts; */ function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) { var links = getNodeLinks(node); - if (!links.resolvedJsxElementAttributesType) { + var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { var elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); } - return links.resolvedJsxElementAttributesType; + return links[linkLocation]; } /** * Get all possible attributes type, especially from an overload stateless function component, of the given JSX opening-like element. @@ -36084,7 +36164,7 @@ var ts; if (prop && noUnusedIdentifiers && (prop.flags & 106500 /* ClassMember */) && - prop.valueDeclaration && (ts.getModifierFlags(prop.valueDeclaration) & 8 /* Private */)) { + prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8 /* Private */)) { if (ts.getCheckFlags(prop) & 1 /* Instantiated */) { getSymbolLinks(prop).target.isReferenced = true; } @@ -36407,8 +36487,8 @@ var ts; return undefined; } // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec) - function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper) { - var context = createInferenceContext(signature, 1 /* InferUnionTypes */); + function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) { + var context = createInferenceContext(signature, 1 /* InferUnionTypes */, compareTypes); forEachMatchingParameterType(contextualSignature, signature, function (source, target) { // Type parameters from outer context referenced by source type are fixed by instantiation of the source type inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); @@ -36780,7 +36860,7 @@ var ts; return getLiteralType(element.name.text); case 144 /* ComputedPropertyName */: var nameType = checkComputedPropertyName(element.name); - if (isTypeOfKind(nameType, 512 /* ESSymbol */)) { + if (isTypeAssignableToKind(nameType, 512 /* ESSymbol */)) { return nameType; } else { @@ -36921,9 +37001,10 @@ var ts; // // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. + var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; var excludeArgument; var excludeCount = 0; - if (!isDecorator) { + if (!isDecorator && !isSingleNonGenericCandidate) { // We do not need to call `getEffectiveArgumentCount` here as it only // applies when calculating the number of arguments for a decorator. for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { @@ -37068,6 +37149,17 @@ var ts; if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; + if (isSingleNonGenericCandidate) { + var candidate = candidates[0]; + if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + return undefined; + } + if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { + candidateForArgumentError = candidate; + return undefined; + } + return candidate; + } for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { var originalCandidate = candidates[candidateIndex]; if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { @@ -37230,7 +37322,7 @@ var ts; // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. var valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && ts.getModifierFlags(valueDecl) & 128 /* Abstract */) { + if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) { error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(ts.getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -37277,9 +37369,9 @@ var ts; return true; } var declaration = signature.declaration; - var modifiers = ts.getModifierFlags(declaration); + var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */); // Public constructor is accessible. - if (!(modifiers & 24 /* NonPublicAccessibilityModifier */)) { + if (!modifiers) { return true; } var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); @@ -37546,11 +37638,33 @@ var ts; if (moduleSymbol) { var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); } } return createPromiseReturnType(node, anyType); } + function getTypeWithSyntheticDefaultImportType(type, symbol) { + if (allowSyntheticDefaultImports && type && type !== unknownType) { + var synthType = type; + if (!synthType.syntheticType) { + if (!getPropertyOfType(type, "default" /* Default */)) { + var memberTable = ts.createSymbolTable(); + var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */); + newSymbol.target = resolveSymbol(symbol); + memberTable.set("default" /* Default */, newSymbol); + var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */); + var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + anonymousSymbol.type = defaultContainingObject; + synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + } + else { + synthType.syntheticType = type; + } + } + return synthType.syntheticType; + } + return type; + } function isCommonJsRequire(node) { if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { return false; @@ -37675,15 +37789,15 @@ var ts; } // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push // the destructured type into the contained binding elements. - function assignBindingElementTypes(node) { - if (ts.isBindingPattern(node.name)) { - for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) { - var element = _a[_i]; - if (!ts.isOmittedExpression(element)) { - if (element.name.kind === 71 /* Identifier */) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); - } - assignBindingElementTypes(element); + function assignBindingElementTypes(pattern) { + for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (!ts.isOmittedExpression(element)) { + if (element.name.kind === 71 /* Identifier */) { + getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + } + else { + assignBindingElementTypes(element.name); } } } @@ -37692,13 +37806,14 @@ var ts; var links = getSymbolLinks(parameter); if (!links.type) { links.type = contextualType; - var name = ts.getNameOfDeclaration(parameter.valueDeclaration); - // if inference didn't come up with anything but {}, fall back to the binding pattern if present. - if (links.type === emptyObjectType && - (name.kind === 174 /* ObjectBindingPattern */ || name.kind === 175 /* ArrayBindingPattern */)) { - links.type = getTypeFromBindingPattern(name); + var decl = parameter.valueDeclaration; + if (decl.name.kind !== 71 /* Identifier */) { + // if inference didn't come up with anything but {}, fall back to the binding pattern if present. + if (links.type === emptyObjectType) { + links.type = getTypeFromBindingPattern(decl.name); + } + assignBindingElementTypes(decl.name); } - assignBindingElementTypes(parameter.valueDeclaration); } } function createPromiseType(promisedType) { @@ -37934,16 +38049,16 @@ var ts; } function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) { ts.Debug.assert(node.kind !== 151 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node)); - // Grammar checking - var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); - if (!hasGrammarError && node.kind === 186 /* FunctionExpression */) { - checkGrammarForGenerator(node); - } // The identityMapper object is used to indicate that function expressions are wildcards if (checkMode === 1 /* SkipContextSensitive */ && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } + // Grammar checking + var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); + if (!hasGrammarError && node.kind === 186 /* FunctionExpression */) { + checkGrammarForGenerator(node); + } var links = getNodeLinks(node); var type = getTypeOfSymbol(node.symbol); // Check if function expression is contextually typed and assign parameter types if so. @@ -38028,7 +38143,7 @@ var ts; } } function checkArithmeticOperandType(operand, type, diagnostic) { - if (!isTypeAnyOrAllConstituentTypesHaveKind(type, 84 /* NumberLike */)) { + if (!isTypeAssignableToKind(type, 84 /* NumberLike */)) { error(operand, diagnostic); return false; } @@ -38129,8 +38244,13 @@ var ts; if (operandType === silentNeverType) { return silentNeverType; } - if (node.operator === 38 /* MinusToken */ && node.operand.kind === 8 /* NumericLiteral */) { - return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + if (node.operand.kind === 8 /* NumericLiteral */) { + if (node.operator === 38 /* MinusToken */) { + return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); + } + else if (node.operator === 37 /* PlusToken */) { + return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text)); + } } switch (node.operator) { case 37 /* PlusToken */: @@ -38186,33 +38306,22 @@ var ts; } return false; } - // Return true if type is of the given kind. A union type is of a given kind if all constituent types - // are of the given kind. An intersection type is of a given kind if at least one constituent type is - // of the given kind. - function isTypeOfKind(type, kind) { - if (type.flags & kind) { - return true; - } - if (type.flags & 65536 /* Union */) { - var types = type.types; - for (var _i = 0, types_18 = types; _i < types_18.length; _i++) { - var t = types_18[_i]; - if (!isTypeOfKind(t, kind)) { - return false; - } - } + function isTypeAssignableToKind(source, kind, strict) { + if (source.flags & kind) { return true; } - if (type.flags & 131072 /* Intersection */) { - var types = type.types; - for (var _a = 0, types_19 = types; _a < types_19.length; _a++) { - var t = types_19[_a]; - if (isTypeOfKind(t, kind)) { - return true; - } - } + if (strict && source.flags & (1 /* Any */ | 1024 /* Void */ | 2048 /* Undefined */ | 4096 /* Null */)) { + return false; } - return false; + return (kind & 84 /* NumberLike */ && isTypeAssignableTo(source, numberType)) || + (kind & 262178 /* StringLike */ && isTypeAssignableTo(source, stringType)) || + (kind & 136 /* BooleanLike */ && isTypeAssignableTo(source, booleanType)) || + (kind & 1024 /* Void */ && isTypeAssignableTo(source, voidType)) || + (kind & 8192 /* Never */ && isTypeAssignableTo(source, neverType)) || + (kind & 4096 /* Null */ && isTypeAssignableTo(source, nullType)) || + (kind & 2048 /* Undefined */ && isTypeAssignableTo(source, undefinedType)) || + (kind & 512 /* ESSymbol */ && isTypeAssignableTo(source, esSymbolType)) || + (kind & 16777216 /* NonPrimitive */ && isTypeAssignableTo(source, nonPrimitiveType)); } function isConstEnumObjectType(type) { return getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && isConstEnumSymbol(type.symbol); @@ -38229,7 +38338,7 @@ var ts; // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature. // The result is always of the Boolean primitive type. // NOTE: do not raise error if leftType is unknown as related error was already reported - if (isTypeOfKind(leftType, 8190 /* Primitive */)) { + if (!isTypeAny(leftType) && isTypeAssignableToKind(leftType, 8190 /* Primitive */)) { error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } // NOTE: do not raise error if right is unknown as related error was already reported @@ -38251,18 +38360,18 @@ var ts; // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, // and the right operand to be of type Any, an object type, or a type parameter type. // The result is always of the Boolean primitive type. - if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, 84 /* NumberLike */ | 512 /* ESSymbol */))) { + if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 /* NumberLike */ | 512 /* ESSymbol */))) { error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 /* Object */ | 540672 /* TypeVariable */ | 16777216 /* NonPrimitive */)) { + if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) { error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; } function checkObjectLiteralAssignment(node, sourceType) { var properties = node.properties; - for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { - var p = properties_6[_i]; + for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) { + var p = properties_7[_i]; checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties); } return sourceType; @@ -38541,30 +38650,28 @@ var ts; if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (!isTypeOfKind(leftType, 1 /* Any */ | 262178 /* StringLike */) && !isTypeOfKind(rightType, 1 /* Any */ | 262178 /* StringLike */)) { + if (!isTypeAssignableToKind(leftType, 262178 /* StringLike */) && !isTypeAssignableToKind(rightType, 262178 /* StringLike */)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } var resultType = void 0; - if (isTypeOfKind(leftType, 84 /* NumberLike */) && isTypeOfKind(rightType, 84 /* NumberLike */)) { + if (isTypeAssignableToKind(leftType, 84 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 84 /* NumberLike */, /*strict*/ true)) { // Operands of an enum type are treated as having the primitive type Number. // If both operands are of the Number primitive type, the result is of the Number primitive type. resultType = numberType; } - else { - if (isTypeOfKind(leftType, 262178 /* StringLike */) || isTypeOfKind(rightType, 262178 /* StringLike */)) { - // If one or both operands are of the String primitive type, the result is of the String primitive type. - resultType = stringType; - } - else if (isTypeAny(leftType) || isTypeAny(rightType)) { - // Otherwise, the result is of type Any. - // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. - resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; - } - // Symbols are not allowed at all in arithmetic expressions - if (resultType && !checkForDisallowedESSymbolOperand(operator)) { - return resultType; - } + else if (isTypeAssignableToKind(leftType, 262178 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 262178 /* StringLike */, /*strict*/ true)) { + // If one or both operands are of the String primitive type, the result is of the String primitive type. + resultType = stringType; + } + else if (isTypeAny(leftType) || isTypeAny(rightType)) { + // Otherwise, the result is of type Any. + // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. + resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; + } + // Symbols are not allowed at all in arithmetic expressions + if (resultType && !checkForDisallowedESSymbolOperand(operator)) { + return resultType; } if (!resultType) { reportOperatorError(); @@ -38749,13 +38856,12 @@ var ts; return getBestChoiceType(type1, type2); } function checkLiteralExpression(node) { - if (node.kind === 8 /* NumericLiteral */) { - checkGrammarNumericLiteral(node); - } switch (node.kind) { + case 13 /* NoSubstitutionTemplateLiteral */: case 9 /* StringLiteral */: return getFreshTypeOfLiteralType(getLiteralType(node.text)); case 8 /* NumericLiteral */: + checkGrammarNumericLiteral(node); return getFreshTypeOfLiteralType(getLiteralType(+node.text)); case 101 /* TrueKeyword */: return trueType; @@ -38951,6 +39057,7 @@ var ts; return checkSuperExpression(node); case 95 /* NullKeyword */: return nullWideningType; + case 13 /* NoSubstitutionTemplateLiteral */: case 9 /* StringLiteral */: case 8 /* NumericLiteral */: case 101 /* TrueKeyword */: @@ -38958,8 +39065,6 @@ var ts; return checkLiteralExpression(node); case 196 /* TemplateExpression */: return checkTemplateExpression(node); - case 13 /* NoSubstitutionTemplateLiteral */: - return stringType; case 12 /* RegularExpressionLiteral */: return globalRegExpType; case 177 /* ArrayLiteralExpression */: @@ -39058,7 +39163,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); checkVariableLikeDeclaration(node); var func = ts.getContainingFunction(node); - if (ts.getModifierFlags(node) & 92 /* ParameterPropertyModifier */) { + if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { func = ts.getContainingFunction(node); if (!(func.kind === 152 /* Constructor */ && ts.nodeIsPresent(func.body))) { error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -39264,7 +39369,7 @@ var ts; } } else { - var isStatic = ts.getModifierFlags(member) & 32 /* Static */; + var isStatic = ts.hasModifier(member, 32 /* Static */); var names = isStatic ? staticNames : instanceNames; var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); if (memberName) { @@ -39320,7 +39425,7 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var memberNameNode = member.name; - var isStatic = ts.getModifierFlags(member) & 32 /* Static */; + var isStatic = ts.hasModifier(member, 32 /* Static */); if (isStatic && memberNameNode) { var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -39418,7 +39523,7 @@ var ts; checkFunctionOrMethodDeclaration(node); // Abstract methods cannot have an implementation. // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node. - if (ts.getModifierFlags(node) & 128 /* Abstract */ && node.body) { + if (ts.hasModifier(node, 128 /* Abstract */) && node.body) { error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } @@ -39458,17 +39563,9 @@ var ts; } return ts.forEachChild(n, containsSuperCall); } - function markThisReferencesAsErrors(n) { - if (n.kind === 99 /* ThisKeyword */) { - error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location); - } - else if (n.kind !== 186 /* FunctionExpression */ && n.kind !== 228 /* FunctionDeclaration */) { - ts.forEachChild(n, markThisReferencesAsErrors); - } - } function isInstancePropertyWithInitializer(n) { return n.kind === 149 /* PropertyDeclaration */ && - !(ts.getModifierFlags(n) & 32 /* Static */) && + !ts.hasModifier(n, 32 /* Static */) && !!n.initializer; } // TS 1.0 spec (April 2014): 8.3.2 @@ -39488,8 +39585,8 @@ var ts; // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. - var superCallShouldBeFirst = ts.forEach(node.parent.members, isInstancePropertyWithInitializer) || - ts.forEach(node.parameters, function (p) { return ts.getModifierFlags(p) & 92 /* ParameterPropertyModifier */; }); + var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) || + ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); }); // Skip past any prologue directives to find the first statement // to ensure that it was a super call. if (superCallShouldBeFirst) { @@ -39540,10 +39637,12 @@ var ts; var otherKind = node.kind === 153 /* GetAccessor */ ? 154 /* SetAccessor */ : 153 /* GetAccessor */; var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if ((ts.getModifierFlags(node) & 28 /* AccessibilityModifier */) !== (ts.getModifierFlags(otherAccessor) & 28 /* AccessibilityModifier */)) { + var nodeFlags = ts.getModifierFlags(node); + var otherFlags = ts.getModifierFlags(otherAccessor); + if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) { error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (ts.hasModifier(node, 128 /* Abstract */) !== ts.hasModifier(otherAccessor, 128 /* Abstract */)) { + if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) { error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } // TypeScript 1.0 spec (April 2014): 4.5 @@ -39600,7 +39699,17 @@ var ts; ts.forEach(node.typeArguments, checkSourceElement); if (produceDiagnostics) { var symbol = getNodeLinks(node).resolvedSymbol; - var typeParameters = symbol.flags & 524288 /* TypeAlias */ ? getSymbolLinks(symbol).typeParameters : type.target.localTypeParameters; + if (!symbol) { + // There is no resolved symbol cached if the type resolved to a builtin + // via JSDoc type reference resolution (eg, Boolean became boolean), none + // of which are generic when they have no associated symbol + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return; + } + var typeParameters = symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters; + if (!typeParameters && getObjectFlags(type) & 4 /* Reference */) { + typeParameters = type.target.localTypeParameters; + } checkTypeArgumentConstraints(typeParameters, node.typeArguments); } } @@ -39647,7 +39756,7 @@ var ts; } // Check if we're indexing with a numeric type and the object type is a generic // type with a constraint that has a numeric index signature. - if (maybeTypeOfKind(objectType, 540672 /* TypeVariable */) && isTypeOfKind(indexType, 84 /* NumberLike */)) { + if (maybeTypeOfKind(objectType, 540672 /* TypeVariable */) && isTypeAssignableToKind(indexType, 84 /* NumberLike */)) { var constraint = getBaseConstraintOfType(objectType); if (constraint && getIndexInfoOfType(constraint, 1 /* Number */)) { return type; @@ -39657,6 +39766,8 @@ var ts; return type; } function checkIndexedAccessType(node) { + checkSourceElement(node.objectType); + checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } function checkMappedType(node) { @@ -39667,7 +39778,7 @@ var ts; checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); } function isPrivateWithinAmbient(node) { - return (ts.getModifierFlags(node) & 8 /* Private */) && ts.isInAmbientContext(node); + return ts.hasModifier(node, 8 /* Private */) && ts.isInAmbientContext(node); } function getEffectiveDeclarationFlags(n, flagsToCheck) { var flags = ts.getCombinedModifierFlags(n); @@ -39767,13 +39878,13 @@ var ts; (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { var reportError = (node.kind === 151 /* MethodDeclaration */ || node.kind === 150 /* MethodSignature */) && - (ts.getModifierFlags(node) & 32 /* Static */) !== (ts.getModifierFlags(subsequentNode) & 32 /* Static */); + ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */); // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { - var diagnostic = ts.getModifierFlags(node) & 32 /* Static */ ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; + var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode_1, diagnostic); } return; @@ -39791,7 +39902,7 @@ var ts; else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. - if (ts.getModifierFlags(node) & 128 /* Abstract */) { + if (ts.hasModifier(node, 128 /* Abstract */)) { error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -39801,8 +39912,8 @@ var ts; } var duplicateFunctionDeclaration = false; var multipleConstructorImplementation = false; - for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { - var current = declarations_5[_i]; + for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { + var current = declarations_4[_i]; var node = current; var inAmbientContext = ts.isInAmbientContext(node); var inAmbientContextOrInterface = node.parent.kind === 230 /* InterfaceDeclaration */ || node.parent.kind === 163 /* TypeLiteral */ || inAmbientContext; @@ -39859,7 +39970,7 @@ var ts; } // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(ts.getModifierFlags(lastSeenNonAmbientDeclaration) & 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) { + !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } if (hasOverloads) { @@ -40569,14 +40680,14 @@ var ts; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 151 /* MethodDeclaration */ || member.kind === 149 /* PropertyDeclaration */) { - if (!member.symbol.isReferenced && ts.getModifierFlags(member) & 8 /* Private */) { + if (!member.symbol.isReferenced && ts.hasModifier(member, 8 /* Private */)) { error(member.name, ts.Diagnostics._0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(member.symbol.escapedName)); } } else if (member.kind === 152 /* Constructor */) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; - if (!parameter.symbol.isReferenced && ts.getModifierFlags(parameter) & 8 /* Private */) { + if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) { error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_never_used, ts.unescapeLeadingUnderscores(parameter.symbol.escapedName)); } } @@ -40997,7 +41108,7 @@ var ts; 128 /* Abstract */ | 64 /* Readonly */ | 32 /* Static */; - return (ts.getModifierFlags(left) & interestingFlags) === (ts.getModifierFlags(right) & interestingFlags); + return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); @@ -41162,7 +41273,7 @@ var ts; } // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 32768 /* Object */ | 540672 /* TypeVariable */ | 16777216 /* NonPrimitive */)) { + if (!isTypeAssignableToKind(rightType, 16777216 /* NonPrimitive */ | 540672 /* TypeVariable */)) { error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } checkSourceElement(node.statement); @@ -41662,7 +41773,7 @@ var ts; // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, // and properties with literal names were already checked. - if (!(ts.getModifierFlags(member) & 32 /* Static */) && ts.hasDynamicName(member)) { + if (!ts.hasModifier(member, 32 /* Static */) && ts.hasDynamicName(member)) { var propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */); @@ -41773,8 +41884,8 @@ var ts; if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) { // Report an error on every conflicting declaration. var name = symbolToString(symbol); - for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { - var declaration = declarations_6[_i]; + for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { + var declaration = declarations_5[_i]; error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } @@ -41783,8 +41894,8 @@ var ts; function areTypeParametersIdentical(declarations, typeParameters) { var maxTypeArgumentCount = ts.length(typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { - var declaration = declarations_7[_i]; + for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { + var declaration = declarations_6[_i]; // If this declaration has too few or too many type parameters, we report an error var numTypeParameters = ts.length(declaration.typeParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { @@ -41827,7 +41938,7 @@ var ts; registerForUnusedIdentifiersCheck(node); } function checkClassDeclaration(node) { - if (!node.name && !(ts.getModifierFlags(node) & 512 /* Default */)) { + if (!node.name && !ts.hasModifier(node, 512 /* Default */)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -41925,7 +42036,7 @@ var ts; var signatures = getSignaturesOfType(type, 1 /* Construct */); if (signatures.length) { var declaration = signatures[0].declaration; - if (declaration && ts.getModifierFlags(declaration) & 8 /* Private */) { + if (declaration && ts.hasModifier(declaration, 8 /* Private */)) { var typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); @@ -41981,7 +42092,7 @@ var ts; // It is an error to inherit an abstract member without implementing it or being declared abstract. // If there is no declaration for the derived class (as in the case of class expressions), // then the class cannot be declared abstract. - if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !(ts.getModifierFlags(derivedClassDecl) & 128 /* Abstract */))) { + if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) { if (derivedClassDecl.kind === 199 /* ClassExpression */) { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } @@ -42032,8 +42143,8 @@ var ts; for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) { var base = baseTypes_2[_i]; var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); - for (var _a = 0, properties_7 = properties; _a < properties_7.length; _a++) { - var prop = properties_7[_a]; + for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) { + var prop = properties_8[_a]; var existing = seen.get(prop.escapedName); if (!existing) { seen.set(prop.escapedName, { prop: prop, containingType: base }); @@ -42307,8 +42418,8 @@ var ts; } function getFirstNonAmbientClassOrFunctionDeclaration(symbol) { var declarations = symbol.declarations; - for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { - var declaration = declarations_8[_i]; + for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { + var declaration = declarations_7[_i]; if ((declaration.kind === 229 /* ClassDeclaration */ || (declaration.kind === 228 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) && !ts.isInAmbientContext(declaration)) { @@ -42558,7 +42669,7 @@ var ts; // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -42586,7 +42697,7 @@ var ts; checkGrammarDecorators(node) || checkGrammarModifiers(node); if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (ts.getModifierFlags(node) & 1 /* Export */) { + if (ts.hasModifier(node, 1 /* Export */)) { markExportAsReferenced(node); } if (ts.isInternalModuleImportEqualsDeclaration(node)) { @@ -42617,7 +42728,7 @@ var ts; // If we hit an export in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { @@ -42682,7 +42793,7 @@ var ts; return; } // Grammar checking - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === 71 /* Identifier */) { @@ -42736,8 +42847,8 @@ var ts; return; } if (exportedDeclarationsCount > 1) { - for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { - var declaration = declarations_9[_i]; + for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { + var declaration = declarations_8[_i]; if (isNotOverload(declaration)) { diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } @@ -43046,7 +43157,7 @@ var ts; return []; } var symbols = ts.createSymbolTable(); - var memberFlags = 0 /* None */; + var isStatic = false; populateSymbols(); return symbolsToArray(symbols); function populateSymbols() { @@ -43075,7 +43186,7 @@ var ts; // add the type parameters into the symbol table // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol. // Note: that the memberFlags come from previous iteration. - if (!(memberFlags & 32 /* Static */)) { + if (!isStatic) { copySymbols(getSymbolOfNode(location).members, meaning & 793064 /* Type */); } break; @@ -43089,7 +43200,7 @@ var ts; if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } - memberFlags = ts.getModifierFlags(location); + isStatic = ts.hasModifier(location, 32 /* Static */); location = location.parent; } copySymbols(globals, meaning); @@ -43487,7 +43598,7 @@ var ts; */ function getParentTypeOfClassElement(node) { var classSymbol = getSymbolOfNode(node.parent); - return ts.getModifierFlags(node) & 32 /* Static */ + return ts.hasModifier(node, 32 /* Static */) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -43769,13 +43880,13 @@ var ts; return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && - !(ts.getModifierFlags(parameter) & 92 /* ParameterPropertyModifier */); + !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */); } function isOptionalUninitializedParameterProperty(parameter) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - !!(ts.getModifierFlags(parameter) & 92 /* ParameterPropertyModifier */); + ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */); } function getNodeCheckFlags(node) { return getNodeLinks(node).flags; @@ -43835,22 +43946,22 @@ var ts; else if (type.flags & 1 /* Any */) { return ts.TypeReferenceSerializationKind.ObjectType; } - else if (isTypeOfKind(type, 1024 /* Void */ | 6144 /* Nullable */ | 8192 /* Never */)) { + else if (isTypeAssignableToKind(type, 1024 /* Void */ | 6144 /* Nullable */ | 8192 /* Never */)) { return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } - else if (isTypeOfKind(type, 136 /* BooleanLike */)) { + else if (isTypeAssignableToKind(type, 136 /* BooleanLike */)) { return ts.TypeReferenceSerializationKind.BooleanType; } - else if (isTypeOfKind(type, 84 /* NumberLike */)) { + else if (isTypeAssignableToKind(type, 84 /* NumberLike */)) { return ts.TypeReferenceSerializationKind.NumberLikeType; } - else if (isTypeOfKind(type, 262178 /* StringLike */)) { + else if (isTypeAssignableToKind(type, 262178 /* StringLike */)) { return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } - else if (isTypeOfKind(type, 512 /* ESSymbol */)) { + else if (isTypeAssignableToKind(type, 512 /* ESSymbol */)) { return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { @@ -44346,7 +44457,7 @@ var ts; node.kind !== 154 /* SetAccessor */) { return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === 229 /* ClassDeclaration */ && ts.getModifierFlags(node.parent) & 128 /* Abstract */)) { + if (!(node.parent.kind === 229 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) { return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & 32 /* Static */) { @@ -44547,7 +44658,7 @@ var ts; if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (ts.getModifierFlags(parameter) !== 0) { + if (ts.hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -44850,10 +44961,10 @@ var ts; else if (ts.isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(ts.getModifierFlags(accessor) & 128 /* Abstract */)) { + else if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) { return grammarErrorAtPos(ts.getSourceFileOfNode(accessor), accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } - else if (accessor.body && ts.getModifierFlags(accessor) & 128 /* Abstract */) { + else if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) { return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { @@ -45196,7 +45307,7 @@ var ts; node.kind === 244 /* ExportDeclaration */ || node.kind === 243 /* ExportAssignment */ || node.kind === 236 /* NamespaceExportDeclaration */ || - ts.getModifierFlags(node) & (2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) { + ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) { return false; } return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); @@ -48142,7 +48253,7 @@ var ts; function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) { var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; if (property === firstAccessor) { - var properties_8 = []; + var properties_9 = []; if (getAccessor) { var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, /*asteriskToken*/ undefined, @@ -48152,7 +48263,7 @@ var ts; ts.setTextRange(getterFunction, getAccessor); ts.setOriginalNode(getterFunction, getAccessor); var getter = ts.createPropertyAssignment("get", getterFunction); - properties_8.push(getter); + properties_9.push(getter); } if (setAccessor) { var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, @@ -48163,15 +48274,15 @@ var ts; ts.setTextRange(setterFunction, setAccessor); ts.setOriginalNode(setterFunction, setAccessor); var setter = ts.createPropertyAssignment("set", setterFunction); - properties_8.push(setter); + properties_9.push(setter); } - properties_8.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); - properties_8.push(ts.createPropertyAssignment("configurable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); + properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue())); var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ receiver, createExpressionForPropertyName(property.name), - ts.createObjectLiteral(properties_8, multiLine) + ts.createObjectLiteral(properties_9, multiLine) ]), /*location*/ firstAccessor); return ts.aggregateTransformFlags(expression); @@ -50628,11 +50739,14 @@ var ts; : numElements, location), /*reuseIdentifierExpressions*/ false, location); } - else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)) { + else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0) + || ts.every(elements, ts.isOmittedExpression)) { // For anything other than a single-element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. Additionally, if we have zero elements // we need to emit *something* to ensure that in case a 'var' keyword was already emitted, // so in that case, we'll intentionally create that temporary. + // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]", + // then we will create temporary variable. var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } @@ -50919,7 +51033,16 @@ var ts; if (ts.hasModifier(node, 2 /* Ambient */)) { break; } - recordEmittedDeclarationInScope(node); + // Record these declarations provided that they have a name. + if (node.name) { + recordEmittedDeclarationInScope(node); + } + else { + // These nodes should always have names unless they are default-exports; + // however, class declaration parsing allows for undefined names, so syntactically invalid + // programs may also have an undefined name. + ts.Debug.assert(node.kind === 229 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */)); + } break; } } @@ -51748,8 +51871,8 @@ var ts; * @param receiver The receiver on which each property should be assigned. */ function addInitializedPropertyStatements(statements, properties, receiver) { - for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) { - var property = properties_9[_i]; + for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { + var property = properties_10[_i]; var statement = ts.createStatement(transformInitializedProperty(property, receiver)); ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); ts.setCommentRange(statement, property); @@ -51764,8 +51887,8 @@ var ts; */ function generateInitializedPropertyExpressions(properties, receiver) { var expressions = []; - for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { - var property = properties_10[_i]; + for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { + var property = properties_11[_i]; var expression = transformInitializedProperty(property, receiver); expression.startsOnNewLine = true; ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); @@ -52928,33 +53051,30 @@ var ts; /** * Records that a declaration was emitted in the current scope, if it was the first * declaration for the provided symbol. - * - * NOTE: if there is ever a transformation above this one, we may not be able to rely - * on symbol names. */ function recordEmittedDeclarationInScope(node) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - if (!currentScopeFirstDeclarationsOfName) { - currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); - } - if (!currentScopeFirstDeclarationsOfName.has(name)) { - currentScopeFirstDeclarationsOfName.set(name, node); - } + if (!currentScopeFirstDeclarationsOfName) { + currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); + } + var name = declaredNameInScope(node); + if (!currentScopeFirstDeclarationsOfName.has(name)) { + currentScopeFirstDeclarationsOfName.set(name, node); } } /** - * Determines whether a declaration is the first declaration with the same name emitted - * in the current scope. + * Determines whether a declaration is the first declaration with + * the same name emitted in the current scope. */ function isFirstEmittedDeclarationInScope(node) { if (currentScopeFirstDeclarationsOfName) { - var name = node.symbol && node.symbol.escapedName; - if (name) { - return currentScopeFirstDeclarationsOfName.get(name) === node; - } + var name = declaredNameInScope(node); + return currentScopeFirstDeclarationsOfName.get(name) === node; } - return false; + return true; + } + function declaredNameInScope(node) { + ts.Debug.assertNode(node.name, ts.isIdentifier); + return node.name.escapedText; } /** * Adds a leading VariableStatement for a enum or module declaration. @@ -53021,7 +53141,7 @@ var ts; if (!shouldEmitModuleDeclaration(node)) { return ts.createNotEmittedStatement(node); } - ts.Debug.assert(ts.isIdentifier(node.name), "TypeScript module should have an Identifier name."); + ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name."); enableSubstitutionForNamespaceExports(); var statements = []; // We request to be advised when the printer is about to print this node. This allows @@ -54050,6 +54170,8 @@ var ts; return visitExpressionStatement(node); case 185 /* ParenthesizedExpression */: return visitParenthesizedExpression(node, noDestructuringValue); + case 260 /* CatchClause */: + return visitCatchClause(node); default: return ts.visitEachChild(node, visitor, context); } @@ -54130,6 +54252,12 @@ var ts; function visitParenthesizedExpression(node, noDestructuringValue) { return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context); } + function visitCatchClause(node) { + if (!node.variableDeclaration) { + return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock)); + } + return ts.visitEachChild(node, visitor, context); + } /** * Visits a BinaryExpression that contains a destructuring assignment. * @@ -54674,7 +54802,7 @@ var ts; objectProperties = ts.createAssignHelper(context, segments); } } - var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.filter(ts.map(children, transformJsxChildToExpression), ts.isDefined), node, location); + var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } @@ -55378,7 +55506,7 @@ var ts; function shouldVisitNode(node) { return (node.transformFlags & 128 /* ContainsES2015 */) !== 0 || convertedLoopState !== undefined - || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && ts.isStatement(node)) + || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */))) || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)) || isTypeScriptClassWrapper(node); } @@ -55733,10 +55861,12 @@ var ts; var outer = ts.createPartiallyEmittedExpression(inner); outer.end = ts.skipTrivia(currentText, node.pos); ts.setEmitFlags(outer, 1536 /* NoComments */); - return ts.createParen(ts.createCall(outer, + var result = ts.createParen(ts.createCall(outer, /*typeArguments*/ undefined, extendsClauseElement ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)] : [])); + ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class "); + return result; } /** * Transforms a ClassExpression or ClassDeclaration into a function body. @@ -56654,13 +56784,14 @@ var ts; ts.setTextRange(declarationList, node); ts.setCommentRange(declarationList, node); if (node.transformFlags & 8388608 /* ContainsBindingPattern */ - && (ts.isBindingPattern(node.declarations[0].name) - || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { + && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { // If the first or last declaration is a binding pattern, we need to modify // the source map range for the declaration list. var firstDeclaration = ts.firstOrUndefined(declarations); - var lastDeclaration = ts.lastOrUndefined(declarations); - ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + if (firstDeclaration) { + var lastDeclaration = ts.lastOrUndefined(declarations); + ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); + } } return declarationList; } @@ -57405,6 +57536,7 @@ var ts; function visitCatchClause(node) { var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */); var updated; + ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (ts.isBindingPattern(node.variableDeclaration.name)) { var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); var newVariableDeclaration = ts.createVariableDeclaration(temp); @@ -59979,9 +60111,6 @@ var ts; var block = endBlock(); markLabel(block.endLabel); } - function isWithBlock(block) { - return block.kind === 1 /* With */; - } /** * Begins a code block for a generated `try` statement. */ @@ -60065,9 +60194,6 @@ var ts; emitNop(); exception.state = 3 /* Done */; } - function isExceptionBlock(block) { - return block.kind === 0 /* Exception */; - } /** * Begins a code block that supports `break` or `continue` statements that are defined in * the source tree and not from generated code. @@ -60301,7 +60427,7 @@ var ts; * @param location An optional source map location for the statement. */ function createInlineBreak(label, location) { - ts.Debug.assert(label > 0, "Invalid label: " + label); + ts.Debug.assertLessThan(0, label, "Invalid label"); return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3 /* Break */), createLabel(label) @@ -60642,31 +60768,33 @@ var ts; for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { var block = blocks[blockIndex]; var blockAction = blockActions[blockIndex]; - if (isExceptionBlock(block)) { - if (blockAction === 0 /* Open */) { - if (!exceptionBlockStack) { - exceptionBlockStack = []; + switch (block.kind) { + case 0 /* Exception */: + if (blockAction === 0 /* Open */) { + if (!exceptionBlockStack) { + exceptionBlockStack = []; + } + if (!statements) { + statements = []; + } + exceptionBlockStack.push(currentExceptionBlock); + currentExceptionBlock = block; } - if (!statements) { - statements = []; + else if (blockAction === 1 /* Close */) { + currentExceptionBlock = exceptionBlockStack.pop(); } - exceptionBlockStack.push(currentExceptionBlock); - currentExceptionBlock = block; - } - else if (blockAction === 1 /* Close */) { - currentExceptionBlock = exceptionBlockStack.pop(); - } - } - else if (isWithBlock(block)) { - if (blockAction === 0 /* Open */) { - if (!withBlockStack) { - withBlockStack = []; + break; + case 1 /* With */: + if (blockAction === 0 /* Open */) { + if (!withBlockStack) { + withBlockStack = []; + } + withBlockStack.push(block); } - withBlockStack.push(block); - } - else if (blockAction === 1 /* Close */) { - withBlockStack.pop(); - } + else if (blockAction === 1 /* Close */) { + withBlockStack.pop(); + } + break; } } } @@ -64580,14 +64708,14 @@ var ts; writer.writeLine(); } } - function emitTrailingCommentsOfPosition(pos) { + function emitTrailingCommentsOfPosition(pos, prefixSpace) { if (disabled) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeEmitTrailingCommentsOfPosition"); } - forEachTrailingCommentToEmit(pos, emitTrailingCommentOfPosition); + forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition); if (extendedDiagnostics) { ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); } @@ -64676,17 +64804,7 @@ var ts; * @return true if the comment is a triple-slash comment else false */ function isTripleSlashComment(commentPos, commentEnd) { - // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text - // so that we don't end up computing comment string and doing match for all // comments - if (currentText.charCodeAt(commentPos + 1) === 47 /* slash */ && - commentPos + 2 < commentEnd && - currentText.charCodeAt(commentPos + 2) === 47 /* slash */) { - var textSubStr = currentText.substring(commentPos, commentEnd); - return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || - textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ? - true : false; - } - return false; + return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd); } } ts.createCommentWriter = createCommentWriter; @@ -65898,6 +66016,10 @@ var ts; return ts.forEach(node.declarationList.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); }); } function writeVariableStatement(node) { + // If binding pattern doesn't have name, then there is nothing to be emitted for declaration file i.e. const [,] = [1,2]. + if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) { + return; + } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isLet(node.declarationList)) { @@ -67437,7 +67559,9 @@ var ts; if (!(ts.getEmitFlags(node) & 131072 /* NoIndentation */)) { var dotRangeStart = node.expression.end; var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1; - var dotToken = { kind: 23 /* DotToken */, pos: dotRangeStart, end: dotRangeEnd }; + var dotToken = ts.createToken(23 /* DotToken */); + dotToken.pos = dotRangeStart; + dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } @@ -67566,7 +67690,9 @@ var ts; var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right); emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); + emitLeadingCommentsOfPosition(node.operatorToken.pos); writeTokenNode(node.operatorToken); + emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); decreaseIndentIf(indentBeforeOperator, indentAfterOperator); @@ -67760,8 +67886,19 @@ var ts; emitWithPrefix(" ", node.label); write(";"); } + function emitTokenWithComment(token, pos, contextNode) { + var node = contextNode && ts.getParseTreeNode(contextNode); + if (node && node.kind === contextNode.kind) { + pos = ts.skipTrivia(currentSourceFile.text, pos); + } + pos = writeToken(token, pos, /*contextNode*/ contextNode); + if (node && node.kind === contextNode.kind) { + emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true); + } + return pos; + } function emitReturnStatement(node) { - writeToken(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node); + emitTokenWithComment(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node); emitExpressionWithPrefix(" ", node.expression); write(";"); } @@ -68237,10 +68374,12 @@ var ts; function emitCatchClause(node) { var openParenPos = writeToken(74 /* CatchKeyword */, node.pos); write(" "); - writeToken(19 /* OpenParenToken */, openParenPos); - emit(node.variableDeclaration); - writeToken(20 /* CloseParenToken */, node.variableDeclaration ? node.variableDeclaration.end : openParenPos); - write(" "); + if (node.variableDeclaration) { + writeToken(19 /* OpenParenToken */, openParenPos); + emit(node.variableDeclaration); + writeToken(20 /* CloseParenToken */, node.variableDeclaration.end); + write(" "); + } emit(node.block); } // @@ -69520,6 +69659,14 @@ var ts; var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; }; resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); }; } + // Map from a stringified PackageId to the source file with that id. + // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile). + // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around. + var packageIdToSourceFile = ts.createMap(); + // Maps from a SourceFile's `.path` to the name of the package it was imported with. + var sourceFileToPackageName = ts.createMap(); + // See `sourceFileIsRedirectedTo`. + var redirectTargetsSet = ts.createMap(); var filesByName = ts.createMap(); // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing @@ -69588,6 +69735,8 @@ var ts; isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker, getSourceFileFromReference: getSourceFileFromReference, + sourceFileToPackageName: sourceFileToPackageName, + redirectTargetsSet: redirectTargetsSet, }; verifyCompilerOptions(); ts.performance.mark("afterProgram"); @@ -69780,17 +69929,57 @@ var ts; var filePaths = []; var modifiedSourceFiles = []; oldProgram.structureIsReused = 2 /* Completely */; - for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) { - var oldSourceFile = _a[_i]; + var oldSourceFiles = oldProgram.getSourceFiles(); + var SeenPackageName; + (function (SeenPackageName) { + SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists"; + SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified"; + })(SeenPackageName || (SeenPackageName = {})); + var seenPackageNames = ts.createMap(); + for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { + var oldSourceFile = oldSourceFiles_1[_i]; var newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target) : host.getSourceFile(oldSourceFile.fileName, options.target); if (!newSourceFile) { return oldProgram.structureIsReused = 0 /* Not */; } + ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); + var fileChanged = void 0; + if (oldSourceFile.redirectInfo) { + // We got `newSourceFile` by path, so it is actually for the unredirected file. + // This lets us know if the unredirected file has changed. If it has we should break the redirect. + if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { + // Underlying file has changed. Might not redirect anymore. Must rebuild program. + return oldProgram.structureIsReused = 0 /* Not */; + } + fileChanged = false; + newSourceFile = oldSourceFile; // Use the redirect. + } + else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) { + // If a redirected-to source file changes, the redirect may be broken. + if (newSourceFile !== oldSourceFile) { + return oldProgram.structureIsReused = 0 /* Not */; + } + fileChanged = false; + } + else { + fileChanged = newSourceFile !== oldSourceFile; + } newSourceFile.path = oldSourceFile.path; filePaths.push(newSourceFile.path); - if (oldSourceFile !== newSourceFile) { + var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); + if (packageName !== undefined) { + // If there are 2 different source files for the same package name and at least one of them changes, + // they might become redirects. So we must rebuild the program. + var prevKind = seenPackageNames.get(packageName); + var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */; + if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) { + return oldProgram.structureIsReused = 0 /* Not */; + } + seenPackageNames.set(packageName, newKind); + } + if (fileChanged) { // The `newSourceFile` object was created for the new program. if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { // value of no-default-lib has changed @@ -69831,8 +70020,8 @@ var ts; } modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; }); // try to verify results of module resolution - for (var _b = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _b < modifiedSourceFiles_1.length; _b++) { - var _c = modifiedSourceFiles_1[_b], oldSourceFile = _c.oldFile, newSourceFile = _c.newFile; + for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) { + var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile; var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { var moduleNames = ts.map(ts.concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral); @@ -69875,8 +70064,8 @@ var ts; if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) { return oldProgram.structureIsReused = 1 /* SafeModules */; } - for (var _d = 0, _e = oldProgram.getMissingFilePaths(); _d < _e.length; _d++) { - var p = _e[_d]; + for (var _c = 0, _d = oldProgram.getMissingFilePaths(); _c < _d.length; _c++) { + var p = _d[_c]; filesByName.set(p, undefined); } // update fileName -> file mapping @@ -69885,11 +70074,13 @@ var ts; } files = newSourceFiles; fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics(); - for (var _f = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _f < modifiedSourceFiles_2.length; _f++) { - var modifiedFile = modifiedSourceFiles_2[_f]; + for (var _e = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _e < modifiedSourceFiles_2.length; _e++) { + var modifiedFile = modifiedSourceFiles_2[_e]; fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile); } resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives(); + sourceFileToPackageName = oldProgram.sourceFileToPackageName; + redirectTargetsSet = oldProgram.redirectTargetsSet; return oldProgram.structureIsReused = 2 /* Completely */; } function getEmitHost(writeFileCallback) { @@ -70436,7 +70627,7 @@ var ts; } /** This has side effects through `findSourceFile`. */ function processSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd) { - getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd); }, function (diagnostic) { + getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, /*packageId*/ undefined); }, function (diagnostic) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; @@ -70453,8 +70644,25 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } } + function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) { + var redirect = Object.create(redirectTarget); + redirect.fileName = fileName; + redirect.path = path; + redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected }; + Object.defineProperties(redirect, { + id: { + get: function () { return this.redirectInfo.redirectTarget.id; }, + set: function (value) { this.redirectInfo.redirectTarget.id = value; }, + }, + symbol: { + get: function () { return this.redirectInfo.redirectTarget.symbol; }, + set: function (value) { this.redirectInfo.redirectTarget.symbol = value; }, + }, + }); + return redirect; + } // Get source file from normalized fileName - function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd) { + function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) { if (filesByName.has(path)) { var file_1 = filesByName.get(path); // try to check if we've already seen this file but with a different casing in path @@ -70490,6 +70698,25 @@ var ts; fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); + if (packageId) { + var packageIdKey = packageId.name + "@" + packageId.version; + var fileFromPackageId = packageIdToSourceFile.get(packageIdKey); + if (fileFromPackageId) { + // Some other SourceFile already exists with this package name and version. + // Instead of creating a duplicate, just redirect to the existing one. + var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path); + redirectTargetsSet.set(fileFromPackageId.path, true); + filesByName.set(path, dupFile); + sourceFileToPackageName.set(path, packageId.name); + files.push(dupFile); + return dupFile; + } + else if (file) { + // This is the first source file to have this packageId. + packageIdToSourceFile.set(packageIdKey, file); + sourceFileToPackageName.set(path, packageId.name); + } + } filesByName.set(path, file); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); @@ -70630,7 +70857,7 @@ var ts; else if (shouldAddFile) { var path = toPath(resolvedFileName); var pos = ts.skipTrivia(file.text, file.imports[i].pos); - findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end); + findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end, resolution.packageId); } if (isFromNodeModulesSearch) { currentNodeModulesDepth--; @@ -70785,8 +71012,8 @@ var ts; } // there has to be common source directory if user specified --outdir || --sourceRoot // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted - if (options.outDir || - options.sourceRoot || + if (options.outDir || // there is --outDir specified + options.sourceRoot || // there is --sourceRoot specified options.mapRoot) { // Precalculate and cache the common source directory var dir = getCommonSourceDirectory(); @@ -71349,6 +71576,12 @@ var ts; category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "preserveSymlinks", + type: "boolean", + category: ts.Diagnostics.Module_Resolution_Options, + description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, + }, // Source Maps { name: "sourceRoot", @@ -72006,7 +72239,7 @@ var ts; if (option && typeof option.type !== "string") { var customOption = option; // Validate custom option type - if (!customOption.type.has(text)) { + if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } @@ -72306,13 +72539,10 @@ var ts; } } else { - // If no includes were specified, exclude common package folders and the outDir - var specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; var outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"]; if (outDir) { - specs.push(outDir); + excludeSpecs = [outDir]; } - excludeSpecs = specs; } if (fileNames === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; @@ -72573,7 +72803,7 @@ var ts; return value; } else if (typeof option.type !== "string") { - return option.type.get(value); + return option.type.get(typeof value === "string" ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } @@ -72748,23 +72978,13 @@ var ts; }; } function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { - var validSpecs = []; - for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) { - var spec = specs_1[_i]; - if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidMultipleRecursionPatterns.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else { - validSpecs.push(spec); + return specs.filter(function (spec) { + var diag = specToDiagnostic(spec, allowTrailingRecursion); + if (diag !== undefined) { + errors.push(createDiagnostic(diag, spec)); } - } - return validSpecs; + return diag === undefined; + }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { @@ -72782,6 +73002,17 @@ var ts; return ts.createCompilerDiagnostic(message, spec); } } + function specToDiagnostic(spec, allowTrailingRecursion) { + if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + else if (invalidMultipleRecursionPatterns.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; + } + else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + } /** * Gets directories in a set of include patterns that should be watched for changes. */ @@ -72945,7 +73176,7 @@ var ts; (function (ts) { var ScriptSnapshot; (function (ScriptSnapshot) { - var StringScriptSnapshot = (function () { + var StringScriptSnapshot = /** @class */ (function () { function StringScriptSnapshot(text) { this.text = text; } @@ -72969,7 +73200,7 @@ var ts; } ScriptSnapshot.fromString = fromString; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); - var TextChange = (function () { + var TextChange = /** @class */ (function () { function TextChange() { } return TextChange; @@ -73858,7 +74089,7 @@ var ts; // if this is the case - then we should assume that token in question is located in previous child. if (position < child.end && (nodeHasTokens(child) || child.kind === 10 /* JsxText */)) { var start = child.getStart(sourceFile, includeJsDoc); - var lookInPreviousChild = (start >= position) || + var lookInPreviousChild = (start >= position) || // cursor in the leading trivia (child.kind === 10 /* JsxText */ && start === child.end); // whitespace only JsxText if (lookInPreviousChild) { // actual start of the node is past the position - previous token should be at the end of previous child @@ -74357,6 +74588,7 @@ var ts; } ts.symbolToDisplayParts = symbolToDisplayParts; function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) { + flags |= 65536 /* UseAliasDefinedOutsideCurrentScope */; return mapToDisplayParts(function (writer) { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); @@ -74666,11 +74898,11 @@ var ts; templateStack.pop(); } else { - ts.Debug.assert(token === 15 /* TemplateMiddle */, "Should have been a template middle. Was " + token); + ts.Debug.assertEqual(token, 15 /* TemplateMiddle */, "Should have been a template middle."); } } else { - ts.Debug.assert(lastTemplateStackToken === 17 /* OpenBraceToken */, "Should have been an open brace. Was: " + token); + ts.Debug.assertEqual(lastTemplateStackToken, 17 /* OpenBraceToken */, "Should have been an open brace"); templateStack.pop(); } } @@ -76652,7 +76884,7 @@ var ts; if (!typeForObject) return false; // In a binding pattern, get only known properties. Everywhere else we will get all possible properties. - typeMembers = typeChecker.getPropertiesOfType(typeForObject); + typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */); }); existingMembers = objectLikeContainer.elements; } } @@ -76916,11 +77148,11 @@ var ts; return containingNodeKind === 226 /* VariableDeclaration */ || containingNodeKind === 227 /* VariableDeclarationList */ || containingNodeKind === 208 /* VariableStatement */ || - containingNodeKind === 232 /* EnumDeclaration */ || + containingNodeKind === 232 /* EnumDeclaration */ || // enum a { foo, | isFunctionLikeButNotConstructor(containingNodeKind) || - containingNodeKind === 230 /* InterfaceDeclaration */ || - containingNodeKind === 175 /* ArrayBindingPattern */ || - containingNodeKind === 231 /* TypeAliasDeclaration */ || + containingNodeKind === 230 /* InterfaceDeclaration */ || // interface A undefined); => should get use to the declaration in file "./foo" + // + // function bar(onfulfilled: (value: T) => void) { //....} + // interface Test { + // pr/*destination*/op1: number + // } + // bar(({pr/*goto*/op1})=>{}); + if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) && + (node === (node.parent.propertyName || node.parent.name))) { + var type = typeChecker.getTypeAtLocation(node.parent.parent); + if (type) { + var propSymbols = ts.getPropertySymbolsFromType(type, node); + if (propSymbols) { + return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); }); + } + } + } // If the current location we want to find its definition is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. // For example @@ -80614,7 +80877,7 @@ var ts; "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console" ]; - var nodeCoreModules = ts.arrayToMap(JsTyping.nodeCoreModuleList, function (x) { return x; }); + var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList); function loadSafeList(host, safeListPath) { var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); }); return ts.createMapFromTemplate(result.config); @@ -80812,8 +81075,8 @@ var ts; if (!matches) { return; // continue to next named declarations } - for (var _i = 0, declarations_12 = declarations; _i < declarations_12.length; _i++) { - var declaration = declarations_12[_i]; + for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { + var declaration = declarations_11[_i]; // It was a match! If the pattern has dots in it, then also see if the // declaration container matches as well. if (patternMatcher.patternContainsDots) { @@ -82760,8 +83023,8 @@ var ts; var nameToDeclarations = sourceFile.getNamedDeclarations(); var declarations = nameToDeclarations.get(name.text); if (declarations) { - for (var _b = 0, declarations_13 = declarations; _b < declarations_13.length; _b++) { - var declaration = declarations_13[_b]; + for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) { + var declaration = declarations_12[_b]; var symbol = declaration.symbol; if (symbol) { var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration); @@ -82820,7 +83083,9 @@ var ts; } var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 /* TypeArguments */ : 1 /* CallArguments */; var argumentCount = getArgumentCount(list); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var argumentsSpan = getApplicableSpanForArguments(list, sourceFile); return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount }; } @@ -82942,7 +83207,9 @@ var ts; var argumentCount = tagExpression.template.kind === 13 /* NoSubstitutionTemplateLiteral */ ? 1 : tagExpression.template.templateSpans.length + 1; - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } return { kind: 2 /* TaggedTemplateArguments */, invocation: tagExpression, @@ -83060,7 +83327,9 @@ var ts; tags: candidateSignature.getJsDocTags() }; }); - ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex); + if (argumentIndex !== 0) { + ts.Debug.assertLessThan(argumentIndex, argumentCount); + } var selectedItemIndex = candidates.indexOf(resolvedSignature); ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function. return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount }; @@ -83288,12 +83557,12 @@ var ts; hasAddedSymbolInfo = true; } } - else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || + else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration (location.kind === 123 /* ConstructorKeyword */ && location.parent.kind === 152 /* Constructor */)) { // get the signature from the declaration and write it var functionDeclaration_1 = location.parent; // Use function declaration to write the signatures only if the symbol corresponding to this declaration - var locationIsSymbolDeclaration = ts.findDeclaration(symbol, function (declaration) { + var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) { return declaration === (location.kind === 123 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1); }); if (locationIsSymbolDeclaration) { @@ -83676,11 +83945,11 @@ var ts; getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; }, writeFile: function (name, text) { if (ts.fileExtensionIs(name, ".map")) { - ts.Debug.assert(sourceMapText === undefined, "Unexpected multiple source map outputs for the file '" + name + "'"); + ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); sourceMapText = text; } else { - ts.Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: '" + name + "'"); + ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); outputText = text; } }, @@ -84005,7 +84274,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var FormattingContext = (function () { + var FormattingContext = /** @class */ (function () { function FormattingContext(sourceFile, formattingRequestKind, options) { this.sourceFile = sourceFile; this.formattingRequestKind = formattingRequestKind; @@ -84104,7 +84373,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var Rule = (function () { + var Rule = /** @class */ (function () { function Rule(Descriptor, Operation, Flag) { if (Flag === void 0) { Flag = 0 /* None */; } this.Descriptor = Descriptor; @@ -84142,7 +84411,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RuleDescriptor = (function () { + var RuleDescriptor = /** @class */ (function () { function RuleDescriptor(LeftTokenRange, RightTokenRange) { this.LeftTokenRange = LeftTokenRange; this.RightTokenRange = RightTokenRange; @@ -84187,7 +84456,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RuleOperation = (function () { + var RuleOperation = /** @class */ (function () { function RuleOperation(Context, Action) { this.Context = Context; this.Action = Action; @@ -84213,7 +84482,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RuleOperationContext = (function () { + var RuleOperationContext = /** @class */ (function () { function RuleOperationContext() { var funcs = []; for (var _i = 0; _i < arguments.length; _i++) { @@ -84248,7 +84517,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var Rules = (function () { + var Rules = /** @class */ (function () { function Rules() { /// /// Common Rules @@ -84407,6 +84676,7 @@ var ts; // Insert space after opening and before closing nonempty parenthesis this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */)); this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */)); + this.SpaceBetweenOpenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 19 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 2 /* Space */)); this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenParenToken */, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */)); this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */)); this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */)); @@ -84486,7 +84756,7 @@ var ts; this.SpaceAfterComma, this.NoSpaceAfterComma, this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword, this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl, - this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, + this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace, this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail, @@ -84825,7 +85095,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RulesMap = (function () { + var RulesMap = /** @class */ (function () { function RulesMap() { this.map = []; this.mapRowLength = 0; @@ -84895,7 +85165,7 @@ var ts; RulesPosition[RulesPosition["NoContextRulesSpecific"] = MaskBitSize * 4] = "NoContextRulesSpecific"; RulesPosition[RulesPosition["NoContextRulesAny"] = MaskBitSize * 5] = "NoContextRulesAny"; })(RulesPosition = formatting.RulesPosition || (formatting.RulesPosition = {})); - var RulesBucketConstructionState = (function () { + var RulesBucketConstructionState = /** @class */ (function () { function RulesBucketConstructionState() { //// The Rules list contains all the inserted rules into a rulebucket in the following order: //// 1- Ignore rules with specific token combination @@ -84936,7 +85206,7 @@ var ts; return RulesBucketConstructionState; }()); formatting.RulesBucketConstructionState = RulesBucketConstructionState; - var RulesBucket = (function () { + var RulesBucket = /** @class */ (function () { function RulesBucket() { this.rules = []; } @@ -84985,7 +85255,7 @@ var ts; for (var token = 0 /* FirstToken */; token <= 142 /* LastToken */; token++) { allTokens.push(token); } - var TokenValuesAccess = (function () { + var TokenValuesAccess = /** @class */ (function () { function TokenValuesAccess(tokens) { if (tokens === void 0) { tokens = []; } this.tokens = tokens; @@ -84999,7 +85269,7 @@ var ts; TokenValuesAccess.prototype.isSpecific = function () { return true; }; return TokenValuesAccess; }()); - var TokenSingleValueAccess = (function () { + var TokenSingleValueAccess = /** @class */ (function () { function TokenSingleValueAccess(token) { this.token = token; } @@ -85012,7 +85282,7 @@ var ts; TokenSingleValueAccess.prototype.isSpecific = function () { return true; }; return TokenSingleValueAccess; }()); - var TokenAllAccess = (function () { + var TokenAllAccess = /** @class */ (function () { function TokenAllAccess() { } TokenAllAccess.prototype.GetTokens = function () { @@ -85027,7 +85297,7 @@ var ts; TokenAllAccess.prototype.isSpecific = function () { return false; }; return TokenAllAccess; }()); - var TokenAllExceptAccess = (function () { + var TokenAllExceptAccess = /** @class */ (function () { function TokenAllExceptAccess(except) { this.except = except; } @@ -85119,7 +85389,7 @@ var ts; (function (ts) { var formatting; (function (formatting) { - var RulesProvider = (function () { + var RulesProvider = /** @class */ (function () { function RulesProvider() { this.globalRules = new formatting.Rules(); var activeRules = this.globalRules.HighPriorityCommonRules.slice(0).concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules); @@ -86633,6 +86903,12 @@ var ts; } return false; } + var ChangeKind; + (function (ChangeKind) { + ChangeKind[ChangeKind["Remove"] = 0] = "Remove"; + ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode"; + ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes"; + })(ChangeKind || (ChangeKind = {})); function getSeparatorCharacter(separator) { return ts.tokenToString(separator.kind); } @@ -86666,13 +86942,11 @@ var ts; } textChanges.getAdjustedStartPosition = getAdjustedStartPosition; function getAdjustedEndPosition(sourceFile, node, options) { - if (options.useNonAdjustedEndPosition) { + if (options.useNonAdjustedEndPosition || ts.isExpression(node)) { return node.getEnd(); } var end = node.getEnd(); var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true); - // check if last character before newPos is linebreak - // if yes - considered all skipped trivia to be trailing trivia of the node return newEnd !== end && ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)) ? newEnd : end; @@ -86691,7 +86965,10 @@ var ts; } return s; } - var ChangeTracker = (function () { + function getNewlineKind(context) { + return context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */; + } + var ChangeTracker = /** @class */ (function () { function ChangeTracker(newLine, rulesProvider, validator) { this.newLine = newLine; this.rulesProvider = rulesProvider; @@ -86700,24 +86977,24 @@ var ts; this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine }); } ChangeTracker.fromCodeFixContext = function (context) { - return new ChangeTracker(context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */, context.rulesProvider); + return new ChangeTracker(getNewlineKind(context), context.rulesProvider); + }; + ChangeTracker.prototype.deleteRange = function (sourceFile, range) { + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range }); + return this; }; ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, node, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); - return this; - }; - ChangeTracker.prototype.deleteRange = function (sourceFile, range) { - this.changes.push({ sourceFile: sourceFile, range: range }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, range: { pos: startPosition, end: endPosition } }); + this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) { @@ -86756,33 +87033,68 @@ var ts; }; ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, range: range, options: options, node: newNode }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode }); return this; }; ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); }; ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); + return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); + }; + ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, + sourceFile: sourceFile, + options: options, + node: newNode, + range: { pos: startPosition, end: endPosition } + }); + return this; + }; + ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) { + this.changes.push({ + kind: ChangeKind.ReplaceWithMultipleNodes, + sourceFile: sourceFile, + options: options, + nodes: newNodes, + range: { pos: startPosition, end: endPosition } + }); return this; }; + ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; + ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) { + return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options); + }; + ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) { + var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); + var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); + return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); + }; ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) { if (options === void 0) { options = {}; } - this.changes.push({ sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); + this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); return this; }; ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: startPosition } }); - return this; + return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options); }; ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) { if (options === void 0) { options = {}; } @@ -86794,6 +87106,7 @@ var ts; // if not - insert semicolon to preserve the code from changing the meaning due to ASI if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: {}, range: { pos: after.end, end: after.end }, @@ -86802,8 +87115,7 @@ var ts; } } var endPosition = getAdjustedEndPosition(sourceFile, after, options); - this.changes.push({ sourceFile: sourceFile, options: options, useIndentationFromFile: true, node: newNode, range: { pos: endPosition, end: endPosition } }); - return this; + return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options); }; /** * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range, @@ -86869,10 +87181,10 @@ var ts; startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile); } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) }, node: newNode, - useIndentationFromFile: true, options: { prefix: prefix, // write separator and leading trivia of the next element as suffix @@ -86911,6 +87223,7 @@ var ts; if (multilineList) { // insert separator immediately following the 'after' node to preserve comments in trailing trivia this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: ts.createToken(separator), @@ -86924,6 +87237,7 @@ var ts; insertPos--; } this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: insertPos, end: insertPos }, node: newNode, @@ -86932,6 +87246,7 @@ var ts; } else { this.changes.push({ + kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: newNode, @@ -86973,33 +87288,45 @@ var ts; return ts.createTextSpanFromBounds(change.range.pos, change.range.end); }; ChangeTracker.prototype.computeNewText = function (change, sourceFile) { - if (!change.node) { + var _this = this; + if (change.kind === ChangeKind.Remove) { // deletion case return ""; } var options = change.options || {}; - var nonFormattedText = getNonformattedText(change.node, sourceFile, this.newLine); + var text; + var pos = change.range.pos; + var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; + if (change.kind === ChangeKind.ReplaceWithMultipleNodes) { + var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); }); + text = parts.join(change.options.nodeSeparator); + } + else { + ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode"); + text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options); + } + // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line + text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, ""); + return (options.prefix || "") + text + (options.suffix || ""); + }; + ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) { + var nonformattedText = getNonformattedText(node, sourceFile, this.newLine); if (this.validator) { - this.validator(nonFormattedText); + this.validator(nonformattedText); } var formatOptions = this.rulesProvider.getFormatOptions(); - var pos = change.range.pos; var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; - var initialIndentation = change.options.indentation !== undefined - ? change.options.indentation - : change.useIndentationFromFile - ? ts.formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix === this.newLineCharacter)) + var initialIndentation = options.indentation !== undefined + ? options.indentation + : (options.useIndentationFromFile !== false) + ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) : 0; - var delta = change.options.delta !== undefined - ? change.options.delta - : ts.formatting.SmartIndenter.shouldIndentChildNode(change.node) - ? formatOptions.indentSize + var delta = options.delta !== undefined + ? options.delta + : ts.formatting.SmartIndenter.shouldIndentChildNode(node) + ? (formatOptions.indentSize || 0) : 0; - var text = applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, this.rulesProvider); - // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line - // however keep indentation if it is was forced - text = posStartsLine || change.options.indentation !== undefined ? text : text.replace(/^\s+/, ""); - return (options.prefix || "") + text + (options.suffix || ""); + return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); }; ChangeTracker.normalize = function (changes) { // order changes by start position @@ -87065,7 +87392,7 @@ var ts; nodeArray.end = getEnd(nodes); return nodeArray; } - var Writer = (function () { + var Writer = /** @class */ (function () { function Writer(newLine) { var _this = this; this.lastNonTriviaPosition = 0; @@ -87948,7 +88275,7 @@ var ts; ModuleSpecifierComparison[ModuleSpecifierComparison["Equal"] = 1] = "Equal"; ModuleSpecifierComparison[ModuleSpecifierComparison["Worse"] = 2] = "Worse"; })(ModuleSpecifierComparison || (ModuleSpecifierComparison = {})); - var ImportCodeActionMap = (function () { + var ImportCodeActionMap = /** @class */ (function () { function ImportCodeActionMap() { this.symbolIdToActionMap = []; } @@ -88061,7 +88388,7 @@ var ts; } else if (ts.isJsxOpeningLikeElement(token.parent) && token.parent.tagName === token) { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. - symbol = checker.getAliasedSymbol(checker.resolveNameAtLocation(token, checker.getJsxNamespace(), 107455 /* Value */)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), token.parent.tagName, 107455 /* Value */)); symbolName = symbol.name; } else { @@ -88086,7 +88413,7 @@ var ts; if (localSymbol && localSymbol.escapedName === name && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) { // check if this symbol is already used var symbolId = getUniqueSymbolId(localSymbol); - symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name, /*isDefault*/ true)); + symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name, /*isNamespaceImport*/ true)); } } // "default" is a keyword and not a legal identifier for the import, so we don't expect it here @@ -88162,8 +88489,8 @@ var ts; var namespaceImportDeclaration; var namedImportDeclaration; var existingModuleSpecifier; - for (var _i = 0, declarations_14 = declarations; _i < declarations_14.length; _i++) { - var declaration = declarations_14[_i]; + for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) { + var declaration = declarations_13[_i]; if (declaration.kind === 238 /* ImportDeclaration */) { var namedBindings = declaration.importClause && declaration.importClause.namedBindings; if (namedBindings && namedBindings.kind === 240 /* NamespaceImport */) { @@ -88273,9 +88600,11 @@ var ts; : isNamespaceImport ? ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(ts.createIdentifier(symbolName))) : ts.createImportClause(/*name*/ undefined, ts.createNamedImports([ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(symbolName))])); - var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, ts.createLiteral(moduleSpecifierWithoutQuotes)); + var moduleSpecifierLiteral = ts.createLiteral(moduleSpecifierWithoutQuotes); + moduleSpecifierLiteral.singleQuote = getSingleQuoteStyleFromExistingImports(); + var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, moduleSpecifierLiteral); if (!lastImportDeclaration) { - changeTracker.insertNodeAt(sourceFile, sourceFile.getStart(), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); + changeTracker.insertNodeAt(sourceFile, getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + context.newLineCharacter + context.newLineCharacter }); } else { changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: context.newLineCharacter }); @@ -88284,6 +88613,46 @@ var ts; // between the only import statement and user code. Otherwise just insert the statement because chances // are there are already a new line seperating code and import statements. return createCodeAction(ts.Diagnostics.Import_0_from_1, [symbolName, "\"" + moduleSpecifierWithoutQuotes + "\""], changeTracker.getChanges(), "NewImport", moduleSpecifierWithoutQuotes); + function getSourceFileImportLocation(node) { + // For a source file, it is possible there are detached comments we should not skip + var text = node.text; + var ranges = ts.getLeadingCommentRanges(text, 0); + if (!ranges) + return 0; + var position = 0; + // However we should still skip a pinned comment at the top + if (ranges.length && ranges[0].kind === 3 /* MultiLineCommentTrivia */ && ts.isPinnedComment(text, ranges[0])) { + position = ranges[0].end + 1; + ranges = ranges.slice(1); + } + // As well as any triple slash references + for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) { + var range = ranges_1[_i]; + if (range.kind === 2 /* SingleLineCommentTrivia */ && ts.isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { + position = range.end + 1; + continue; + } + break; + } + return position; + } + function getSingleQuoteStyleFromExistingImports() { + var firstModuleSpecifier = ts.forEach(sourceFile.statements, function (node) { + if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) { + if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { + return node.moduleSpecifier; + } + } + else if (ts.isImportEqualsDeclaration(node)) { + if (ts.isExternalModuleReference(node.moduleReference) && ts.isStringLiteral(node.moduleReference.expression)) { + return node.moduleReference.expression; + } + } + }); + if (firstModuleSpecifier) { + return sourceFile.text.charCodeAt(firstModuleSpecifier.getStart()) === 39 /* singleQuote */; + } + } function getModuleSpecifierForNewImport() { var fileName = sourceFile.fileName; var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName; @@ -88415,8 +88784,8 @@ var ts; } function getNodeModulePathParts(fullPath) { // If fullPath can't be valid module file within node_modules, returns undefined. - // Example of expected pattern: /base/path/node_modules/[otherpackage/node_modules/]package/[subdirectory/]file.js - // Returns indices: ^ ^ ^ ^ + // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js + // Returns indices: ^ ^ ^ ^ var topLevelNodeModulesIndex = 0; var topLevelPackageNameIndex = 0; var packageRootIndex = 0; @@ -88425,7 +88794,8 @@ var ts; (function (States) { States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; States[States["NodeModules"] = 1] = "NodeModules"; - States[States["PackageContent"] = 2] = "PackageContent"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; })(States || (States = {})); var partStart = 0; var partEnd = 0; @@ -88442,15 +88812,21 @@ var ts; } break; case 1 /* NodeModules */: - packageRootIndex = partEnd; - state = 2 /* PackageContent */; + case 2 /* Scope */: + if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { + state = 2 /* Scope */; + } + else { + packageRootIndex = partEnd; + state = 3 /* PackageContent */; + } break; - case 2 /* PackageContent */: + case 3 /* PackageContent */: if (fullPath.indexOf("/node_modules/", partStart) === partStart) { state = 1 /* NodeModules */; } else { - state = 2 /* PackageContent */; + state = 3 /* PackageContent */; } break; } @@ -88807,231 +89183,1211 @@ var ts; (function (ts) { var refactor; (function (refactor) { - var actionName = "convert"; - var convertFunctionToES6Class = { - name: "Convert to ES2015 class", - description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, - getEditsForAction: getEditsForAction, - getAvailableActions: getAvailableActions - }; - refactor.registerRefactor(convertFunctionToES6Class); - function getAvailableActions(context) { - if (!ts.isInJavaScriptFile(context.file)) { - return undefined; - } - var start = context.startPosition; - var node = ts.getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); - var checker = context.program.getTypeChecker(); - var symbol = checker.getSymbolAtLocation(node); - if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { - symbol = symbol.valueDeclaration.initializer.symbol; + var convertFunctionToES6Class; + (function (convertFunctionToES6Class_1) { + var actionName = "convert"; + var convertFunctionToES6Class = { + name: "Convert to ES2015 class", + description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, + getEditsForAction: getEditsForAction, + getAvailableActions: getAvailableActions + }; + refactor.registerRefactor(convertFunctionToES6Class); + function getAvailableActions(context) { + if (!ts.isInJavaScriptFile(context.file)) { + return undefined; + } + var start = context.startPosition; + var node = ts.getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); + var checker = context.program.getTypeChecker(); + var symbol = checker.getSymbolAtLocation(node); + if (symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = symbol.valueDeclaration.initializer.symbol; + } + if (symbol && (symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) { + return [ + { + name: convertFunctionToES6Class.name, + description: convertFunctionToES6Class.description, + actions: [ + { + description: convertFunctionToES6Class.description, + name: actionName + } + ] + } + ]; + } } - if (symbol && (symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) { - return [ - { - name: convertFunctionToES6Class.name, - description: convertFunctionToES6Class.description, - actions: [ - { - description: convertFunctionToES6Class.description, - name: actionName + function getEditsForAction(context, action) { + // Somehow wrong action got invoked? + if (actionName !== action) { + return undefined; + } + var start = context.startPosition; + var sourceFile = context.file; + var checker = context.program.getTypeChecker(); + var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + var ctorSymbol = checker.getSymbolAtLocation(token); + var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; + var deletedNodes = []; + var deletes = []; + if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) { + return undefined; + } + var ctorDeclaration = ctorSymbol.valueDeclaration; + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + var precedingNode; + var newClassDeclaration; + switch (ctorDeclaration.kind) { + case 228 /* FunctionDeclaration */: + precedingNode = ctorDeclaration; + deleteNode(ctorDeclaration); + newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); + break; + case 226 /* VariableDeclaration */: + precedingNode = ctorDeclaration.parent.parent; + if (ctorDeclaration.parent.declarations.length === 1) { + deleteNode(precedingNode); + } + else { + deleteNode(ctorDeclaration, /*inList*/ true); + } + newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); + break; + } + if (!newClassDeclaration) { + return undefined; + } + // Because the preceding node could be touched, we need to insert nodes before delete nodes. + changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); + for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { + var deleteCallback = deletes_1[_i]; + deleteCallback(); + } + return { + edits: changeTracker.getChanges() + }; + function deleteNode(node, inList) { + if (inList === void 0) { inList = false; } + if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { + // Parent node has already been deleted; do nothing + return; + } + deletedNodes.push(node); + if (inList) { + deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + } + else { + deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + } + } + function createClassElementsFromSymbol(symbol) { + var memberElements = []; + // all instance members are stored in the "member" array of symbol + if (symbol.members) { + symbol.members.forEach(function (member) { + var memberElement = createClassElement(member, /*modifiers*/ undefined); + if (memberElement) { + memberElements.push(memberElement); } - ] + }); } - ]; - } - } - function getEditsForAction(context, action) { - // Somehow wrong action got invoked? - if (actionName !== action) { - return undefined; + // all static members are stored in the "exports" array of symbol + if (symbol.exports) { + symbol.exports.forEach(function (member) { + var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]); + if (memberElement) { + memberElements.push(memberElement); + } + }); + } + return memberElements; + function shouldConvertDeclaration(_target, source) { + // Right now the only thing we can convert are function expressions - other values shouldn't get + // transformed. We can update this once ES public class properties are available. + return ts.isFunctionLike(source); + } + function createClassElement(symbol, modifiers) { + // both properties and methods are bound as property symbols + if (!(symbol.flags & 4 /* Property */)) { + return; + } + var memberDeclaration = symbol.valueDeclaration; + var assignmentBinaryExpression = memberDeclaration.parent; + if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { + return; + } + // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end + var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 /* ExpressionStatement */ + ? assignmentBinaryExpression.parent : assignmentBinaryExpression; + deleteNode(nodeToDelete); + if (!assignmentBinaryExpression.right) { + return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, + /*type*/ undefined, /*initializer*/ undefined); + } + switch (assignmentBinaryExpression.right.kind) { + case 186 /* FunctionExpression */: { + var functionExpression = assignmentBinaryExpression.right; + var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, + /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); + copyComments(assignmentBinaryExpression, method); + return method; + } + case 187 /* ArrowFunction */: { + var arrowFunction = assignmentBinaryExpression.right; + var arrowFunctionBody = arrowFunction.body; + var bodyBlock = void 0; + // case 1: () => { return [1,2,3] } + if (arrowFunctionBody.kind === 207 /* Block */) { + bodyBlock = arrowFunctionBody; + } + else { + var expression = arrowFunctionBody; + bodyBlock = ts.createBlock([ts.createReturn(expression)]); + } + var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, + /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); + copyComments(assignmentBinaryExpression, method); + return method; + } + default: { + // Don't try to declare members in JavaScript files + if (ts.isSourceFileJavaScript(sourceFile)) { + return; + } + var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, + /*type*/ undefined, assignmentBinaryExpression.right); + copyComments(assignmentBinaryExpression.parent, prop); + return prop; + } + } + } + } + function copyComments(sourceNode, targetNode) { + ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { + if (kind === 3 /* MultiLineCommentTrivia */) { + // Remove leading /* + pos += 2; + // Remove trailing */ + end -= 2; + } + else { + // Remove leading // + pos += 2; + } + ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); + }); + } + function createClassFromVariableDeclaration(node) { + var initializer = node.initializer; + if (!initializer || initializer.kind !== 186 /* FunctionExpression */) { + return undefined; + } + if (node.name.kind !== 71 /* Identifier */) { + return undefined; + } + var memberElements = createClassElementsFromSymbol(initializer.symbol); + if (initializer.body) { + memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); + } + var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, + /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); + // Don't call copyComments here because we'll already leave them in place + return cls; + } + function createClassFromFunctionDeclaration(node) { + var memberElements = createClassElementsFromSymbol(ctorSymbol); + if (node.body) { + memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); + } + var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, + /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); + // Don't call copyComments here because we'll already leave them in place + return cls; + } } - var start = context.startPosition; - var sourceFile = context.file; - var checker = context.program.getTypeChecker(); - var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); - var ctorSymbol = checker.getSymbolAtLocation(token); - var newLine = context.rulesProvider.getFormatOptions().newLineCharacter; - var deletedNodes = []; - var deletes = []; - if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) { - return undefined; + })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {})); + })(refactor = ts.refactor || (ts.refactor = {})); +})(ts || (ts = {})); +/// +/// +/* @internal */ +var ts; +(function (ts) { + var refactor; + (function (refactor) { + var extractMethod; + (function (extractMethod_1) { + var extractMethod = { + name: "Extract Method", + description: ts.Diagnostics.Extract_function.message, + getAvailableActions: getAvailableActions, + getEditsForAction: getEditsForAction, + }; + refactor.registerRefactor(extractMethod); + /** Compute the associated code actions */ + function getAvailableActions(context) { + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: context.endPosition - context.startPosition }); + var targetRange = rangeToExtract.targetRange; + if (targetRange === undefined) { + return undefined; + } + var extractions = getPossibleExtractions(targetRange, context); + if (extractions === undefined) { + // No extractions possible + return undefined; + } + var actions = []; + var usedNames = ts.createMap(); + var i = 0; + for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { + var extr = extractions_1[_i]; + // Skip these since we don't have a way to report errors yet + if (extr.errors && extr.errors.length) { + continue; + } + // Don't issue refactorings with duplicated names. + // Scopes come back in "innermost first" order, so extractions will + // preferentially go into nearer scopes + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + if (!usedNames.has(description)) { + usedNames.set(description, true); + actions.push({ + description: description, + name: "scope_" + i + }); + } + // *do* increment i anyway because we'll look for the i-th scope + // later when actually doing the refactoring if the user requests it + i++; + } + if (actions.length === 0) { + return undefined; + } + return [{ + name: extractMethod.name, + description: extractMethod.description, + inlineable: true, + actions: actions + }]; } - var ctorDeclaration = ctorSymbol.valueDeclaration; - var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); - var precedingNode; - var newClassDeclaration; - switch (ctorDeclaration.kind) { - case 228 /* FunctionDeclaration */: - precedingNode = ctorDeclaration; - deleteNode(ctorDeclaration); - newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); - break; - case 226 /* VariableDeclaration */: - precedingNode = ctorDeclaration.parent.parent; - if (ctorDeclaration.parent.declarations.length === 1) { - deleteNode(precedingNode); + function getEditsForAction(context, actionName) { + var length = context.endPosition === undefined ? 0 : context.endPosition - context.startPosition; + var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: length }); + var targetRange = rangeToExtract.targetRange; + var parsedIndexMatch = /^scope_(\d+)$/.exec(actionName); + ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); + var index = +parsedIndexMatch[1]; + ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); + var extractions = getPossibleExtractions(targetRange, context, index); + // Scope is no longer valid from when the user issued the refactor (??) + ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); + return ({ edits: extractions[0].changes }); + } + // Move these into diagnostic messages if they become user-facing + var Messages; + (function (Messages) { + function createMessage(message) { + return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message }; + } + Messages.CannotExtractFunction = createMessage("Cannot extract function."); + Messages.StatementOrExpressionExpected = createMessage("Statement or expression expected."); + Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements."); + Messages.CannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement."); + Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); + Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); + Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); + Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); + Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); + Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); + Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); + Messages.CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); + })(Messages || (Messages = {})); + var RangeFacts; + (function (RangeFacts) { + RangeFacts[RangeFacts["None"] = 0] = "None"; + RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn"; + RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator"; + RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; + RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; + /** + * The range is in a function which needs the 'static' modifier in a class + */ + RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; + })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + /** + * getRangeToExtract takes a span inside a text file and returns either an expression or an array + * of statements representing the minimum set of nodes needed to extract the entire span. This + * process may fail, in which case a set of errors is returned instead (these are currently + * not shown to the user, but can be used by us diagnostically) + */ + function getRangeToExtract(sourceFile, span) { + var length = span.length || 0; + // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. + // This may fail (e.g. you select two statements in the root of a source file) + var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span); + // Do the same for the ending position + var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span); + var declarations = []; + // We'll modify these flags as we walk the tree to collect data + // about what things need to be done as part of the extraction. + var rangeFacts = RangeFacts.None; + if (!start || !end) { + // cannot find either start or end node + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractFunction)] }; + } + if (start.parent !== end.parent) { + // handle cases like 1 + [2 + 3] + 4 + // user selection is marked with []. + // in this case 2 + 3 does not belong to the same tree node + // instead the shape of the tree looks like this: + // + + // / \ + // + 4 + // / \ + // + 3 + // / \ + // 1 2 + // in this case there is no such one node that covers ends of selection and is located inside the selection + // to handle this we check if both start and end of the selection belong to some binary operation + // and start node is parented by the parent of the end node + // if this is the case - expand the selection to the entire parent of end node (in this case it will be [1 + 2 + 3] + 4) + var startParent = ts.skipParentheses(start.parent); + var endParent = ts.skipParentheses(end.parent); + if (ts.isBinaryExpression(startParent) && ts.isBinaryExpression(endParent) && ts.isNodeDescendantOf(startParent, endParent)) { + start = end = endParent; } else { - deleteNode(ctorDeclaration, /*inList*/ true); + // start and end nodes belong to different subtrees + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); } - newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); - break; + } + if (start !== end) { + // start and end should be statements and parent should be either block or a source file + if (!isBlockLike(start.parent)) { + return createErrorResult(sourceFile, span.start, length, Messages.CannotExtractFunction); + } + var statements = []; + for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) { + var statement = _a[_i]; + if (statement === start || statements.length) { + var errors = checkNode(statement); + if (errors) { + return { errors: errors }; + } + statements.push(statement); + } + if (statement === end) { + break; + } + } + return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } }; + } + else { + // We have a single node (start) + var errors = checkRootNode(start) || checkNode(start); + if (errors) { + return { errors: errors }; + } + // If our selection is the expression in an ExpressionStatement, expand + // the selection to include the enclosing Statement (this stops us + // from trying to care about the return value of the extracted function + // and eliminates double semicolon insertion in certain scenarios) + var range = ts.isStatement(start) + ? [start] + : start.parent && start.parent.kind === 210 /* ExpressionStatement */ + ? [start.parent] + : start; + return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + } + function createErrorResult(sourceFile, start, length, message) { + return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; + } + function checkRootNode(node) { + if (ts.isIdentifier(node)) { + return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; + } + return undefined; + } + function checkForStaticContext(nodeToCheck, containingClass) { + var current = nodeToCheck; + while (current !== containingClass) { + if (current.kind === 149 /* PropertyDeclaration */) { + if (ts.hasModifier(current, 32 /* Static */)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 146 /* Parameter */) { + var ctorOrMethod = ts.getContainingFunction(current); + if (ctorOrMethod.kind === 152 /* Constructor */) { + rangeFacts |= RangeFacts.InStaticRegion; + } + break; + } + else if (current.kind === 151 /* MethodDeclaration */) { + if (ts.hasModifier(current, 32 /* Static */)) { + rangeFacts |= RangeFacts.InStaticRegion; + } + } + current = current.parent; + } + } + // Verifies whether we can actually extract this node or not. + function checkNode(nodeToCheck) { + var PermittedJumps; + (function (PermittedJumps) { + PermittedJumps[PermittedJumps["None"] = 0] = "None"; + PermittedJumps[PermittedJumps["Break"] = 1] = "Break"; + PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue"; + PermittedJumps[PermittedJumps["Return"] = 4] = "Return"; + })(PermittedJumps || (PermittedJumps = {})); + if (!ts.isStatement(nodeToCheck) && !(ts.isExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)]; + } + if (ts.isInAmbientContext(nodeToCheck)) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)]; + } + // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default) + var containingClass = ts.getContainingClass(nodeToCheck); + if (containingClass) { + checkForStaticContext(nodeToCheck, containingClass); + } + var errors; + var permittedJumps = 4 /* Return */; + var seenLabels; + visit(nodeToCheck); + return errors; + function visit(node) { + if (errors) { + // already found an error - can stop now + return true; + } + if (ts.isDeclaration(node)) { + var declaringNode = (node.kind === 226 /* VariableDeclaration */) ? node.parent.parent : node; + if (ts.hasModifier(declaringNode, 1 /* Export */)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + return true; + } + declarations.push(node.symbol); + } + // Some things can't be extracted in certain situations + switch (node.kind) { + case 238 /* ImportDeclaration */: + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + case 97 /* SuperKeyword */: + // For a super *constructor call*, we have to be extracting the entire class, + // but a super *method call* simply implies a 'this' reference + if (node.parent.kind === 181 /* CallExpression */) { + // Super constructor call + var containingClass_1 = ts.getContainingClass(node); + if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractFunction)); + return true; + } + } + else { + rangeFacts |= RangeFacts.UsesThis; + } + break; + } + if (!node || ts.isFunctionLike(node) || ts.isClassLike(node)) { + switch (node.kind) { + case 228 /* FunctionDeclaration */: + case 229 /* ClassDeclaration */: + if (node.parent.kind === 265 /* SourceFile */ && node.parent.externalModuleIndicator === undefined) { + // You cannot extract global declarations + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope)); + } + break; + } + // do not dive into functions or classes + return false; + } + var savedPermittedJumps = permittedJumps; + if (node.parent) { + switch (node.parent.kind) { + case 211 /* IfStatement */: + if (node.parent.thenStatement === node || node.parent.elseStatement === node) { + // forbid all jumps inside thenStatement or elseStatement + permittedJumps = 0 /* None */; + } + break; + case 224 /* TryStatement */: + if (node.parent.tryBlock === node) { + // forbid all jumps inside try blocks + permittedJumps = 0 /* None */; + } + else if (node.parent.finallyBlock === node) { + // allow unconditional returns from finally blocks + permittedJumps = 4 /* Return */; + } + break; + case 260 /* CatchClause */: + if (node.parent.block === node) { + // forbid all jumps inside the block of catch clause + permittedJumps = 0 /* None */; + } + break; + case 257 /* CaseClause */: + if (node.expression !== node) { + // allow unlabeled break inside case clauses + permittedJumps |= 1 /* Break */; + } + break; + default: + if (ts.isIterationStatement(node.parent, /*lookInLabeledStatements*/ false)) { + if (node.parent.statement === node) { + // allow unlabeled break/continue inside loops + permittedJumps |= 1 /* Break */ | 2 /* Continue */; + } + } + break; + } + } + switch (node.kind) { + case 169 /* ThisType */: + case 99 /* ThisKeyword */: + rangeFacts |= RangeFacts.UsesThis; + break; + case 222 /* LabeledStatement */: + { + var label = node.label; + (seenLabels || (seenLabels = [])).push(label.escapedText); + ts.forEachChild(node, visit); + seenLabels.pop(); + break; + } + case 218 /* BreakStatement */: + case 217 /* ContinueStatement */: + { + var label = node.label; + if (label) { + if (!ts.contains(seenLabels, label.escapedText)) { + // attempts to jump to label that is not in range to be extracted + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); + } + } + else { + if (!(permittedJumps & (218 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) { + // attempt to break or continue in a forbidden context + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements)); + } + } + break; + } + case 191 /* AwaitExpression */: + rangeFacts |= RangeFacts.IsAsyncFunction; + break; + case 197 /* YieldExpression */: + rangeFacts |= RangeFacts.IsGenerator; + break; + case 219 /* ReturnStatement */: + if (permittedJumps & 4 /* Return */) { + rangeFacts |= RangeFacts.HasReturn; + } + else { + (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement)); + } + break; + default: + ts.forEachChild(node, visit); + break; + } + permittedJumps = savedPermittedJumps; + } + } } - if (!newClassDeclaration) { - return undefined; + extractMethod_1.getRangeToExtract = getRangeToExtract; + function isValidExtractionTarget(node) { + // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method + return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); + } + /** + * Computes possible places we could extract the function into. For example, + * you may be able to extract into a class method *or* local closure *or* namespace function, + * depending on what's in the extracted body. + */ + function collectEnclosingScopes(range) { + var current = isReadonlyArray(range.range) ? ts.firstOrUndefined(range.range) : range.range; + if (range.facts & RangeFacts.UsesThis) { + // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class + var containingClass = ts.getContainingClass(current); + if (containingClass) { + return [containingClass]; + } + } + var start = current; + var scopes = undefined; + while (current) { + // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of. + // Walk up to the closest parent of a place where we can logically put a sibling: + // * Function declaration + // * Class declaration or expression + // * Module/namespace or source file + if (current !== start && isValidExtractionTarget(current)) { + (scopes = scopes || []).push(current); + } + // A function parameter's initializer is actually in the outer scope, not the function declaration + if (current && current.parent && current.parent.kind === 146 /* Parameter */) { + // Skip all the way to the outer scope of the function that declared this parameter + current = ts.findAncestor(current, function (parent) { return ts.isFunctionLike(parent); }).parent; + } + else { + current = current.parent; + } + } + return scopes; } - // Because the preceding node could be touched, we need to insert nodes before delete nodes. - changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); - for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { - var deleteCallback = deletes_1[_i]; - deleteCallback(); + extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; + /** + * Given a piece of text to extract ('targetRange'), computes a list of possible extractions. + * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes + * or an error explaining why we can't extract into that scope. + */ + function getPossibleExtractions(targetRange, context, requestedChangesIndex) { + if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + var sourceFile = context.file; + if (targetRange === undefined) { + return undefined; + } + var scopes = collectEnclosingScopes(targetRange); + if (scopes === undefined) { + return undefined; + } + var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); + var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; + context.cancellationToken.throwIfCancellationRequested(); + if (requestedChangesIndex !== undefined) { + if (errorsPerScope[requestedChangesIndex].length) { + return undefined; + } + return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; + } + else { + return scopes.map(function (scope, i) { + var errors = errorsPerScope[i]; + if (errors.length) { + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + errors: errors + }; + } + return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; + }); + } } - return { - edits: changeTracker.getChanges() - }; - function deleteNode(node, inList) { - if (inList === void 0) { inList = false; } - if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { - // Parent node has already been deleted; do nothing - return; + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getDescriptionForScope(scope) { + if (ts.isFunctionLike(scope)) { + switch (scope.kind) { + case 152 /* Constructor */: + return "constructor"; + case 186 /* FunctionExpression */: + return scope.name + ? "function expression " + scope.name.getText() + : "anonymous function expression"; + case 228 /* FunctionDeclaration */: + return "function " + scope.name.getText(); + case 187 /* ArrowFunction */: + return "arrow function"; + case 151 /* MethodDeclaration */: + return "method " + scope.name.getText(); + case 153 /* GetAccessor */: + return "get " + scope.name.getText(); + case 154 /* SetAccessor */: + return "set " + scope.name.getText(); + } + } + else if (isModuleBlock(scope)) { + return "namespace " + scope.parent.name.getText(); + } + else if (ts.isClassLike(scope)) { + return scope.kind === 229 /* ClassDeclaration */ + ? "class " + scope.name.text + : scope.name.text + ? "class expression " + scope.name.text + : "anonymous class expression"; } - deletedNodes.push(node); - if (inList) { - deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); + else if (ts.isSourceFile(scope)) { + return "file '" + scope.fileName + "'"; } else { - deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); + return "unknown"; } } - function createClassElementsFromSymbol(symbol) { - var memberElements = []; - // all instance members are stored in the "member" array of symbol - if (symbol.members) { - symbol.members.forEach(function (member) { - var memberElement = createClassElement(member, /*modifiers*/ undefined); - if (memberElement) { - memberElements.push(memberElement); + function getUniqueName(isNameOkay) { + var functionNameText = "newFunction"; + if (isNameOkay(functionNameText)) { + return functionNameText; + } + var i = 1; + while (!isNameOkay(functionNameText = "newFunction_" + i)) { + i++; + } + return functionNameText; + } + function extractFunctionInScope(node, scope, _a, range, context) { + var usagesInScope = _a.usages, substitutions = _a.substitutions; + var checker = context.program.getTypeChecker(); + // Make a unique name for the extracted function + var file = scope.getSourceFile(); + var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var isJS = ts.isInJavaScriptFile(scope); + var functionName = ts.createIdentifier(functionNameText); + var functionReference = ts.createIdentifier(functionNameText); + var returnType = undefined; + var parameters = []; + var callArguments = []; + var writes; + usagesInScope.forEach(function (usage, name) { + var typeNode = undefined; + if (!isJS) { + var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); + // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" + type = checker.getBaseTypeOfLiteralType(type); + typeNode = checker.typeToTypeNode(type, node, ts.NodeBuilderFlags.NoTruncation); + } + var paramDecl = ts.createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + /*name*/ name, + /*questionToken*/ undefined, typeNode); + parameters.push(paramDecl); + if (usage.usage === 2 /* Write */) { + (writes || (writes = [])).push(usage); + } + callArguments.push(ts.createIdentifier(name)); + }); + // Provide explicit return types for contexutally-typed functions + // to avoid problems when there are literal types present + if (ts.isExpression(node) && !isJS) { + var contextualType = checker.getContextualType(node); + returnType = checker.typeToTypeNode(contextualType); + } + var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var newFunction; + if (ts.isClassLike(scope)) { + // always create private method in TypeScript files + var modifiers = isJS ? [] : [ts.createToken(112 /* PrivateKeyword */)]; + if (range.facts & RangeFacts.InStaticRegion) { + modifiers.push(ts.createToken(115 /* StaticKeyword */)); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + modifiers.push(ts.createToken(120 /* AsyncKeyword */)); + } + newFunction = ts.createMethod( + /*decorators*/ undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, + /*questionToken*/ undefined, + /*typeParameters*/ [], parameters, returnType, body); + } + else { + newFunction = ts.createFunctionDeclaration( + /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, + /*typeParameters*/ [], parameters, returnType, body); + } + var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); + // insert function at the end of the scope + changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); + var newNodes = []; + // replace range with function call + var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, + /*typeArguments*/ undefined, callArguments); + if (range.facts & RangeFacts.IsGenerator) { + call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call); + } + if (range.facts & RangeFacts.IsAsyncFunction) { + call = ts.createAwait(call); + } + if (writes) { + if (returnValueProperty) { + // has both writes and return, need to create variable declaration to hold return value; + newNodes.push(ts.createVariableStatement( + /*modifiers*/ undefined, [ts.createVariableDeclaration(returnValueProperty, ts.createKeywordTypeNode(119 /* AnyKeyword */))])); + } + var assignments = getPropertyAssignmentsForWrites(writes); + if (returnValueProperty) { + assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty)); + } + // propagate writes back + if (assignments.length === 1) { + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); + } + else { + newNodes.push(ts.createStatement(ts.createBinary(assignments[0].name, 58 /* EqualsToken */, call))); + } + } + else { + // emit e.g. + // { a, b, __return } = newFunction(a, b); + // return __return; + newNodes.push(ts.createStatement(ts.createBinary(ts.createObjectLiteral(assignments), 58 /* EqualsToken */, call))); + if (returnValueProperty) { + newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); } + } + } + else { + if (range.facts & RangeFacts.HasReturn) { + newNodes.push(ts.createReturn(call)); + } + else if (isReadonlyArray(range.range)) { + newNodes.push(ts.createStatement(call)); + } + else { + newNodes.push(call); + } + } + if (isReadonlyArray(range.range)) { + changeTracker.replaceNodesWithNodes(context.file, range.range, newNodes, { + nodeSeparator: context.newLineCharacter, + suffix: context.newLineCharacter // insert newline only when replacing statements }); } - // all static members are stored in the "exports" array of symbol - if (symbol.exports) { - symbol.exports.forEach(function (member) { - var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]); - if (memberElement) { - memberElements.push(memberElement); + else { + changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); + } + return { + scope: scope, + scopeDescription: getDescriptionForScope(scope), + changes: changeTracker.getChanges() + }; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); + } + function generateReturnValueProperty() { + return "__return"; + } + function transformFunctionBody(body) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + // already block, no writes to propagate back, no substitutions - can use node as is + return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { + // add return at the end to propagate writes back in case if control flow falls out of the function body + // it is ok to know that range has at least one return since it we only allow unconditional returns + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); + } + } + return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 /* ReturnStatement */ && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = generateReturnValueProperty(); + } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); + } + else { + return ts.createReturn(ts.createObjectLiteral(assignments)); + } + } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } + } + } + } + extractMethod_1.extractFunctionInScope = extractFunctionInScope; + function isModuleBlock(n) { + return n.kind === 234 /* ModuleBlock */; + } + function isReadonlyArray(v) { + return ts.isArray(v); + } + /** + * Produces a range that spans the entirety of nodes, given a selection + * that might start/end in the middle of nodes. + * + * For example, when the user makes a selection like this + * v---v + * var someThing = foo + bar; + * this returns ^-------^ + */ + function getEnclosingTextRange(targetRange, sourceFile) { + return isReadonlyArray(targetRange.range) + ? { pos: targetRange.range[0].getStart(sourceFile), end: targetRange.range[targetRange.range.length - 1].getEnd() } + : targetRange.range; + } + var Usage; + (function (Usage) { + // value should be passed to extracted method + Usage[Usage["Read"] = 1] = "Read"; + // value should be passed to extracted method and propagated back + Usage[Usage["Write"] = 2] = "Write"; + })(Usage || (Usage = {})); + function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker) { + var usagesPerScope = []; + var substitutionsPerScope = []; + var errorsPerScope = []; + var visibleDeclarationsInExtractedRange = []; + // initialize results + for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) { + var _ = scopes_1[_i]; + usagesPerScope.push({ usages: ts.createMap(), substitutions: ts.createMap() }); + substitutionsPerScope.push(ts.createMap()); + errorsPerScope.push([]); + } + var seenUsages = ts.createMap(); + var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range; + var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] : ts.getEnclosingBlockScopeContainer(scopes[0]); + collectUsages(target); + var _loop_8 = function (i) { + var hasWrite = false; + var readonlyClassPropertyWrite = undefined; + usagesPerScope[i].usages.forEach(function (value) { + if (value.usage === 2 /* Write */) { + hasWrite = true; + if (value.symbol.flags & 106500 /* ClassMember */ && + value.symbol.valueDeclaration && + ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) { + readonlyClassPropertyWrite = value.symbol.valueDeclaration; + } } }); + if (hasWrite && !isReadonlyArray(targetRange.range) && ts.isExpression(targetRange.range)) { + errorsPerScope[i].push(ts.createDiagnosticForNode(targetRange.range, Messages.CannotCombineWritesAndReturns)); + } + else if (readonlyClassPropertyWrite && i > 0) { + errorsPerScope[i].push(ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotCombineWritesAndReturns)); + } + }; + for (var i = 0; i < scopes.length; i++) { + _loop_8(i); + } + // If there are any declarations in the extracted block that are used in the same enclosing + // lexical scope, we can't move the extraction "up" as those declarations will become unreachable + if (visibleDeclarationsInExtractedRange.length) { + ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); + } + return { target: target, usagesPerScope: usagesPerScope, errorsPerScope: errorsPerScope }; + function collectUsages(node, valueUsage) { + if (valueUsage === void 0) { valueUsage = 1 /* Read */; } + if (ts.isDeclaration(node) && node.symbol) { + visibleDeclarationsInExtractedRange.push(node.symbol); + } + if (ts.isAssignmentExpression(node)) { + // use 'write' as default usage for values + collectUsages(node.left, 2 /* Write */); + collectUsages(node.right); + } + else if (ts.isUnaryExpressionWithWrite(node)) { + collectUsages(node.operand, 2 /* Write */); + } + else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) { + // use 'write' as default usage for values + ts.forEachChild(node, collectUsages); + } + else if (ts.isIdentifier(node)) { + if (!node.parent) { + return; + } + if (ts.isQualifiedName(node.parent) && node !== node.parent.left) { + return; + } + if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { + return; + } + recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node)); + } + else { + ts.forEachChild(node, collectUsages); + } } - return memberElements; - function shouldConvertDeclaration(_target, source) { - // Right now the only thing we can convert are function expressions - other values shouldn't get - // transformed. We can update this once ES public class properties are available. - return ts.isFunctionLike(source); + function recordUsage(n, usage, isTypeNode) { + var symbolId = recordUsagebySymbol(n, usage, isTypeNode); + if (symbolId) { + for (var i = 0; i < scopes.length; i++) { + // push substitution from map to map to simplify rewriting + var substitition = substitutionsPerScope[i].get(symbolId); + if (substitition) { + usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitition); + } + } + } } - function createClassElement(symbol, modifiers) { - // both properties and methods are bound as property symbols - if (!(symbol.flags & 4 /* Property */)) { - return; + function recordUsagebySymbol(identifier, usage, isTypeName) { + var symbol = checker.getSymbolAtLocation(identifier); + if (!symbol) { + // cannot find symbol - do nothing + return undefined; } - var memberDeclaration = symbol.valueDeclaration; - var assignmentBinaryExpression = memberDeclaration.parent; - if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { - return; + var symbolId = ts.getSymbolId(symbol).toString(); + var lastUsage = seenUsages.get(symbolId); + // there are two kinds of value usages + // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter + // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and + // returned as a return value + // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read' + // since all information is already recorded + if (lastUsage && lastUsage >= usage) { + return symbolId; + } + seenUsages.set(symbolId, usage); + if (lastUsage) { + // if we get here this means that we are trying to handle 'write' and 'read' was already processed + // walk scopes and update existing records. + for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) { + var perScope = usagesPerScope_1[_i]; + var prevEntry = perScope.usages.get(identifier.text); + if (prevEntry) { + perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); + } + } + return symbolId; + } + // find first declaration in this file + var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; }); + if (!declInFile) { + return undefined; } - // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end - var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 210 /* ExpressionStatement */ - ? assignmentBinaryExpression.parent : assignmentBinaryExpression; - deleteNode(nodeToDelete); - if (!assignmentBinaryExpression.right) { - return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, - /*type*/ undefined, /*initializer*/ undefined); - } - switch (assignmentBinaryExpression.right.kind) { - case 186 /* FunctionExpression */: { - var functionExpression = assignmentBinaryExpression.right; - var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, - /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); - copyComments(assignmentBinaryExpression, method); - return method; - } - case 187 /* ArrowFunction */: { - var arrowFunction = assignmentBinaryExpression.right; - var arrowFunctionBody = arrowFunction.body; - var bodyBlock = void 0; - // case 1: () => { return [1,2,3] } - if (arrowFunctionBody.kind === 207 /* Block */) { - bodyBlock = arrowFunctionBody; + if (ts.rangeContainsRange(enclosingTextRange, declInFile)) { + // declaration is located in range to be extracted - do nothing + return undefined; + } + if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) { + // this is write to a reference located outside of the target scope and range is extracted into generator + // currently this is unsupported scenario + for (var _a = 0, errorsPerScope_1 = errorsPerScope; _a < errorsPerScope_1.length; _a++) { + var errors = errorsPerScope_1[_a]; + errors.push(ts.createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators)); + } + } + for (var i = 0; i < scopes.length; i++) { + var scope = scopes[i]; + var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + if (resolvedSymbol === symbol) { + continue; + } + if (!substitutionsPerScope[i].has(symbolId)) { + var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName); + if (substitution) { + substitutionsPerScope[i].set(symbolId, substitution); } - else { - var expression = arrowFunctionBody; - bodyBlock = ts.createBlock([ts.createReturn(expression)]); + else if (isTypeName) { + errorsPerScope[i].push(ts.createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope)); } - var method = ts.createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, - /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); - copyComments(assignmentBinaryExpression, method); - return method; - } - default: { - // Don't try to declare members in JavaScript files - if (ts.isSourceFileJavaScript(sourceFile)) { - return; + else { + usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } - var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, - /*type*/ undefined, assignmentBinaryExpression.right); - copyComments(assignmentBinaryExpression.parent, prop); - return prop; } } + return symbolId; } - } - function copyComments(sourceNode, targetNode) { - ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { - if (kind === 3 /* MultiLineCommentTrivia */) { - // Remove leading /* - pos += 2; - // Remove trailing */ - end -= 2; + function checkForUsedDeclarations(node) { + // If this node is entirely within the original extraction range, we don't need to do anything. + if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) { + return; + } + // Otherwise check and recurse. + var sym = checker.getSymbolAtLocation(node); + if (sym && visibleDeclarationsInExtractedRange.some(function (d) { return d === sym; })) { + for (var _i = 0, errorsPerScope_2 = errorsPerScope; _i < errorsPerScope_2.length; _i++) { + var scope = errorsPerScope_2[_i]; + scope.push(ts.createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + } + return true; } else { - // Remove leading // - pos += 2; + ts.forEachChild(node, checkForUsedDeclarations); } - ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); - }); + } + function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) { + if (!symbol) { + return undefined; + } + if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) { + return ts.createIdentifier(symbol.name); + } + var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); + if (prefix === undefined) { + return undefined; + } + return isTypeNode ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name)) : ts.createPropertyAccess(prefix, symbol.name); + } } - function createClassFromVariableDeclaration(node) { - var initializer = node.initializer; - if (!initializer || initializer.kind !== 186 /* FunctionExpression */) { + function getParentNodeInSpan(node, file, span) { + if (!node) return undefined; + while (node.parent) { + if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { + return node; + } + node = node.parent; } - if (node.name.kind !== 71 /* Identifier */) { - return undefined; + } + function spanContainsNode(span, node, file) { + return ts.textSpanContainsPosition(span, node.getStart(file)) && + node.getEnd() <= ts.textSpanEnd(span); + } + /** + * Computes whether or not a node represents an expression in a position where it could + * be extracted. + * The isExpression() in utilities.ts returns some false positives we need to handle, + * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression + * in the sense of something that you could extract on + */ + function isExtractableExpression(node) { + switch (node.parent.kind) { + case 264 /* EnumMember */: + return false; } - var memberElements = createClassElementsFromSymbol(initializer.symbol); - if (initializer.body) { - memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); + switch (node.kind) { + case 9 /* StringLiteral */: + return node.parent.kind !== 238 /* ImportDeclaration */ && + node.parent.kind !== 242 /* ImportSpecifier */; + case 198 /* SpreadElement */: + case 174 /* ObjectBindingPattern */: + case 176 /* BindingElement */: + return false; + case 71 /* Identifier */: + return node.parent.kind !== 176 /* BindingElement */ && + node.parent.kind !== 242 /* ImportSpecifier */ && + node.parent.kind !== 246 /* ExportSpecifier */; } - var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, - /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); - // Don't call copyComments here because we'll already leave them in place - return cls; + return true; } - function createClassFromFunctionDeclaration(node) { - var memberElements = createClassElementsFromSymbol(ctorSymbol); - if (node.body) { - memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); + function isBlockLike(node) { + switch (node.kind) { + case 207 /* Block */: + case 265 /* SourceFile */: + case 234 /* ModuleBlock */: + case 257 /* CaseClause */: + return true; + default: + return false; } - var cls = ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, - /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); - // Don't call copyComments here because we'll already leave them in place - return cls; } - } + })(extractMethod = refactor.extractMethod || (refactor.extractMethod = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /// +/// /// /// /// @@ -89074,7 +90430,7 @@ var ts; node.parent = parent; return node; } - var NodeObject = (function () { + var NodeObject = /** @class */ (function () { function NodeObject(kind, pos, end) { this.pos = pos; this.end = end; @@ -89227,7 +90583,7 @@ var ts; }; return NodeObject; }()); - var TokenOrIdentifierObject = (function () { + var TokenOrIdentifierObject = /** @class */ (function () { function TokenOrIdentifierObject(pos, end) { // Set properties in same order as NodeObject this.pos = pos; @@ -89282,7 +90638,7 @@ var ts; }; return TokenOrIdentifierObject; }()); - var SymbolObject = (function () { + var SymbolObject = /** @class */ (function () { function SymbolObject(flags, name) { this.flags = flags; this.escapedName = name; @@ -89320,7 +90676,7 @@ var ts; }; return SymbolObject; }()); - var TokenObject = (function (_super) { + var TokenObject = /** @class */ (function (_super) { __extends(TokenObject, _super); function TokenObject(kind, pos, end) { var _this = _super.call(this, pos, end) || this; @@ -89329,7 +90685,7 @@ var ts; } return TokenObject; }(TokenOrIdentifierObject)); - var IdentifierObject = (function (_super) { + var IdentifierObject = /** @class */ (function (_super) { __extends(IdentifierObject, _super); function IdentifierObject(_kind, pos, end) { return _super.call(this, pos, end) || this; @@ -89344,7 +90700,7 @@ var ts; return IdentifierObject; }(TokenOrIdentifierObject)); IdentifierObject.prototype.kind = 71 /* Identifier */; - var TypeObject = (function () { + var TypeObject = /** @class */ (function () { function TypeObject(checker, flags) { this.checker = checker; this.flags = flags; @@ -89386,7 +90742,7 @@ var ts; }; return TypeObject; }()); - var SignatureObject = (function () { + var SignatureObject = /** @class */ (function () { function SignatureObject(checker) { this.checker = checker; } @@ -89416,7 +90772,7 @@ var ts; }; return SignatureObject; }()); - var SourceFileObject = (function (_super) { + var SourceFileObject = /** @class */ (function (_super) { __extends(SourceFileObject, _super); function SourceFileObject(kind, pos, end) { return _super.call(this, kind, pos, end) || this; @@ -89587,7 +90943,7 @@ var ts; }; return SourceFileObject; }(NodeObject)); - var SourceMapSourceObject = (function () { + var SourceMapSourceObject = /** @class */ (function () { function SourceMapSourceObject(fileName, text, skipTrivia) { this.fileName = fileName; this.text = text; @@ -89656,7 +91012,7 @@ var ts; // Cache host information about script Should be refreshed // at each language service public entry point, since we don't know when // the set of scripts handled by the host changes. - var HostCache = (function () { + var HostCache = /** @class */ (function () { function HostCache(host, getCanonicalFileName) { this.host = host; // script id => script index @@ -89718,7 +91074,7 @@ var ts; }; return HostCache; }()); - var SyntaxTreeCache = (function () { + var SyntaxTreeCache = /** @class */ (function () { function SyntaxTreeCache(host) { this.host = host; } @@ -89813,7 +91169,7 @@ var ts; return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind); } ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile; - var CancellationTokenObject = (function () { + var CancellationTokenObject = /** @class */ (function () { function CancellationTokenObject(cancellationToken) { this.cancellationToken = cancellationToken; } @@ -89829,7 +91185,7 @@ var ts; }()); /* @internal */ /** A cancellation that throttles calls to the host */ - var ThrottledCancellationToken = (function () { + var ThrottledCancellationToken = /** @class */ (function () { function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) { if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; } this.hostCancellationToken = hostCancellationToken; @@ -89980,8 +91336,8 @@ var ts; if (program) { var oldSourceFiles = program.getSourceFiles(); var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings); - for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { - var oldSourceFile = oldSourceFiles_1[_i]; + for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) { + var oldSourceFile = oldSourceFiles_2[_i]; if (!newProgram.getSourceFile(oldSourceFile.fileName) || shouldCreateNewSourceFiles) { documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey); } @@ -90038,7 +91394,7 @@ var ts; // We do not support the scenario where a host can modify a registered // file's script kind, i.e. in one project some file is treated as ".ts" // and in another as ".js" - ts.Debug.assert(hostFileInformation.scriptKind === oldSourceFile.scriptKind, "Registered script kind (" + oldSourceFile.scriptKind + ") should match new script kind (" + hostFileInformation.scriptKind + ") for file: " + path); + ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path); return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind); } // We didn't already have the file. Fall through and acquire it from the registry. @@ -90777,12 +92133,17 @@ var ts; function getPropertySymbolsFromContextualType(typeChecker, node) { var objectLiteral = node.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(node.name)); - if (name && contextualType) { + return getPropertySymbolsFromType(contextualType, node.name); + } + ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + /* @internal */ + function getPropertySymbolsFromType(type, propName) { + var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName)); + if (name && type) { var result_10 = []; - var symbol = contextualType.getProperty(name); - if (contextualType.flags & 65536 /* Union */) { - ts.forEach(contextualType.types, function (t) { + var symbol = type.getProperty(name); + if (type.flags & 65536 /* Union */) { + ts.forEach(type.types, function (t) { var symbol = t.getProperty(name); if (symbol) { result_10.push(symbol); @@ -90797,7 +92158,7 @@ var ts; } return undefined; } - ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; + ts.getPropertySymbolsFromType = getPropertySymbolsFromType; function isArgumentOfElementAccessExpression(node) { return node && node.parent && @@ -91352,7 +92713,7 @@ var ts; } } function spanInOpenParenToken(node) { - if (node.parent.kind === 212 /* DoStatement */ || + if (node.parent.kind === 212 /* DoStatement */ || // Go to while keyword and do action instead node.parent.kind === 181 /* CallExpression */ || node.parent.kind === 182 /* NewExpression */) { return spanInPreviousNode(node); @@ -91471,7 +92832,7 @@ var ts; logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message); } } - var ScriptSnapshotShimAdapter = (function () { + var ScriptSnapshotShimAdapter = /** @class */ (function () { function ScriptSnapshotShimAdapter(scriptSnapshotShim) { this.scriptSnapshotShim = scriptSnapshotShim; } @@ -91499,7 +92860,7 @@ var ts; }; return ScriptSnapshotShimAdapter; }()); - var LanguageServiceShimHostAdapter = (function () { + var LanguageServiceShimHostAdapter = /** @class */ (function () { function LanguageServiceShimHostAdapter(shimHost) { var _this = this; this.shimHost = shimHost; @@ -91623,7 +92984,7 @@ var ts; return LanguageServiceShimHostAdapter; }()); ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter; - var CoreServicesShimHostAdapter = (function () { + var CoreServicesShimHostAdapter = /** @class */ (function () { function CoreServicesShimHostAdapter(shimHost) { var _this = this; this.shimHost = shimHost; @@ -91688,7 +93049,7 @@ var ts; return JSON.stringify({ error: err }); } } - var ShimBase = (function () { + var ShimBase = /** @class */ (function () { function ShimBase(factory) { this.factory = factory; factory.registerShim(this); @@ -91712,7 +93073,7 @@ var ts; code: diagnostic.code }; } - var LanguageServiceShimObject = (function (_super) { + var LanguageServiceShimObject = /** @class */ (function (_super) { __extends(LanguageServiceShimObject, _super); function LanguageServiceShimObject(factory, host, languageService) { var _this = _super.call(this, factory) || this; @@ -91985,7 +93346,7 @@ var ts; function convertClassifications(classifications) { return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState }; } - var ClassifierShimObject = (function (_super) { + var ClassifierShimObject = /** @class */ (function (_super) { __extends(ClassifierShimObject, _super); function ClassifierShimObject(factory, logger) { var _this = _super.call(this, factory) || this; @@ -92012,7 +93373,7 @@ var ts; }; return ClassifierShimObject; }(ShimBase)); - var CoreServicesShimObject = (function (_super) { + var CoreServicesShimObject = /** @class */ (function (_super) { __extends(CoreServicesShimObject, _super); function CoreServicesShimObject(factory, logger, host) { var _this = _super.call(this, factory) || this; @@ -92119,7 +93480,7 @@ var ts; }; return CoreServicesShimObject; }(ShimBase)); - var TypeScriptServicesFactory = (function () { + var TypeScriptServicesFactory = /** @class */ (function () { function TypeScriptServicesFactory() { this._shims = []; } diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 0aea3ef23596b..9f38426db2613 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -14,6 +14,14 @@ and limitations under the License. ***************************************************************************** */ "use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || @@ -154,7 +162,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; @@ -438,10 +446,9 @@ var ts; ts.removeWhere = removeWhere; function filterMutate(array, f) { var outIndex = 0; - for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { - var item = array_3[_i]; - if (f(item)) { - array[outIndex] = item; + for (var i = 0; i < array.length; i++) { + if (f(array[i], i, array)) { + array[outIndex] = array[i]; outIndex++; } } @@ -487,8 +494,8 @@ var ts; var result; if (array) { result = []; - for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { - var v = array_4[_i]; + for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { + var v = array_3[_i]; if (v) { if (isArray(v)) { addRange(result, v); @@ -558,11 +565,13 @@ var ts; ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; - for (var i = 0; i < array.length; i++) { - var item = array[i]; - var mapped = mapFn(item, i); - if (mapped !== undefined) { - result.push(mapped); + if (array) { + for (var i = 0; i < array.length; i++) { + var item = array[i]; + var mapped = mapFn(item, i); + if (mapped !== undefined) { + result.push(mapped); + } } } return result; @@ -630,8 +639,8 @@ var ts; function some(array, predicate) { if (array) { if (predicate) { - for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { - var v = array_5[_i]; + for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { + var v = array_4[_i]; if (predicate(v)) { return true; } @@ -656,8 +665,8 @@ var ts; var result; if (array) { result = []; - loop: for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { - var item = array_6[_i]; + loop: for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { + var item = array_5[_i]; for (var _a = 0, result_1 = result; _a < result_1.length; _a++) { var res = result_1[_a]; if (areEqual ? areEqual(res, item) : res === item) { @@ -745,8 +754,8 @@ var ts; ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; - for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { - var v = array_7[_i]; + for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { + var v = array_6[_i]; result += v[prop]; } return result; @@ -1006,8 +1015,8 @@ var ts; ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); - for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { - var value = array_8[_i]; + for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { + var value = array_7[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; @@ -1167,11 +1176,11 @@ var ts; ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { var end = start + length; - Debug.assert(start >= 0, "start must be non-negative, is " + start); - Debug.assert(length >= 0, "length must be non-negative, is " + length); + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); if (file) { - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + Debug.assertLessThanOrEqual(start, file.text.length); + Debug.assertLessThanOrEqual(end, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { @@ -1655,8 +1664,28 @@ var ts; ts.fileExtensionIsOneOf = fileExtensionIsOneOf; var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42, 63]; - var singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; - var singleAsteriskRegexFragmentOther = "[^/]*"; + ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; + var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; + var filesMatcher = { + singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } + }; + var directoriesMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } + }; + var excludeMatcher = { + singleAsteriskRegexFragment: "[^/]*", + doubleAsteriskRegexFragment: "(/.+?)?", + replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } + }; + var wildcardMatchers = { + files: filesMatcher, + directories: directoriesMatcher, + exclude: excludeMatcher + }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { @@ -1671,18 +1700,16 @@ var ts; if (specs === undefined || specs.length === 0) { return undefined; } - var replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther; - var singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther; - var doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; return flatMap(specs, function (spec) { - return spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); + return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } function isImplicitGlob(lastPathComponent) { return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; - function getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter) { + function getSubPatternFromSpec(spec, basePath, usage, _a) { + var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; @@ -1714,16 +1741,24 @@ var ts; subpattern += ts.directorySeparator; } if (usage !== "exclude") { + var componentPattern = ""; if (component.charCodeAt(0) === 42) { - subpattern += "([^./]" + singleAsteriskRegexFragment + ")?"; + componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63) { - subpattern += "[^./]"; + componentPattern += "[^./]"; component = component.substr(1); } + componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); + if (componentPattern !== component) { + subpattern += implicitExcludePathRegexPattern; + } + subpattern += componentPattern; + } + else { + subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } - subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } hasWrittenComponent = true; } @@ -1733,12 +1768,6 @@ var ts; } return subpattern; } - function replaceWildCardCharacterFiles(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentFiles); - } - function replaceWildCardCharacterOther(match) { - return replaceWildcardCharacter(match, singleAsteriskRegexFragmentOther); - } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } @@ -1875,14 +1904,7 @@ var ts; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } - var extensions = allSupportedExtensions.slice(0); - for (var _i = 0, extraFileExtensions_1 = extraFileExtensions; _i < extraFileExtensions_1.length; _i++) { - var extInfo = extraFileExtensions_1[_i]; - if (extensions.indexOf(extInfo.extension) === -1) { - extensions.push(extInfo.extension); - } - } - return extensions; + return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; }))); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { @@ -2010,12 +2032,37 @@ var ts; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { - message += "\r\nVerbose Debug Information: " + verboseDebugInfo(); + message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; + function assertEqual(a, b, msg, msg2) { + if (a !== b) { + var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; + fail("Expected " + a + " === " + b + ". " + message); + } + } + Debug.assertEqual = assertEqual; + function assertLessThan(a, b, msg) { + if (a >= b) { + fail("Expected " + a + " < " + b + ". " + (msg || "")); + } + } + Debug.assertLessThan = assertLessThan; + function assertLessThanOrEqual(a, b) { + if (a > b) { + fail("Expected " + a + " <= " + b); + } + } + Debug.assertLessThanOrEqual = assertLessThanOrEqual; + function assertGreaterThanOrEqual(a, b) { + if (a < b) { + fail("Expected " + a + " >= " + b); + } + } + Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); @@ -2150,6 +2197,10 @@ var ts; Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; + function isAnySupportedFileExtension(path) { + return tryGetExtensionFromPath(path) !== undefined; + } + ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } @@ -2161,6 +2212,12 @@ var ts; })(ts || (ts = {})); var ts; (function (ts) { + function setStackTraceLimit() { + if (Error.stackTraceLimit < 100) { + Error.stackTraceLimit = 100; + } + } + ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; @@ -2210,7 +2267,7 @@ var ts; watcher.referenceCount += 1; return; } - watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); + watcher = _fs.watch(dirPath || ".", { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; @@ -3031,6 +3088,7 @@ var ts; Expected_at_least_0_arguments_but_got_a_minimum_of_1: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557", "Expected at least {0} arguments, but got a minimum of {1}."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), + Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), @@ -3218,6 +3276,7 @@ var ts; Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), + Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), @@ -3471,6 +3530,8 @@ var ts; Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'."), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), + Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), }; })(ts || (ts = {})); var ts; @@ -3491,19 +3552,6 @@ var ts; return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; - function findDeclaration(symbol, predicate) { - var declarations = symbol.declarations; - if (declarations) { - for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { - var declaration = declarations_2[_i]; - if (predicate(declaration)) { - return declaration; - } - } - } - return undefined; - } - ts.findDeclaration = findDeclaration; var stringWriter = createSingleLineStringWriter(); var stringWriterAcquired = false; function createSingleLineStringWriter() { @@ -3566,9 +3614,13 @@ var ts; function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && - oldResolution.resolvedFileName === newResolution.resolvedFileName; + oldResolution.resolvedFileName === newResolution.resolvedFileName && + packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; + function packageIdIsEqual(a, b) { + return a === b || a && b && a.name === b.name && a.version === b.version; + } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } @@ -3633,14 +3685,6 @@ var ts; return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; - function getStartPosOfNode(node) { - return node.pos; - } - ts.getStartPosOfNode = getStartPosOfNode; - function isDefined(value) { - return value !== undefined; - } - ts.isDefined = isDefined; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); @@ -3671,6 +3715,25 @@ var ts; return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; + function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { + if (text.charCodeAt(commentPos + 1) === 47 && + commentPos + 2 < commentEnd && + text.charCodeAt(commentPos + 2) === 47) { + var textSubStr = text.substring(commentPos, commentEnd); + return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || + textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || + textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || + textSubStr.match(defaultLibReferenceRegEx) ? + true : false; + } + return false; + } + ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; + function isPinnedComment(text, comment) { + return text.charCodeAt(comment.pos + 1) === 42 && + text.charCodeAt(comment.pos + 2) === 33; + } + ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { if (nodeIsMissing(node)) { return node.pos; @@ -3727,15 +3790,20 @@ var ts; var escapeText = getEmitFlags(node) & 16777216 ? escapeString : escapeNonAsciiString; switch (node.kind) { case 9: - return '"' + escapeText(node.text) + '"'; + if (node.singleQuote) { + return "'" + escapeText(node.text, 39) + "'"; + } + else { + return '"' + escapeText(node.text, 34) + '"'; + } case 13: - return "`" + escapeText(node.text) + "`"; + return "`" + escapeText(node.text, 96) + "`"; case 14: - return "`" + escapeText(node.text) + "${"; + return "`" + escapeText(node.text, 96) + "${"; case 15: - return "}" + escapeText(node.text) + "${"; + return "}" + escapeText(node.text, 96) + "${"; case 16: - return "}" + escapeText(node.text) + "`"; + return "}" + escapeText(node.text, 96) + "`"; case 8: return node.text; } @@ -3990,10 +4058,6 @@ var ts; return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos); } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; - function getLeadingCommentRangesOfNodeFromText(node, text) { - return ts.getLeadingCommentRanges(text, node.pos); - } - ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 146 || node.kind === 145 || @@ -4001,7 +4065,7 @@ var ts; node.kind === 187 || node.kind === 185) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); + ts.getLeadingCommentRanges(text, node.pos); return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 && text.charCodeAt(comment.pos + 2) === 42 && @@ -4010,8 +4074,9 @@ var ts; } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; - ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; + var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; + var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (158 <= node.kind && node.kind <= 173) { return true; @@ -4238,21 +4303,11 @@ var ts; } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { - while (true) { - node = node.parent; - if (!node || ts.isFunctionLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { - while (true) { - node = node.parent; - if (!node || ts.isClassLike(node)) { - return node; - } - } + return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { @@ -5056,14 +5111,14 @@ var ts; ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*/gim; + var isNoDefaultLibRegEx = new RegExp(defaultLibReferenceRegEx.source, "gim"); if (simpleReferenceRegEx.test(comment)) { if (isNoDefaultLibRegEx.test(comment)) { return { isNoDefaultLib: true }; } else { var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment); - var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + var refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); var match = refMatchResult || refLibResult; if (match) { var pos = commentRange.pos + match[1].length + match[2].length; @@ -5244,10 +5299,6 @@ var ts; return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; - function getOriginalSourceFiles(sourceFiles) { - return ts.sameMap(sourceFiles, getOriginalSourceFile); - } - ts.getOriginalSourceFiles = getOriginalSourceFiles; function getExpressionAssociativity(expression) { var operator = getOperator(expression); var hasArguments = expression.kind === 182 && expression.arguments !== undefined; @@ -5481,7 +5532,9 @@ var ts; } } ts.createDiagnosticCollection = createDiagnosticCollection; - var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", @@ -5492,11 +5545,16 @@ var ts; "\n": "\\n", "\\": "\\\\", "\"": "\\\"", + "\'": "\\\'", + "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" }); - function escapeString(s) { + function escapeString(s, quoteChar) { + var escapedCharsRegExp = quoteChar === 96 ? backtickQuoteEscapedCharsRegExp : + quoteChar === 39 ? singleQuoteEscapedCharsRegExp : + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } ts.escapeString = escapeString; @@ -5514,8 +5572,8 @@ var ts; return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; - function escapeNonAsciiString(s) { - s = escapeString(s); + function escapeNonAsciiString(s, quoteChar) { + s = escapeString(s, quoteChar); return nonAsciiCharacters.test(s) ? s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) : s; @@ -5856,7 +5914,7 @@ var ts; var currentDetachedCommentInfo; if (removeComments) { if (node.pos === 0) { - leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedComment); + leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { @@ -5888,9 +5946,8 @@ var ts; } } return currentDetachedCommentInfo; - function isPinnedComment(comment) { - return text.charCodeAt(comment.pos + 1) === 42 && - text.charCodeAt(comment.pos + 2) === 33; + function isPinnedCommentLocal(comment) { + return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; @@ -5961,9 +6018,13 @@ var ts; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { - return (getModifierFlags(node) & flags) !== 0; + return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; + function getSelectedModifierFlags(node, flags) { + return getModifierFlags(node) & flags; + } + ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912) { return node.modifierFlagsCache & ~536870912; @@ -6039,21 +6100,6 @@ var ts; return false; } ts.isDestructuringAssignment = isDestructuringAssignment; - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 71) { - return true; - } - else if (ts.isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } - } function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } @@ -6166,72 +6212,6 @@ var ts; return carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; - function isSimpleExpression(node) { - return isSimpleExpressionWorker(node, 0); - } - ts.isSimpleExpression = isSimpleExpression; - function isSimpleExpressionWorker(node, depth) { - if (depth <= 5) { - var kind = node.kind; - if (kind === 9 - || kind === 8 - || kind === 12 - || kind === 13 - || kind === 71 - || kind === 99 - || kind === 97 - || kind === 101 - || kind === 86 - || kind === 95) { - return true; - } - else if (kind === 179) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 180) { - return isSimpleExpressionWorker(node.expression, depth + 1) - && isSimpleExpressionWorker(node.argumentExpression, depth + 1); - } - else if (kind === 192 - || kind === 193) { - return isSimpleExpressionWorker(node.operand, depth + 1); - } - else if (kind === 194) { - return node.operatorToken.kind !== 40 - && isSimpleExpressionWorker(node.left, depth + 1) - && isSimpleExpressionWorker(node.right, depth + 1); - } - else if (kind === 195) { - return isSimpleExpressionWorker(node.condition, depth + 1) - && isSimpleExpressionWorker(node.whenTrue, depth + 1) - && isSimpleExpressionWorker(node.whenFalse, depth + 1); - } - else if (kind === 190 - || kind === 189 - || kind === 188) { - return isSimpleExpressionWorker(node.expression, depth + 1); - } - else if (kind === 177) { - return node.elements.length === 0; - } - else if (kind === 178) { - return node.properties.length === 0; - } - else if (kind === 181) { - if (!isSimpleExpressionWorker(node.expression, depth + 1)) { - return false; - } - for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { - var argument = _a[_i]; - if (!isSimpleExpressionWorker(argument, depth + 1)) { - return false; - } - } - return true; - } - } - return false; - } function formatEnum(value, enumObject, isFlags) { if (value === void 0) { value = 0; } var members = getEnumMembers(enumObject); @@ -6300,18 +6280,6 @@ var ts; return formatEnum(flags, ts.ObjectFlags, true); } ts.formatObjectFlags = formatObjectFlags; - function getRangePos(range) { - return range ? range.pos : -1; - } - ts.getRangePos = getRangePos; - function getRangeEnd(range) { - return range ? range.end : -1; - } - ts.getRangeEnd = getRangeEnd; - function movePos(pos, value) { - return ts.positionIsSynthesized(pos) ? -1 : pos + value; - } - ts.movePos = movePos; function createRange(pos, end) { return { pos: pos, end: end }; } @@ -6340,14 +6308,6 @@ var ts; return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; - function collapseRangeToStart(range) { - return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos); - } - ts.collapseRangeToStart = collapseRangeToStart; - function collapseRangeToEnd(range) { - return isCollapsedRange(range) ? range : moveRangePos(range, range.end); - } - ts.collapseRangeToEnd = collapseRangeToEnd; function createTokenRange(pos, token) { return createRange(pos, pos + ts.tokenToString(token).length); } @@ -6400,22 +6360,6 @@ var ts; function isInitializedVariable(node) { return node.initializer !== undefined; } - function isMergedWithClass(node) { - if (node.symbol) { - for (var _i = 0, _a = node.symbol.declarations; _i < _a.length; _i++) { - var declaration = _a[_i]; - if (declaration.kind === 229 && declaration !== node) { - return true; - } - } - } - return false; - } - ts.isMergedWithClass = isMergedWithClass; - function isFirstDeclarationOfKind(node, kind) { - return node.symbol && getDeclarationOfKind(node.symbol, kind) === node; - } - ts.isFirstDeclarationOfKind = isFirstDeclarationOfKind; function isWatchSet(options) { return options.watch && options.hasOwnProperty("watch"); } @@ -6616,6 +6560,20 @@ var ts; return ts.hasModifier(node, 92) && node.parent.kind === 152 && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; + function isEmptyBindingPattern(node) { + if (ts.isBindingPattern(node)) { + return ts.every(node.elements, isEmptyBindingElement); + } + return false; + } + ts.isEmptyBindingPattern = isEmptyBindingPattern; + function isEmptyBindingElement(node) { + if (ts.isOmittedExpression(node)) { + return true; + } + return isEmptyBindingPattern(node.name); + } + ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 176 || ts.isBindingPattern(node))) { node = node.parent; @@ -7696,6 +7654,18 @@ var ts; return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; + function isUnaryExpressionWithWrite(expr) { + switch (expr.kind) { + case 193: + return true; + case 192: + return expr.operator === 43 || + expr.operator === 44; + default: + return false; + } + } + ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; function isExpressionKind(kind) { return kind === 195 || kind === 197 @@ -7880,9 +7850,19 @@ var ts; var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) - || kind === 207; + || isBlockStatement(node); } ts.isStatement = isStatement; + function isBlockStatement(node) { + if (node.kind !== 207) + return false; + if (node.parent !== undefined) { + if (node.parent.kind === 224 || node.parent.kind === 260) { + return false; + } + } + return !ts.isFunctionBlock(node); + } function isModuleReference(node) { var kind = node.kind; return kind === 248 @@ -11377,11 +11357,31 @@ var ts; var node = parseTokenNode(); return token() === 23 ? undefined : node; } - function parseLiteralTypeNode() { + function parseLiteralTypeNode(negative) { var node = createNode(173); - node.literal = parseSimpleUnaryExpression(); - finishNode(node); - return node; + var unaryMinusExpression; + if (negative) { + unaryMinusExpression = createNode(192); + unaryMinusExpression.operator = 38; + nextToken(); + } + var expression; + switch (token()) { + case 9: + case 8: + expression = parseLiteralLikeNode(token()); + break; + case 101: + case 86: + expression = parseTokenNode(); + } + if (negative) { + unaryMinusExpression.operand = expression; + finishNode(unaryMinusExpression); + expression = unaryMinusExpression; + } + node.literal = expression; + return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8; @@ -11413,7 +11413,7 @@ var ts; case 86: return parseLiteralTypeNode(); case 38: - return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference(); + return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(true) : parseTypeReference(); case 105: case 95: return parseTokenNode(); @@ -11462,6 +11462,7 @@ var ts; case 101: case 86: case 134: + case 39: return true; case 38: return lookAhead(nextTokenIsNumericLiteral); @@ -11780,7 +11781,7 @@ var ts; if (!arrowFunction) { return undefined; } - var isAsync = !!(ts.getModifierFlags(arrowFunction) & 256); + var isAsync = ts.hasModifier(arrowFunction, 256); var lastToken = token(); arrowFunction.equalsGreaterThanToken = parseExpectedToken(36, false, ts.Diagnostics._0_expected, "=>"); arrowFunction.body = (lastToken === 36 || lastToken === 17) @@ -11896,7 +11897,7 @@ var ts; function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNode(187); node.modifiers = parseModifiersForArrowFunction(); - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; fillSignature(56, isAsync | (allowAmbiguity ? 0 : 8), node); if (!node.parameters) { return undefined; @@ -12629,7 +12630,7 @@ var ts; parseExpected(89); node.asteriskToken = parseOptionalToken(39); var isGenerator = node.asteriskToken ? 1 : 0; - var isAsync = (ts.getModifierFlags(node) & 256) ? 2 : 0; + var isAsync = ts.hasModifier(node, 256) ? 2 : 0; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : @@ -12854,10 +12855,13 @@ var ts; function parseCatchClause() { var result = createNode(260); parseExpected(74); - if (parseExpected(19)) { + if (parseOptional(19)) { result.variableDeclaration = parseVariableDeclaration(); + parseExpected(20); + } + else { + result.variableDeclaration = undefined; } - parseExpected(20); result.block = parseBlock(false); return finishNode(result); } @@ -14545,8 +14549,8 @@ var ts; array._children = undefined; array.pos += delta; array.end += delta; - for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { - var node = array_9[_i]; + for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { + var node = array_8[_i]; visitNode(node); } } @@ -14618,8 +14622,8 @@ var ts; array.intersectsChange = true; array._children = undefined; adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (var _i = 0, array_10 = array; _i < array_10.length; _i++) { - var node = array_10[_i]; + for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { + var node = array_9[_i]; visitNode(node); } return; @@ -15131,6 +15135,12 @@ var ts; category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "preserveSymlinks", + type: "boolean", + category: ts.Diagnostics.Module_Resolution_Options, + description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, + }, { name: "sourceRoot", type: "string", @@ -15742,7 +15752,7 @@ var ts; var text = valueExpression.text; if (option && typeof option.type !== "string") { var customOption = option; - if (!customOption.type.has(text)) { + if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } @@ -15993,12 +16003,10 @@ var ts; } } else { - var specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; var outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"]; if (outDir) { - specs.push(outDir); + excludeSpecs = [outDir]; } - excludeSpecs = specs; } if (fileNames === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; @@ -16249,7 +16257,7 @@ var ts; return value; } else if (typeof option.type !== "string") { - return option.type.get(value); + return option.type.get(typeof value === "string" ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } @@ -16324,23 +16332,13 @@ var ts; }; } function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { - var validSpecs = []; - for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) { - var spec = specs_1[_i]; - if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidMultipleRecursionPatterns.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec)); - } - else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { - errors.push(createDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec)); + return specs.filter(function (spec) { + var diag = specToDiagnostic(spec, allowTrailingRecursion); + if (diag !== undefined) { + errors.push(createDiagnostic(diag, spec)); } - else { - validSpecs.push(spec); - } - } - return validSpecs; + return diag === undefined; + }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { @@ -16358,6 +16356,17 @@ var ts; return ts.createCompilerDiagnostic(message, spec); } } + function specToDiagnostic(spec, allowTrailingRecursion) { + if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + else if (invalidMultipleRecursionPatterns.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; + } + else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { + return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; + } + } function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) { var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude"); var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); @@ -16482,7 +16491,7 @@ var ts; "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console" ]; - var nodeCoreModules = ts.arrayToMap(JsTyping.nodeCoreModuleList, function (x) { return x; }); + var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList); function loadSafeList(host, safeListPath) { var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); }); return ts.createMapFromTemplate(result.config); @@ -16664,6 +16673,12 @@ var ts; return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; + function withPackageId(packageId, r) { + return r && { path: r.path, extension: r.ext, packageId: packageId }; + } + function noPackageId(r) { + return withPackageId(undefined, r); + } var Extensions; (function (Extensions) { Extensions[Extensions["TypeScript"] = 0] = "TypeScript"; @@ -16679,12 +16694,11 @@ var ts; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { - resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport }, + resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } - function tryReadPackageJsonFields(readTypes, packageJsonPath, baseDirectory, state) { - var jsonContent = readJson(packageJsonPath, state.host); + function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { @@ -16778,7 +16792,9 @@ var ts; } var resolvedTypeReferenceDirective; if (resolved) { - resolved = realpath(resolved, host, traceEnabled); + if (!options.preserveSymlinks) { + resolved = realpath(resolved, host, traceEnabled); + } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary); } @@ -17079,7 +17095,7 @@ var ts; if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, false, state); if (path_1 !== undefined) { - return { path: path_1, extension: extension }; + return { path: path_1, extension: extension, packageId: undefined }; } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); @@ -17100,7 +17116,7 @@ var ts; function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, undefined, true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { - throw new Error("Could not resolve JS module " + moduleName + " starting at " + initialDir + ". Looked in: " + failedLookupLocations.join(", ")); + throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } @@ -17126,7 +17142,13 @@ var ts; trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); - return resolved_1 && { value: resolved_1.value && { resolved: { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }, isExternalLibraryImport: true } }; + if (!resolved_1) + return undefined; + var resolvedValue = resolved_1.value; + if (!compilerOptions.preserveSymlinks) { + resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realpath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); + } + return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); @@ -17161,7 +17183,7 @@ var ts; } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return resolvedFromFile; + return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { @@ -17179,6 +17201,9 @@ var ts; return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; + function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { + return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + } function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); if (resolvedByAddingExtension) { @@ -17208,9 +17233,9 @@ var ts; case Extensions.JavaScript: return tryExtension(".js") || tryExtension(".jsx"); } - function tryExtension(extension) { - var path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); - return path && { path: path, extension: extension }; + function tryExtension(ext) { + var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + return path && { path: path, ext: ext }; } } function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) { @@ -17233,12 +17258,20 @@ var ts; function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); + var packageId; if (considerPackageJson) { var packageJsonPath = pathToPackageJson(candidate); if (directoryExists && state.host.fileExists(packageJsonPath)) { - var fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state); + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); + } + var jsonContent = readJson(packageJsonPath, state.host); + if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") { + packageId = { name: jsonContent.name, version: jsonContent.version }; + } + var fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { - return fromPackageJson; + return withPackageId(packageId, fromPackageJson); } } else { @@ -17248,13 +17281,10 @@ var ts; failedLookupLocations.push(packageJsonPath); } } - return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return withPackageId(packageId, loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state)); } - function loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); - } - var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state); + function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { + var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } @@ -17270,11 +17300,15 @@ var ts; } } var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; - return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, false); + if (result) { + ts.Debug.assert(result.packageId === undefined); + return { path: result.path, ext: result.extension }; + } } function resolvedIfExtensionMatches(extensions, path) { - var extension = ts.tryGetExtensionFromPath(path); - return extension !== undefined && extensionIsOk(extensions, extension) ? { path: path, extension: extension } : undefined; + var ext = ts.tryGetExtensionFromPath(path); + return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } function extensionIsOk(extensions, extension) { switch (extensions) { @@ -17291,7 +17325,7 @@ var ts; } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || + return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { @@ -17365,7 +17399,7 @@ var ts; if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { @@ -17376,7 +17410,7 @@ var ts; var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, false, failedLookupLocations); function tryResolve(extensions) { - var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); + var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -17388,7 +17422,7 @@ var ts; return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, false, state)); }); if (resolved_3) { return resolved_3; @@ -17399,7 +17433,7 @@ var ts; } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, false, state)); } } } @@ -17727,14 +17761,15 @@ var ts; _this.sendResponse(_this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles))); } finally { - _this.sendResponse({ + var response = { kind: server.EventEndInstallTypes, eventId: requestId, projectName: req.projectName, packagesToInstall: scopedTypings, installSuccess: ok, typingsInstallerVersion: ts.version - }); + }; + _this.sendResponse(response); } }); }; From ba56b62b9ff46060c4f09ffc6f8ab78889c2ac5a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 18 Aug 2017 15:38:19 -0700 Subject: [PATCH 08/60] Ensure string enums are generated in protocol.d.ts --- scripts/buildProtocol.ts | 14 +++++++++----- src/server/protocol.ts | 4 ++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts index e03338bf60ddd..c2ac33c83fc19 100644 --- a/scripts/buildProtocol.ts +++ b/scripts/buildProtocol.ts @@ -7,11 +7,15 @@ function endsWith(s: string, suffix: string) { return s.lastIndexOf(suffix, s.length - suffix.length) !== -1; } +function isStringEnum(declaration: ts.EnumDeclaration) { + return declaration.members.length && declaration.members.every(m => m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral); +} + class DeclarationsWalker { private visitedTypes: ts.Type[] = []; private text = ""; private removedTypes: ts.Type[] = []; - + private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) { } @@ -19,7 +23,7 @@ class DeclarationsWalker { let text = "declare namespace ts.server.protocol {\n"; var walker = new DeclarationsWalker(typeChecker, protocolFile); walker.visitTypeNodes(protocolFile); - text = walker.text + text = walker.text ? `declare namespace ts.server.protocol {\n${walker.text}}` : ""; if (walker.removedTypes) { @@ -52,7 +56,7 @@ class DeclarationsWalker { if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") { return; } - if (decl.kind === ts.SyntaxKind.EnumDeclaration) { + if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) { this.removedTypes.push(type); return; } @@ -91,7 +95,7 @@ class DeclarationsWalker { for (const type of heritageClauses[0].types) { this.processTypeOfNode(type); } - } + } break; } } @@ -110,7 +114,7 @@ class DeclarationsWalker { this.processType(type); } } - } + } } function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0b7405c7b6986..214091fc7415d 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2473,6 +2473,7 @@ namespace ts.server.protocol { System = "System", ES6 = "ES6", ES2015 = "ES2015", + ESNext = "ESNext" } export const enum ModuleResolutionKind { @@ -2490,5 +2491,8 @@ namespace ts.server.protocol { ES5 = "ES5", ES6 = "ES6", ES2015 = "ES2015", + ES2016 = "ES2016", + ES2017 = "ES2017", + ESNext = "ESNext" } } From 3e5de591236073098a142564c6ca86f6b5027bd0 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 18 Aug 2017 15:40:22 -0700 Subject: [PATCH 09/60] Update LKG --- lib/protocol.d.ts | 81 +++++++++++++++++++++++++++++++++++++++- lib/tsserver.js | 4 ++ lib/tsserverlibrary.d.ts | 4 ++ lib/tsserverlibrary.js | 4 ++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index 2f76e5f6115ea..e260845e853ce 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -1963,6 +1963,7 @@ declare namespace ts.server.protocol { System = "System", ES6 = "ES6", ES2015 = "ES2015", + ESNext = "ESNext", } const enum ModuleResolutionKind { Classic = "Classic", @@ -1977,6 +1978,9 @@ declare namespace ts.server.protocol { ES5 = "ES5", ES6 = "ES6", ES2015 = "ES2015", + ES2016 = "ES2016", + ES2017 = "ES2017", + ESNext = "ESNext", } } declare namespace ts.server.protocol { @@ -1998,6 +2002,81 @@ declare namespace ts.server.protocol { position: number; } + enum HighlightSpanKind { + none = "none", + definition = "definition", + reference = "reference", + writtenReference = "writtenReference", + } + + enum ScriptElementKind { + unknown = "", + warning = "warning", + /** predefined type (void) or keyword (class) */ + keyword = "keyword", + /** top level script node */ + scriptElement = "script", + /** module foo {} */ + moduleElement = "module", + /** class X {} */ + classElement = "class", + /** var x = class X {} */ + localClassElement = "local class", + /** interface Y {} */ + interfaceElement = "interface", + /** type T = ... */ + typeElement = "type", + /** enum E */ + enumElement = "enum", + enumMemberElement = "enum member", + /** + * Inside module and script only + * const v = .. + */ + variableElement = "var", + /** Inside function */ + localVariableElement = "local var", + /** + * Inside module and script only + * function f() { } + */ + functionElement = "function", + /** Inside function */ + localFunctionElement = "local function", + /** class X { [public|private]* foo() {} } */ + memberFunctionElement = "method", + /** class X { [public|private]* [get|set] foo:number; } */ + memberGetAccessorElement = "getter", + memberSetAccessorElement = "setter", + /** + * class X { [public|private]* foo:number; } + * interface Y { foo:number; } + */ + memberVariableElement = "property", + /** class X { constructor() { } } */ + constructorImplementationElement = "constructor", + /** interface Y { ():number; } */ + callSignatureElement = "call", + /** interface Y { []:number; } */ + indexSignatureElement = "index", + /** interface Y { new():Y; } */ + constructSignatureElement = "construct", + /** function foo(*Y*: string) */ + parameterElement = "parameter", + typeParameterElement = "type parameter", + primitiveType = "primitive type", + label = "label", + alias = "alias", + constElement = "const", + letElement = "let", + directory = "directory", + externalModuleName = "external module name", + /** + * + */ + jsxAttribute = "JSX attribute", + } + interface TypeAcquisition { enableAutoDiscovery?: boolean; enable?: boolean; @@ -2033,8 +2112,6 @@ declare namespace ts.server.protocol { } declare namespace ts { // these types are empty stubs for types from services and should not be used directly - export type HighlightSpanKind = never; - export type ScriptElementKind = never; export type ScriptKind = never; export type IndentStyle = never; export type JsxEmit = never; diff --git a/lib/tsserver.js b/lib/tsserver.js index b9bdd21b2d95e..29157d2fd8683 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -77866,6 +77866,7 @@ var ts; ModuleKind["System"] = "System"; ModuleKind["ES6"] = "ES6"; ModuleKind["ES2015"] = "ES2015"; + ModuleKind["ESNext"] = "ESNext"; })(ModuleKind = protocol.ModuleKind || (protocol.ModuleKind = {})); var ModuleResolutionKind; (function (ModuleResolutionKind) { @@ -77883,6 +77884,9 @@ var ts; ScriptTarget["ES5"] = "ES5"; ScriptTarget["ES6"] = "ES6"; ScriptTarget["ES2015"] = "ES2015"; + ScriptTarget["ES2016"] = "ES2016"; + ScriptTarget["ES2017"] = "ES2017"; + ScriptTarget["ESNext"] = "ESNext"; })(ScriptTarget = protocol.ScriptTarget || (protocol.ScriptTarget = {})); })(protocol = server.protocol || (server.protocol = {})); })(server = ts.server || (ts.server = {})); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index d43f0e03bfff5..a51e9e77838a9 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -4730,6 +4730,7 @@ declare namespace ts.server.protocol { System = "System", ES6 = "ES6", ES2015 = "ES2015", + ESNext = "ESNext", } enum ModuleResolutionKind { Classic = "Classic", @@ -4744,6 +4745,9 @@ declare namespace ts.server.protocol { ES5 = "ES5", ES6 = "ES6", ES2015 = "ES2015", + ES2016 = "ES2016", + ES2017 = "ES2017", + ESNext = "ESNext", } } declare namespace ts.server { diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 9e95700ac6a61..164733f4e69ba 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -77209,6 +77209,7 @@ var ts; ModuleKind["System"] = "System"; ModuleKind["ES6"] = "ES6"; ModuleKind["ES2015"] = "ES2015"; + ModuleKind["ESNext"] = "ESNext"; })(ModuleKind = protocol.ModuleKind || (protocol.ModuleKind = {})); var ModuleResolutionKind; (function (ModuleResolutionKind) { @@ -77226,6 +77227,9 @@ var ts; ScriptTarget["ES5"] = "ES5"; ScriptTarget["ES6"] = "ES6"; ScriptTarget["ES2015"] = "ES2015"; + ScriptTarget["ES2016"] = "ES2016"; + ScriptTarget["ES2017"] = "ES2017"; + ScriptTarget["ESNext"] = "ESNext"; })(ScriptTarget = protocol.ScriptTarget || (protocol.ScriptTarget = {})); })(protocol = server.protocol || (server.protocol = {})); })(server = ts.server || (ts.server = {})); From 34e42097e4c23b9c3e99561586830ff43e4c6ad8 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 23 Aug 2017 10:03:46 -0700 Subject: [PATCH 10/60] Allow use before declaration for export= assignments (#17967) (#17972) * Allow use before declaration for export= assignments (#17967) * Add release-2.5 to covered branches --- .travis.yml | 1 + src/compiler/checker.ts | 7 ++++++- .../exportAssignmentOfGenericType1.errors.txt | 17 --------------- .../reference/exportImport.errors.txt | 21 ------------------- ...eExportAssignmentOfGenericClass.errors.txt | 20 ------------------ 5 files changed, 7 insertions(+), 59 deletions(-) delete mode 100644 tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt delete mode 100644 tests/baselines/reference/exportImport.errors.txt delete mode 100644 tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt diff --git a/.travis.yml b/.travis.yml index 4a99aaf2237fd..27b14739d8b10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ matrix: branches: only: - master + - release-2.5 install: - npm uninstall typescript --no-save diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 15fd97ca5ba8d..89e718e48cc59 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -791,12 +791,17 @@ namespace ts { // 2. inside a function // 3. inside an instance property initializer, a reference to a non-instance property // 4. inside a static property initializer, a reference to a static method in the same class + // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ) // or if usage is in a type context: // 1. inside a type query (typeof in type position) - if (usage.parent.kind === SyntaxKind.ExportSpecifier) { + if (usage.parent.kind === SyntaxKind.ExportSpecifier || (usage.parent.kind === SyntaxKind.ExportAssignment && (usage.parent as ExportAssignment).isExportEquals)) { // export specifiers do not use the variable, they only make it available for use return true; } + // When resolving symbols for exports, the `usage` location passed in can be the export site directly + if (usage.kind === SyntaxKind.ExportAssignment && (usage as ExportAssignment).isExportEquals) { + return true; + } const container = getEnclosingBlockScopeContainer(declaration); return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container); diff --git a/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt b/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt deleted file mode 100644 index e484d4096bb78..0000000000000 --- a/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -tests/cases/compiler/exportAssignmentOfGenericType1_0.ts(1,10): error TS2449: Class 'T' used before its declaration. - - -==== tests/cases/compiler/exportAssignmentOfGenericType1_1.ts (0 errors) ==== - /// - import q = require("exportAssignmentOfGenericType1_0"); - - class M extends q { } - var m: M; - var r: string = m.foo; - -==== tests/cases/compiler/exportAssignmentOfGenericType1_0.ts (1 errors) ==== - export = T; - ~ -!!! error TS2449: Class 'T' used before its declaration. - class T { foo: X; } - \ No newline at end of file diff --git a/tests/baselines/reference/exportImport.errors.txt b/tests/baselines/reference/exportImport.errors.txt deleted file mode 100644 index 4f397d54a557d..0000000000000 --- a/tests/baselines/reference/exportImport.errors.txt +++ /dev/null @@ -1,21 +0,0 @@ -tests/cases/compiler/w1.ts(1,1): error TS2449: Class 'Widget1' used before its declaration. -tests/cases/compiler/w1.ts(1,10): error TS2449: Class 'Widget1' used before its declaration. - - -==== tests/cases/compiler/consumer.ts (0 errors) ==== - import e = require('./exporter'); - - export function w(): e.w { // Should be OK - return new e.w(); - } -==== tests/cases/compiler/w1.ts (2 errors) ==== - export = Widget1 - ~~~~~~~~~~~~~~~~ -!!! error TS2449: Class 'Widget1' used before its declaration. - ~~~~~~~ -!!! error TS2449: Class 'Widget1' used before its declaration. - class Widget1 { name = 'one'; } - -==== tests/cases/compiler/exporter.ts (0 errors) ==== - export import w = require('./w1'); - \ No newline at end of file diff --git a/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt b/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt deleted file mode 100644 index 2945950068a42..0000000000000 --- a/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts(1,1): error TS2449: Class 'Foo' used before its declaration. -tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts(1,10): error TS2449: Class 'Foo' used before its declaration. - - -==== tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_1.ts (0 errors) ==== - import Foo = require("./privacyCheckExternalModuleExportAssignmentOfGenericClass_0"); - export = Bar; - interface Bar { - foo: Foo; - } -==== tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts (2 errors) ==== - export = Foo; - ~~~~~~~~~~~~~ -!!! error TS2449: Class 'Foo' used before its declaration. - ~~~ -!!! error TS2449: Class 'Foo' used before its declaration. - class Foo { - constructor(public a: A) { } - } - \ No newline at end of file From 1420fbc2d4225d00511b1953ed37699957700ebf Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 23 Aug 2017 12:35:34 -0700 Subject: [PATCH 11/60] Bind logger function before using (#17983) * Bind logger function before using * Use lambda isntead of bind --- src/server/typingsInstaller/typingsInstaller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index df2b6916e4bc0..f005ec7de8fc4 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -149,7 +149,7 @@ namespace ts.server.typingsInstaller { } const discoverTypingsResult = JsTyping.discoverTypings( this.installTypingHost, - this.log.isEnabled() ? this.log.writeLine : undefined, + this.log.isEnabled() ? (s => this.log.writeLine(s)) : undefined, req.fileNames, req.projectRootPath, this.safeList, From 6da73b05f936a03a93d178b20726545cc915d9af Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 24 Aug 2017 11:03:43 -0700 Subject: [PATCH 12/60] Port #17771 to release-2.5 (#18018) * No contextual return type when type is circular * Add regression test --- src/compiler/checker.ts | 6 ++++- .../reference/circularContextualReturnType.js | 18 +++++++++++++++ .../circularContextualReturnType.symbols | 19 +++++++++++++++ .../circularContextualReturnType.types | 23 +++++++++++++++++++ .../compiler/circularContextualReturnType.ts | 9 ++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/circularContextualReturnType.js create mode 100644 tests/baselines/reference/circularContextualReturnType.symbols create mode 100644 tests/baselines/reference/circularContextualReturnType.types create mode 100644 tests/cases/compiler/circularContextualReturnType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 89e718e48cc59..4efbbae2d225f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6584,6 +6584,10 @@ namespace ts { return signature.resolvedReturnType; } + function isResolvingReturnTypeOfSignature(signature: Signature) { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0; + } + function getRestTypeOfSignature(signature: Signature): Type { if (signature.hasRestParameter) { const type = getTypeOfSymbol(lastOrUndefined(signature.parameters)); @@ -12957,7 +12961,7 @@ namespace ts { // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature // and that call signature is non-generic, return statements are contextually typed by the return type of the signature const signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); - if (signature) { + if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } diff --git a/tests/baselines/reference/circularContextualReturnType.js b/tests/baselines/reference/circularContextualReturnType.js new file mode 100644 index 0000000000000..d68f25494a89c --- /dev/null +++ b/tests/baselines/reference/circularContextualReturnType.js @@ -0,0 +1,18 @@ +//// [circularContextualReturnType.ts] +// Repro from #17711 + +Object.freeze({ + foo() { + return Object.freeze('a'); + }, +}); + + +//// [circularContextualReturnType.js] +"use strict"; +// Repro from #17711 +Object.freeze({ + foo: function () { + return Object.freeze('a'); + } +}); diff --git a/tests/baselines/reference/circularContextualReturnType.symbols b/tests/baselines/reference/circularContextualReturnType.symbols new file mode 100644 index 0000000000000..d0e81a6b33d35 --- /dev/null +++ b/tests/baselines/reference/circularContextualReturnType.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/circularContextualReturnType.ts === +// Repro from #17711 + +Object.freeze({ +>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + foo() { +>foo : Symbol(foo, Decl(circularContextualReturnType.ts, 2, 15)) + + return Object.freeze('a'); +>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + }, +}); + diff --git a/tests/baselines/reference/circularContextualReturnType.types b/tests/baselines/reference/circularContextualReturnType.types new file mode 100644 index 0000000000000..d32640d2cd970 --- /dev/null +++ b/tests/baselines/reference/circularContextualReturnType.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/circularContextualReturnType.ts === +// Repro from #17711 + +Object.freeze({ +>Object.freeze({ foo() { return Object.freeze('a'); },}) : Readonly<{ foo(): string; }> +>Object.freeze : { (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } +>Object : ObjectConstructor +>freeze : { (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } +>{ foo() { return Object.freeze('a'); },} : { foo(): string; } + + foo() { +>foo : () => string + + return Object.freeze('a'); +>Object.freeze('a') : string +>Object.freeze : { (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } +>Object : ObjectConstructor +>freeze : { (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } +>'a' : "a" + + }, +}); + diff --git a/tests/cases/compiler/circularContextualReturnType.ts b/tests/cases/compiler/circularContextualReturnType.ts new file mode 100644 index 0000000000000..1b356aff160de --- /dev/null +++ b/tests/cases/compiler/circularContextualReturnType.ts @@ -0,0 +1,9 @@ +// @strict: true + +// Repro from #17711 + +Object.freeze({ + foo() { + return Object.freeze('a'); + }, +}); From 952e9cae7020a5d27786c5f9d3cafd8c7617402c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 17 Aug 2017 17:32:06 -0700 Subject: [PATCH 13/60] Remove debug assertions due to invalid syntax in generators transform --- src/compiler/transformers/generators.ts | 76 +++++++++++-------- ...invalidContinueInDownlevelAsync.errors.txt | 17 +++++ .../invalidContinueInDownlevelAsync.js | 63 +++++++++++++++ .../invalidContinueInDownlevelAsync.ts | 8 ++ 4 files changed, 131 insertions(+), 33 deletions(-) create mode 100644 tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt create mode 100644 tests/baselines/reference/invalidContinueInDownlevelAsync.js create mode 100644 tests/cases/compiler/invalidContinueInDownlevelAsync.ts diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index f45147b526c70..20195adeef47b 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1639,8 +1639,13 @@ namespace ts { function transformAndEmitContinueStatement(node: ContinueStatement): void { const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined); - Debug.assert(label > 0, "Expected continue statment to point to a valid Label."); - emitBreak(label, /*location*/ node); + if (label > 0) { + emitBreak(label, /*location*/ node); + } + else { + // invalid continue without a containing loop. Leave the node as is, per #17875. + emitStatement(node); + } } function visitContinueStatement(node: ContinueStatement): Statement { @@ -1656,8 +1661,13 @@ namespace ts { function transformAndEmitBreakStatement(node: BreakStatement): void { const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined); - Debug.assert(label > 0, "Expected break statment to point to a valid Label."); - emitBreak(label, /*location*/ node); + if (label > 0) { + emitBreak(label, /*location*/ node); + } + else { + // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875. + emitStatement(node); + } } function visitBreakStatement(node: BreakStatement): Statement { @@ -2351,27 +2361,27 @@ namespace ts { * @param labelText An optional name of a containing labeled statement. */ function findBreakTarget(labelText?: string): Label { - Debug.assert(blocks !== undefined); - if (labelText) { - for (let i = blockStack.length - 1; i >= 0; i--) { - const block = blockStack[i]; - if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { - return block.breakLabel; - } - else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.breakLabel; + if (blockStack) { + if (labelText) { + for (let i = blockStack.length - 1; i >= 0; i--) { + const block = blockStack[i]; + if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { + return block.breakLabel; + } + else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.breakLabel; + } } } - } - else { - for (let i = blockStack.length - 1; i >= 0; i--) { - const block = blockStack[i]; - if (supportsUnlabeledBreak(block)) { - return block.breakLabel; + else { + for (let i = blockStack.length - 1; i >= 0; i--) { + const block = blockStack[i]; + if (supportsUnlabeledBreak(block)) { + return block.breakLabel; + } } } } - return 0; } @@ -2381,24 +2391,24 @@ namespace ts { * @param labelText An optional name of a containing labeled statement. */ function findContinueTarget(labelText?: string): Label { - Debug.assert(blocks !== undefined); - if (labelText) { - for (let i = blockStack.length - 1; i >= 0; i--) { - const block = blockStack[i]; - if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.continueLabel; + if (blockStack) { + if (labelText) { + for (let i = blockStack.length - 1; i >= 0; i--) { + const block = blockStack[i]; + if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.continueLabel; + } } } - } - else { - for (let i = blockStack.length - 1; i >= 0; i--) { - const block = blockStack[i]; - if (supportsUnlabeledContinue(block)) { - return block.continueLabel; + else { + for (let i = blockStack.length - 1; i >= 0; i--) { + const block = blockStack[i]; + if (supportsUnlabeledContinue(block)) { + return block.continueLabel; + } } } } - return 0; } diff --git a/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt b/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt new file mode 100644 index 0000000000000..ffdfee20090d5 --- /dev/null +++ b/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/invalidContinueInDownlevelAsync.ts(3,9): error TS1107: Jump target cannot cross function boundary. +tests/cases/compiler/invalidContinueInDownlevelAsync.ts(6,9): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/invalidContinueInDownlevelAsync.ts (2 errors) ==== + async function func() { + if (true) { + continue; + ~~~~~~~~~ +!!! error TS1107: Jump target cannot cross function boundary. + } + else { + await 1; + ~~~~~ +!!! error TS7027: Unreachable code detected. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/invalidContinueInDownlevelAsync.js b/tests/baselines/reference/invalidContinueInDownlevelAsync.js new file mode 100644 index 0000000000000..69e5e76e442e7 --- /dev/null +++ b/tests/baselines/reference/invalidContinueInDownlevelAsync.js @@ -0,0 +1,63 @@ +//// [invalidContinueInDownlevelAsync.ts] +async function func() { + if (true) { + continue; + } + else { + await 1; + } +} + +//// [invalidContinueInDownlevelAsync.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +function func() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!true) return [3 /*break*/, 1]; + continue; + return [3 /*break*/, 3]; + case 1: return [4 /*yield*/, 1]; + case 2: + _a.sent(); + _a.label = 3; + case 3: return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/cases/compiler/invalidContinueInDownlevelAsync.ts b/tests/cases/compiler/invalidContinueInDownlevelAsync.ts new file mode 100644 index 0000000000000..bdf476c80338e --- /dev/null +++ b/tests/cases/compiler/invalidContinueInDownlevelAsync.ts @@ -0,0 +1,8 @@ +async function func() { + if (true) { + continue; + } + else { + await 1; + } +} \ No newline at end of file From 80601fccb5656e2a69479260b5fd1ed31aa7ace1 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 23 Aug 2017 17:09:47 -0700 Subject: [PATCH 14/60] Fix crash when exporting class without name --- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/utilities.ts | 2 +- .../reference/exportClassWithoutName.errors.txt | 8 ++++++++ tests/baselines/reference/exportClassWithoutName.js | 10 ++++++++++ tests/cases/compiler/exportClassWithoutName.ts | 4 ++++ 5 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/exportClassWithoutName.errors.txt create mode 100644 tests/baselines/reference/exportClassWithoutName.js create mode 100644 tests/cases/compiler/exportClassWithoutName.ts diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 2c3133de6f565..a0f593e511138 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1204,7 +1204,7 @@ namespace ts { } if (hasModifier(decl, ModifierFlags.Export)) { - const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : decl.name; + const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl); statements = appendExportStatement(statements, exportName, getLocalName(decl), /*location*/ decl); } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index be99df62b67a7..f641ee49faf67 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -124,7 +124,7 @@ namespace ts { else { // export class x { } const name = (node).name; - if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true); exportedNames = append(exportedNames, name); diff --git a/tests/baselines/reference/exportClassWithoutName.errors.txt b/tests/baselines/reference/exportClassWithoutName.errors.txt new file mode 100644 index 0000000000000..448a1b2bb03d1 --- /dev/null +++ b/tests/baselines/reference/exportClassWithoutName.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/exportClassWithoutName.ts(1,1): error TS1211: A class declaration without the 'default' modifier must have a name. + + +==== tests/cases/compiler/exportClassWithoutName.ts (1 errors) ==== + export class { + ~~~~~~ +!!! error TS1211: A class declaration without the 'default' modifier must have a name. + } \ No newline at end of file diff --git a/tests/baselines/reference/exportClassWithoutName.js b/tests/baselines/reference/exportClassWithoutName.js new file mode 100644 index 0000000000000..45b4301a81232 --- /dev/null +++ b/tests/baselines/reference/exportClassWithoutName.js @@ -0,0 +1,10 @@ +//// [exportClassWithoutName.ts] +export class { +} + +//// [exportClassWithoutName.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class default_1 { +} +exports.default_1 = default_1; diff --git a/tests/cases/compiler/exportClassWithoutName.ts b/tests/cases/compiler/exportClassWithoutName.ts new file mode 100644 index 0000000000000..a83ca9758c7ca --- /dev/null +++ b/tests/cases/compiler/exportClassWithoutName.ts @@ -0,0 +1,4 @@ +//@module: commonjs +//@target: es2015 +export class { +} \ No newline at end of file From 09e7e88a1930d080c1147e0a688aeeda324775c3 Mon Sep 17 00:00:00 2001 From: Jan Melcher Date: Tue, 27 Jun 2017 17:22:39 +0200 Subject: [PATCH 15/60] Add missing visitNode call to object literal members Object literal elements that are neither spread elements, nor property assignments would not have visitNode called on them. Therefore, the esnext transformer would not be called on them and their children. Fixes #16765. --- src/compiler/transformers/esnext.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 8d71016b0519c..3bdcc9e9ee722 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -158,8 +158,8 @@ namespace ts { return visitEachChild(node, visitor, context); } - function chunkObjectLiteralElements(elements: ReadonlyArray): Expression[] { - let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[]; + function chunkObjectLiteralElements(elements: ReadonlyArray): Expression[] { + let chunkObject: ObjectLiteralElementLike[]; const objects: Expression[] = []; for (const e of elements) { if (e.kind === SyntaxKind.SpreadAssignment) { @@ -179,7 +179,7 @@ namespace ts { chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression))); } else { - chunkObject.push(e as ShorthandPropertyAssignment); + chunkObject.push(visitNode(e, visitor, isObjectLiteralElementLike)); } } } From d48ac07e146f2c364a103bf439f810a66ac14ae2 Mon Sep 17 00:00:00 2001 From: Jan Melcher Date: Tue, 27 Jun 2017 18:03:16 +0200 Subject: [PATCH 16/60] Add test case for nested object spread / methods See #16765. --- ...preadWithinMethodWithinObjectWithSpread.js | 26 +++++++++++++++++ ...WithinMethodWithinObjectWithSpread.symbols | 24 +++++++++++++++ ...adWithinMethodWithinObjectWithSpread.types | 29 +++++++++++++++++++ ...preadWithinMethodWithinObjectWithSpread.ts | 10 +++++++ 4 files changed, 89 insertions(+) create mode 100644 tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js create mode 100644 tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols create mode 100644 tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types create mode 100644 tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts diff --git a/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js new file mode 100644 index 0000000000000..e16695b655efa --- /dev/null +++ b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.js @@ -0,0 +1,26 @@ +//// [objectSpreadWithinMethodWithinObjectWithSpread.ts] +const obj = {}; +const a = { + ...obj, + prop() { + return { + ...obj, + metadata: 213 + }; + } +}; + + +//// [objectSpreadWithinMethodWithinObjectWithSpread.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var obj = {}; +var a = __assign({}, obj, { prop: function () { + return __assign({}, obj, { metadata: 213 }); + } }); diff --git a/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols new file mode 100644 index 0000000000000..181cacd5e07ef --- /dev/null +++ b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts === +const obj = {}; +>obj : Symbol(obj, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 0, 5)) + +const a = { +>a : Symbol(a, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 1, 5)) + + ...obj, +>obj : Symbol(obj, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 0, 5)) + + prop() { +>prop : Symbol(prop, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 2, 11)) + + return { + ...obj, +>obj : Symbol(obj, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 0, 5)) + + metadata: 213 +>metadata : Symbol(metadata, Decl(objectSpreadWithinMethodWithinObjectWithSpread.ts, 5, 19)) + + }; + } +}; + diff --git a/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types new file mode 100644 index 0000000000000..351aa0c374b1a --- /dev/null +++ b/tests/baselines/reference/objectSpreadWithinMethodWithinObjectWithSpread.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts === +const obj = {}; +>obj : {} +>{} : {} + +const a = { +>a : { prop(): { metadata: number; }; } +>{ ...obj, prop() { return { ...obj, metadata: 213 }; }} : { prop(): { metadata: number; }; } + + ...obj, +>obj : {} + + prop() { +>prop : () => { metadata: number; } + + return { +>{ ...obj, metadata: 213 } : { metadata: number; } + + ...obj, +>obj : {} + + metadata: 213 +>metadata : number +>213 : 213 + + }; + } +}; + diff --git a/tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts b/tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts new file mode 100644 index 0000000000000..4d1663bb4568b --- /dev/null +++ b/tests/cases/compiler/objectSpreadWithinMethodWithinObjectWithSpread.ts @@ -0,0 +1,10 @@ +const obj = {}; +const a = { + ...obj, + prop() { + return { + ...obj, + metadata: 213 + }; + } +}; From 13eeb34e578759af618e301e2e368e410463ba0a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 24 Aug 2017 11:31:21 -0700 Subject: [PATCH 17/60] Ignore scripts for types packages (#17969) --- src/server/typingsInstaller/nodeTypingsInstaller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index de23b2649a6b6..f80b7a70df608 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -102,7 +102,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`); } - this.execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); + this.execSync(`${this.npmPath} install --ignore-scripts ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); if (this.log.isEnabled()) { this.log.writeLine(`Updated ${TypesRegistryPackageName} npm package`); } @@ -152,7 +152,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(args)}'.`); } - const command = `${this.npmPath} install ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`; + const command = `${this.npmPath} install --ignore-scripts ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`; const start = Date.now(); let stdout: Buffer; let stderr: Buffer; From ec8f5cfe3fe8da20e4307c7e50b8f31b90a1a298 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 21 Jun 2017 18:20:46 -0700 Subject: [PATCH 18/60] Follow symbol through commonjs require for inferred class type --- src/compiler/checker.ts | 31 ++++++++--- .../reference/constructorFunctions2.symbols | 41 ++++++++++++++ .../reference/constructorFunctions2.types | 55 +++++++++++++++++++ .../salsa/constructorFunctions2.ts | 18 ++++++ 4 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/constructorFunctions2.symbols create mode 100644 tests/baselines/reference/constructorFunctions2.types create mode 100644 tests/cases/conformance/salsa/constructorFunctions2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4efbbae2d225f..e51ce5499e22d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16327,8 +16327,8 @@ namespace ts { * Indicates whether a declaration can be treated as a constructor in a JavaScript * file. */ - function isJavaScriptConstructor(node: Declaration): boolean { - if (isInJavaScriptFile(node)) { + function isJavaScriptConstructor(node: Declaration | undefined): boolean { + if (node && isInJavaScriptFile(node)) { // If the node has a @class tag, treat it like a constructor. if (getJSDocClassTag(node)) return true; @@ -16343,6 +16343,21 @@ namespace ts { return false; } + function getJavaScriptClassType(symbol: Symbol): Type | undefined { + if (symbol && isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = getSymbolOfNode((symbol.valueDeclaration).initializer); + } + if (isJavaScriptConstructor(symbol.valueDeclaration)) { + return getInferredClassType(symbol); + } + if (symbol.flags & SymbolFlags.Variable) { + const valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + return getInferredClassType(valueType.symbol); + } + } + } + function getInferredClassType(symbol: Symbol) { const links = getSymbolLinks(symbol); if (!links.inferredClassType) { @@ -16386,16 +16401,14 @@ namespace ts { // in a JS file // Note:JS inferred classes might come from a variable declaration instead of a function declaration. // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. - let funcSymbol = node.expression.kind === SyntaxKind.Identifier ? + const funcSymbol = node.expression.kind === SyntaxKind.Identifier ? getResolvedSymbol(node.expression as Identifier) : checkExpression(node.expression).symbol; - if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) { - funcSymbol = getSymbolOfNode((funcSymbol.valueDeclaration).initializer); - } - if (funcSymbol && funcSymbol.flags & SymbolFlags.Function && (funcSymbol.members || getJSDocClassTag(funcSymbol.valueDeclaration))) { - return getInferredClassType(funcSymbol); + const type = funcSymbol && getJavaScriptClassType(funcSymbol); + if (type) { + return type; } - else if (noImplicitAny) { + if (noImplicitAny) { error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; diff --git a/tests/baselines/reference/constructorFunctions2.symbols b/tests/baselines/reference/constructorFunctions2.symbols new file mode 100644 index 0000000000000..1046aa32e9a62 --- /dev/null +++ b/tests/baselines/reference/constructorFunctions2.symbols @@ -0,0 +1,41 @@ +=== tests/cases/conformance/salsa/node.d.ts === +declare function require(id: string): any; +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>id : Symbol(id, Decl(node.d.ts, 0, 25)) + +declare var module: any, exports: any; +>module : Symbol(module, Decl(node.d.ts, 1, 11)) +>exports : Symbol(exports, Decl(node.d.ts, 1, 24)) + +=== tests/cases/conformance/salsa/index.js === +const A = require("./other"); +>A : Symbol(A, Decl(index.js, 0, 5)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>"./other" : Symbol("tests/cases/conformance/salsa/other", Decl(other.js, 0, 0)) + +const a = new A().id; +>a : Symbol(a, Decl(index.js, 1, 5)) +>new A().id : Symbol(A.id, Decl(other.js, 0, 14)) +>A : Symbol(A, Decl(index.js, 0, 5)) +>id : Symbol(A.id, Decl(other.js, 0, 14)) + +const B = function() { this.id = 1; } +>B : Symbol(B, Decl(index.js, 3, 5)) +>id : Symbol(B.id, Decl(index.js, 3, 22)) + +const b = new B().id; +>b : Symbol(b, Decl(index.js, 4, 5)) +>new B().id : Symbol(B.id, Decl(index.js, 3, 22)) +>B : Symbol(B, Decl(index.js, 3, 5)) +>id : Symbol(B.id, Decl(index.js, 3, 22)) + +=== tests/cases/conformance/salsa/other.js === +function A() { this.id = 1; } +>A : Symbol(A, Decl(other.js, 0, 0)) +>id : Symbol(A.id, Decl(other.js, 0, 14)) + +module.exports = A; +>module : Symbol(export=, Decl(other.js, 0, 29)) +>exports : Symbol(export=, Decl(other.js, 0, 29)) +>A : Symbol(A, Decl(other.js, 0, 0)) + diff --git a/tests/baselines/reference/constructorFunctions2.types b/tests/baselines/reference/constructorFunctions2.types new file mode 100644 index 0000000000000..e96053b4f4901 --- /dev/null +++ b/tests/baselines/reference/constructorFunctions2.types @@ -0,0 +1,55 @@ +=== tests/cases/conformance/salsa/node.d.ts === +declare function require(id: string): any; +>require : (id: string) => any +>id : string + +declare var module: any, exports: any; +>module : any +>exports : any + +=== tests/cases/conformance/salsa/index.js === +const A = require("./other"); +>A : () => void +>require("./other") : () => void +>require : (id: string) => any +>"./other" : "./other" + +const a = new A().id; +>a : number +>new A().id : number +>new A() : { id: number; } +>A : () => void +>id : number + +const B = function() { this.id = 1; } +>B : () => void +>function() { this.id = 1; } : () => void +>this.id = 1 : 1 +>this.id : any +>this : any +>id : any +>1 : 1 + +const b = new B().id; +>b : number +>new B().id : number +>new B() : { id: number; } +>B : () => void +>id : number + +=== tests/cases/conformance/salsa/other.js === +function A() { this.id = 1; } +>A : () => void +>this.id = 1 : 1 +>this.id : any +>this : any +>id : any +>1 : 1 + +module.exports = A; +>module.exports = A : () => void +>module.exports : any +>module : any +>exports : any +>A : () => void + diff --git a/tests/cases/conformance/salsa/constructorFunctions2.ts b/tests/cases/conformance/salsa/constructorFunctions2.ts new file mode 100644 index 0000000000000..13a6e7b9a3a85 --- /dev/null +++ b/tests/cases/conformance/salsa/constructorFunctions2.ts @@ -0,0 +1,18 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @module: commonjs +// @filename: node.d.ts +declare function require(id: string): any; +declare var module: any, exports: any; + +// @filename: index.js +const A = require("./other"); +const a = new A().id; + +const B = function() { this.id = 1; } +const b = new B().id; + +// @filename: other.js +function A() { this.id = 1; } +module.exports = A; \ No newline at end of file From 9bb191585123618e0319716b9ea51c7dd49a2f4a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 11 Aug 2017 16:15:28 -0700 Subject: [PATCH 19/60] PR 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 e51ce5499e22d..6f84239061fb3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16344,7 +16344,7 @@ namespace ts { } function getJavaScriptClassType(symbol: Symbol): Type | undefined { - if (symbol && isDeclarationOfFunctionOrClassExpression(symbol)) { + if (isDeclarationOfFunctionOrClassExpression(symbol)) { symbol = getSymbolOfNode((symbol.valueDeclaration).initializer); } if (isJavaScriptConstructor(symbol.valueDeclaration)) { From 01b7df68554bd7f0dff07946a86abf8f8938b57e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 24 Aug 2017 13:40:20 -0700 Subject: [PATCH 20/60] Switch to arrow for ts class wrapper IIFE --- src/compiler/factory.ts | 43 +++++++++++++- src/compiler/transformers/es2015.ts | 59 ++----------------- src/compiler/transformers/ts.ts | 5 +- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 6 +- .../reference/decoratorOnClassMethod11.js | 1 + .../reference/decoratorOnClassMethod12.js | 1 + .../inferringClassMembersFromAssignments.js | 1 + tests/baselines/reference/superAccess2.js | 1 + ...thisInArrowFunctionInStaticInitializer1.js | 1 + .../reference/thisInConstructorParameter2.js | 1 + .../reference/thisInInvalidContexts.js | 1 + .../thisInInvalidContextsExternalModule.js | 1 + .../reference/thisInOuterClassBody.js | 1 + .../reference/typeOfThisInStaticMembers2.js | 1 + 15 files changed, 64 insertions(+), 60 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index daec1bce1e8b5..04e6b5553e894 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2372,6 +2372,24 @@ namespace ts { ); } + export function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression; + export function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + export function createImmediatelyInvokedArrowFunction(statements: Statement[], param?: ParameterDeclaration, paramValue?: Expression) { + return createCall( + createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ param ? [param] : [], + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, + createBlock(statements, /*multiLine*/ true) + ), + /*typeArguments*/ undefined, + /*argumentsArray*/ paramValue ? [paramValue] : [] + ); + } + + export function createComma(left: Expression, right: Expression) { return createBinary(left, SyntaxKind.CommaToken, right); } @@ -4040,8 +4058,31 @@ namespace ts { } } + /** + * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. + * + * A parenthesized expression can be ignored when all of the following are true: + * + * - It's `pos` and `end` are not -1 + * - It does not have a custom source map range + * - It does not have a custom comment range + * - It does not have synthetic leading or trailing comments + * + * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around + * the expression to maintain precedence, a new parenthesized expression should be created automatically when + * the containing expression is created/updated. + */ + function isIgnorableParen(node: Expression) { + return node.kind === SyntaxKind.ParenthesizedExpression + && nodeIsSynthesized(node) + && nodeIsSynthesized(getSourceMapRange(node)) + && nodeIsSynthesized(getCommentRange(node)) + && !some(getSyntheticLeadingComments(node)) + && !some(getSyntheticTrailingComments(node)); + } + export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression { - if (outerExpression && isOuterExpression(outerExpression, kinds)) { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression( outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index ce907d49bee8d..e9c84be51766a 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -339,64 +339,12 @@ namespace ts { && !(node).expression; } - function isClassLikeVariableStatement(node: Node) { - if (!isVariableStatement(node)) return false; - const variable = singleOrUndefined((node).declarationList.declarations); - return variable - && variable.initializer - && isIdentifier(variable.name) - && (isClassLike(variable.initializer) - || (isAssignmentExpression(variable.initializer) - && isIdentifier(variable.initializer.left) - && isClassLike(variable.initializer.right))); - } - - function isTypeScriptClassWrapper(node: Node) { - const call = tryCast(node, isCallExpression); - if (!call || isParseTreeNode(call) || - some(call.typeArguments) || - some(call.arguments)) { - return false; - } - - const func = tryCast(skipOuterExpressions(call.expression), isFunctionExpression); - if (!func || isParseTreeNode(func) || - some(func.typeParameters) || - some(func.parameters) || - func.type || - !func.body) { - return false; - } - - const statements = func.body.statements; - if (statements.length < 2) { - return false; - } - - const firstStatement = statements[0]; - if (isParseTreeNode(firstStatement) || - !isClassLike(firstStatement) && - !isClassLikeVariableStatement(firstStatement)) { - return false; - } - - const lastStatement = elementAt(statements, -1); - const returnStatement = tryCast(isVariableStatement(lastStatement) ? elementAt(statements, -2) : lastStatement, isReturnStatement); - if (!returnStatement || - !returnStatement.expression || - !isIdentifier(skipOuterExpressions(returnStatement.expression))) { - return false; - } - - return true; - } - function shouldVisitNode(node: Node): boolean { return (node.transformFlags & TransformFlags.ContainsES2015) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block))) || (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)) - || isTypeScriptClassWrapper(node); + || (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0; } function visitor(node: Node): VisitResult { @@ -3308,13 +3256,14 @@ namespace ts { * @param node a CallExpression. */ function visitCallExpression(node: CallExpression) { - if (isTypeScriptClassWrapper(node)) { + if (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & TransformFlags.ES2015) { return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true); } + return updateCall( node, visitNode(node.expression, callExpressionVisitor, isExpression), @@ -3357,7 +3306,7 @@ namespace ts { // We skip any outer expressions in a number of places to get to the innermost // expression, but we will restore them later to preserve comments and source maps. - const body = cast(skipOuterExpressions(node.expression), isFunctionExpression).body; + const body = cast(cast(skipOuterExpressions(node.expression), isArrowFunction).body, isBlock); // The class statements are the statements generated by visiting the first statement of the // body (1), while all other statements are added to remainingStatements (2) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 4c679ea1eee84..71a3c7dcb7a0a 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -613,13 +613,16 @@ namespace ts { addRange(statements, context.endLexicalEnvironment()); + const iife = createImmediatelyInvokedArrowFunction(statements); + setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper); + const varStatement = createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList([ createVariableDeclaration( getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), /*type*/ undefined, - createImmediatelyInvokedFunctionExpression(statements) + iife ) ]) ); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e74529e0ea960..5a5724503c082 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4170,6 +4170,7 @@ namespace ts { HasEndOfDeclarationMarker = 1 << 22, // Declaration has an associated NotEmittedStatement to mark the end of the declaration Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable. NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions. + /*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform. } export interface EmitHelper { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c77d267471a06..25ba99cb15403 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2068,9 +2068,9 @@ namespace ts { || kind === SyntaxKind.SourceFile; } - export function nodeIsSynthesized(node: TextRange): boolean { - return positionIsSynthesized(node.pos) - || positionIsSynthesized(node.end); + export function nodeIsSynthesized(range: TextRange): boolean { + return positionIsSynthesized(range.pos) + || positionIsSynthesized(range.end); } export function getOriginalSourceFile(sourceFile: SourceFile) { diff --git a/tests/baselines/reference/decoratorOnClassMethod11.js b/tests/baselines/reference/decoratorOnClassMethod11.js index 2600681c64746..e29c4076c9154 100644 --- a/tests/baselines/reference/decoratorOnClassMethod11.js +++ b/tests/baselines/reference/decoratorOnClassMethod11.js @@ -17,6 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, }; var M; (function (M) { + var _this = this; var C = /** @class */ (function () { function C() { } diff --git a/tests/baselines/reference/decoratorOnClassMethod12.js b/tests/baselines/reference/decoratorOnClassMethod12.js index 494cb083a20f3..0063e0225bc44 100644 --- a/tests/baselines/reference/decoratorOnClassMethod12.js +++ b/tests/baselines/reference/decoratorOnClassMethod12.js @@ -28,6 +28,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, }; var M; (function (M) { + var _this = this; var S = /** @class */ (function () { function S() { } diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments.js b/tests/baselines/reference/inferringClassMembersFromAssignments.js index 3fa72bce2cf5b..90f87734b2e1e 100644 --- a/tests/baselines/reference/inferringClassMembersFromAssignments.js +++ b/tests/baselines/reference/inferringClassMembersFromAssignments.js @@ -124,6 +124,7 @@ var stringOrNumberOrUndefined = C.inStaticNestedArrowFunction; //// [output.js] +var _this = this; var C = /** @class */ (function () { function C() { var _this = this; diff --git a/tests/baselines/reference/superAccess2.js b/tests/baselines/reference/superAccess2.js index de755361a16ca..d3aac217e2229 100644 --- a/tests/baselines/reference/superAccess2.js +++ b/tests/baselines/reference/superAccess2.js @@ -35,6 +35,7 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); +var _this = this; var P = /** @class */ (function () { function P() { } diff --git a/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js b/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js index 97e958ace5ec1..2d58fd455ac4a 100644 --- a/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js +++ b/tests/baselines/reference/thisInArrowFunctionInStaticInitializer1.js @@ -9,6 +9,7 @@ class Vector { } //// [thisInArrowFunctionInStaticInitializer1.js] +var _this = this; function log(a) { } var Vector = /** @class */ (function () { function Vector() { diff --git a/tests/baselines/reference/thisInConstructorParameter2.js b/tests/baselines/reference/thisInConstructorParameter2.js index 6a27183800c2d..a5e4f4d8b5712 100644 --- a/tests/baselines/reference/thisInConstructorParameter2.js +++ b/tests/baselines/reference/thisInConstructorParameter2.js @@ -10,6 +10,7 @@ class P { } //// [thisInConstructorParameter2.js] +var _this = this; var P = /** @class */ (function () { function P(z, zz) { if (z === void 0) { z = this; } diff --git a/tests/baselines/reference/thisInInvalidContexts.js b/tests/baselines/reference/thisInInvalidContexts.js index 635eff25cf4a1..1e24cc4d9e2c2 100644 --- a/tests/baselines/reference/thisInInvalidContexts.js +++ b/tests/baselines/reference/thisInInvalidContexts.js @@ -59,6 +59,7 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); +var _this = this; //'this' in static member initializer var ErrClass1 = /** @class */ (function () { function ErrClass1() { diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index ea69a582730e3..daadace2cfa09 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -60,6 +60,7 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); +var _this = this; //'this' in static member initializer var ErrClass1 = /** @class */ (function () { function ErrClass1() { diff --git a/tests/baselines/reference/thisInOuterClassBody.js b/tests/baselines/reference/thisInOuterClassBody.js index 2b4e3a1aabdb6..d5bf689b49a13 100644 --- a/tests/baselines/reference/thisInOuterClassBody.js +++ b/tests/baselines/reference/thisInOuterClassBody.js @@ -21,6 +21,7 @@ class Foo { } //// [thisInOuterClassBody.js] +var _this = this; var Foo = /** @class */ (function () { function Foo() { this.x = this; diff --git a/tests/baselines/reference/typeOfThisInStaticMembers2.js b/tests/baselines/reference/typeOfThisInStaticMembers2.js index 72243cdd3e619..1cfec3a3fa1d6 100644 --- a/tests/baselines/reference/typeOfThisInStaticMembers2.js +++ b/tests/baselines/reference/typeOfThisInStaticMembers2.js @@ -8,6 +8,7 @@ class C2 { } //// [typeOfThisInStaticMembers2.js] +var _this = this; var C = /** @class */ (function () { function C() { } From 0851f6909e0c0ddca50fb8b62323845a3d5d1359 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 24 Aug 2017 15:06:06 -0700 Subject: [PATCH 21/60] Added additional test --- .../reference/asyncArrowInClassES5.js | 21 +++++++++++++++++++ .../reference/asyncArrowInClassES5.symbols | 12 +++++++++++ .../reference/asyncArrowInClassES5.types | 13 ++++++++++++ tests/cases/compiler/asyncArrowInClassES5.ts | 9 ++++++++ 4 files changed, 55 insertions(+) create mode 100644 tests/baselines/reference/asyncArrowInClassES5.js create mode 100644 tests/baselines/reference/asyncArrowInClassES5.symbols create mode 100644 tests/baselines/reference/asyncArrowInClassES5.types create mode 100644 tests/cases/compiler/asyncArrowInClassES5.ts diff --git a/tests/baselines/reference/asyncArrowInClassES5.js b/tests/baselines/reference/asyncArrowInClassES5.js new file mode 100644 index 0000000000000..f0204f7319bda --- /dev/null +++ b/tests/baselines/reference/asyncArrowInClassES5.js @@ -0,0 +1,21 @@ +//// [asyncArrowInClassES5.ts] +// https://github.com/Microsoft/TypeScript/issues/16924 +// Should capture `this` + +class Test { + static member = async (x: string) => { }; +} + + +//// [asyncArrowInClassES5.js] +// https://github.com/Microsoft/TypeScript/issues/16924 +// Should capture `this` +var _this = this; +var Test = /** @class */ (function () { + function Test() { + } + Test.member = function (x) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/]; + }); }); }; + return Test; +}()); diff --git a/tests/baselines/reference/asyncArrowInClassES5.symbols b/tests/baselines/reference/asyncArrowInClassES5.symbols new file mode 100644 index 0000000000000..a6cc9f75d6e3a --- /dev/null +++ b/tests/baselines/reference/asyncArrowInClassES5.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/asyncArrowInClassES5.ts === +// https://github.com/Microsoft/TypeScript/issues/16924 +// Should capture `this` + +class Test { +>Test : Symbol(Test, Decl(asyncArrowInClassES5.ts, 0, 0)) + + static member = async (x: string) => { }; +>member : Symbol(Test.member, Decl(asyncArrowInClassES5.ts, 3, 12)) +>x : Symbol(x, Decl(asyncArrowInClassES5.ts, 4, 27)) +} + diff --git a/tests/baselines/reference/asyncArrowInClassES5.types b/tests/baselines/reference/asyncArrowInClassES5.types new file mode 100644 index 0000000000000..8da6d5d2eaf26 --- /dev/null +++ b/tests/baselines/reference/asyncArrowInClassES5.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/asyncArrowInClassES5.ts === +// https://github.com/Microsoft/TypeScript/issues/16924 +// Should capture `this` + +class Test { +>Test : Test + + static member = async (x: string) => { }; +>member : (x: string) => Promise +>async (x: string) => { } : (x: string) => Promise +>x : string +} + diff --git a/tests/cases/compiler/asyncArrowInClassES5.ts b/tests/cases/compiler/asyncArrowInClassES5.ts new file mode 100644 index 0000000000000..2712372d35706 --- /dev/null +++ b/tests/cases/compiler/asyncArrowInClassES5.ts @@ -0,0 +1,9 @@ +// @noEmitHelpers: true +// @lib: es2015 +// @target: es5 +// https://github.com/Microsoft/TypeScript/issues/16924 +// Should capture `this` + +class Test { + static member = async (x: string) => { }; +} From 350c9f647bd533a8a90157b6f2b0a62c5a28c50c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 24 Aug 2017 17:59:45 -0700 Subject: [PATCH 22/60] Call dynamic import transform on expression used by export equal statement (#18028) (#18033) * Call dynamic import transform on expression used by export equal statement * Use Debug.fail --- src/compiler/transformers/module/module.ts | 46 +++++++++++-------- .../importCallExpressionInExportEqualsAMD.js | 22 +++++++++ ...ortCallExpressionInExportEqualsAMD.symbols | 10 ++++ ...mportCallExpressionInExportEqualsAMD.types | 14 ++++++ .../importCallExpressionInExportEqualsCJS.js | 18 ++++++++ ...ortCallExpressionInExportEqualsCJS.symbols | 10 ++++ ...mportCallExpressionInExportEqualsCJS.types | 14 ++++++ .../importCallExpressionInExportEqualsUMD.js | 39 ++++++++++++++++ ...ortCallExpressionInExportEqualsUMD.symbols | 10 ++++ ...mportCallExpressionInExportEqualsUMD.types | 14 ++++++ .../importCallExpressionInExportEqualsAMD.ts | 9 ++++ .../importCallExpressionInExportEqualsCJS.ts | 9 ++++ .../importCallExpressionInExportEqualsUMD.ts | 9 ++++ 13 files changed, 204 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsAMD.js create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsAMD.types create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsCJS.js create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsCJS.types create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsUMD.js create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols create mode 100644 tests/baselines/reference/importCallExpressionInExportEqualsUMD.types create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index a0f593e511138..23bae8714c854 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -430,26 +430,32 @@ namespace ts { */ function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) { if (currentModuleInfo.exportEquals) { - if (emitAsReturn) { - const statement = createReturn(currentModuleInfo.exportEquals.expression); - setTextRange(statement, currentModuleInfo.exportEquals); - setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments); - statements.push(statement); - } - else { - const statement = createStatement( - createAssignment( - createPropertyAccess( - createIdentifier("module"), - "exports" - ), - currentModuleInfo.exportEquals.expression - ) - ); + const expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression); + if (expressionResult) { + if (expressionResult instanceof Array) { + return Debug.fail("export= expression should never be replaced with multiple expressions!"); + } + if (emitAsReturn) { + const statement = createReturn(expressionResult); + setTextRange(statement, currentModuleInfo.exportEquals); + setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments); + statements.push(statement); + } + else { + const statement = createStatement( + createAssignment( + createPropertyAccess( + createIdentifier("module"), + "exports" + ), + expressionResult + ) + ); - setTextRange(statement, currentModuleInfo.exportEquals); - setEmitFlags(statement, EmitFlags.NoComments); - statements.push(statement); + setTextRange(statement, currentModuleInfo.exportEquals); + setEmitFlags(statement, EmitFlags.NoComments); + statements.push(statement); + } } } } @@ -497,7 +503,7 @@ namespace ts { } } - function importCallExpressionVisitor(node: Node): VisitResult { + function importCallExpressionVisitor(node: Expression): VisitResult { // This visitor does not need to descend into the tree if there is no dynamic import, // as export/import statements are only transformed at the top level of a file. if (!(node.transformFlags & TransformFlags.ContainsDynamicImport)) { diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js new file mode 100644 index 0000000000000..f2fda1fadd79f --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts] //// + +//// [something.ts] +export = 42; + +//// [index.ts] +export = async function() { + const something = await import("./something"); +}; + +//// [something.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + return 42; +}); +//// [index.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + return async function () { + const something = await new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); }); + }; +}); diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols new file mode 100644 index 0000000000000..cd8d7d3804190 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/dynamicImport/something.ts === +export = 42; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +export = async function() { + const something = await import("./something"); +>something : Symbol(something, Decl(index.ts, 1, 9)) +>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0)) + +}; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.types b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.types new file mode 100644 index 0000000000000..b590130d1cff5 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/dynamicImport/something.ts === +export = 42; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +export = async function() { +>async function() { const something = await import("./something");} : () => Promise + + const something = await import("./something"); +>something : 42 +>await import("./something") : 42 +>import("./something") : Promise<42> +>"./something" : "./something" + +}; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js new file mode 100644 index 0000000000000..5d7e28161164d --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts] //// + +//// [something.ts] +export = 42; + +//// [index.ts] +export = async function() { + const something = await import("./something"); +}; + +//// [something.js] +"use strict"; +module.exports = 42; +//// [index.js] +"use strict"; +module.exports = async function () { + const something = await Promise.resolve().then(function () { return require("./something"); }); +}; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols new file mode 100644 index 0000000000000..cd8d7d3804190 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/dynamicImport/something.ts === +export = 42; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +export = async function() { + const something = await import("./something"); +>something : Symbol(something, Decl(index.ts, 1, 9)) +>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0)) + +}; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.types b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.types new file mode 100644 index 0000000000000..b590130d1cff5 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/dynamicImport/something.ts === +export = 42; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +export = async function() { +>async function() { const something = await import("./something");} : () => Promise + + const something = await import("./something"); +>something : 42 +>await import("./something") : 42 +>import("./something") : Promise<42> +>"./something" : "./something" + +}; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js new file mode 100644 index 0000000000000..e0c6e2a925fd7 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts] //// + +//// [something.ts] +export = 42; + +//// [index.ts] +export = async function() { + const something = await import("./something"); +}; + +//// [something.js] +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + return 42; +}); +//// [index.js] +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + var __syncRequire = typeof module === "object" && typeof module.exports === "object"; + return async function () { + const something = await (__syncRequire ? Promise.resolve().then(function () { return require("./something"); }) : new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); })); + }; +}); diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols new file mode 100644 index 0000000000000..cd8d7d3804190 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/dynamicImport/something.ts === +export = 42; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +export = async function() { + const something = await import("./something"); +>something : Symbol(something, Decl(index.ts, 1, 9)) +>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0)) + +}; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.types b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.types new file mode 100644 index 0000000000000..b590130d1cff5 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/dynamicImport/something.ts === +export = 42; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +export = async function() { +>async function() { const something = await import("./something");} : () => Promise + + const something = await import("./something"); +>something : 42 +>await import("./something") : 42 +>import("./something") : Promise<42> +>"./something" : "./something" + +}; diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts new file mode 100644 index 0000000000000..77f348bd3fa11 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts @@ -0,0 +1,9 @@ +// @module: amd +// @target: esnext +// @filename: something.ts +export = 42; + +// @filename: index.ts +export = async function() { + const something = await import("./something"); +}; \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts new file mode 100644 index 0000000000000..efda80d4995db --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts @@ -0,0 +1,9 @@ +// @module: commonjs +// @target: esnext +// @filename: something.ts +export = 42; + +// @filename: index.ts +export = async function() { + const something = await import("./something"); +}; \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts new file mode 100644 index 0000000000000..fc0865914fbd0 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts @@ -0,0 +1,9 @@ +// @module: umd +// @target: esnext +// @filename: something.ts +export = 42; + +// @filename: index.ts +export = async function() { + const something = await import("./something"); +}; \ No newline at end of file From a39ae1fab712d321ffdc50ee02089fad5091f9bf Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 24 Aug 2017 23:58:20 -0700 Subject: [PATCH 23/60] Fix crash when attempting to merge an import with a local declaration (#18032) (#18034) * There should be no crash when attempting to merge an import with a local declaration * Show symbol has actually merged within the module --- src/compiler/checker.ts | 2 + .../noCrashOnImportShadowing.errors.txt | 33 +++++++++++++ .../reference/noCrashOnImportShadowing.js | 46 +++++++++++++++++++ .../compiler/noCrashOnImportShadowing.ts | 25 ++++++++++ 4 files changed, 106 insertions(+) create mode 100644 tests/baselines/reference/noCrashOnImportShadowing.errors.txt create mode 100644 tests/baselines/reference/noCrashOnImportShadowing.js create mode 100644 tests/cases/compiler/noCrashOnImportShadowing.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6f84239061fb3..bc8223acdc949 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19126,6 +19126,8 @@ namespace ts { : DeclarationSpaces.ExportNamespace; case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: + // A NamespaceImport declares an Alias, which is allowed to merge with other values within the module + case SyntaxKind.NamespaceImport: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue; case SyntaxKind.ImportEqualsDeclaration: let result = DeclarationSpaces.None; diff --git a/tests/baselines/reference/noCrashOnImportShadowing.errors.txt b/tests/baselines/reference/noCrashOnImportShadowing.errors.txt new file mode 100644 index 0000000000000..c1d1dbcdef1a1 --- /dev/null +++ b/tests/baselines/reference/noCrashOnImportShadowing.errors.txt @@ -0,0 +1,33 @@ +tests/cases/compiler/index.ts(4,1): error TS2693: 'B' only refers to a type, but is being used as a value here. +tests/cases/compiler/index.ts(9,10): error TS2304: Cannot find name 'OriginalB'. + + +==== tests/cases/compiler/b.ts (0 errors) ==== + export const zzz = 123; + +==== tests/cases/compiler/a.ts (0 errors) ==== + import * as B from "./b"; + + interface B { + x: string; + } + + const x: B = { x: "" }; + B.zzz; + + export { B }; + +==== tests/cases/compiler/index.ts (2 errors) ==== + import { B } from "./a"; + + const x: B = { x: "" }; + B.zzz; + ~ +!!! error TS2693: 'B' only refers to a type, but is being used as a value here. + + import * as OriginalB from "./b"; + OriginalB.zzz; + + const y: OriginalB = x; + ~~~~~~~~~ +!!! error TS2304: Cannot find name 'OriginalB'. \ No newline at end of file diff --git a/tests/baselines/reference/noCrashOnImportShadowing.js b/tests/baselines/reference/noCrashOnImportShadowing.js new file mode 100644 index 0000000000000..7ca2116954d6f --- /dev/null +++ b/tests/baselines/reference/noCrashOnImportShadowing.js @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/noCrashOnImportShadowing.ts] //// + +//// [b.ts] +export const zzz = 123; + +//// [a.ts] +import * as B from "./b"; + +interface B { + x: string; +} + +const x: B = { x: "" }; +B.zzz; + +export { B }; + +//// [index.ts] +import { B } from "./a"; + +const x: B = { x: "" }; +B.zzz; + +import * as OriginalB from "./b"; +OriginalB.zzz; + +const y: OriginalB = x; + +//// [b.js] +"use strict"; +exports.__esModule = true; +exports.zzz = 123; +//// [a.js] +"use strict"; +exports.__esModule = true; +var B = require("./b"); +var x = { x: "" }; +B.zzz; +//// [index.js] +"use strict"; +exports.__esModule = true; +var x = { x: "" }; +B.zzz; +var OriginalB = require("./b"); +OriginalB.zzz; +var y = x; diff --git a/tests/cases/compiler/noCrashOnImportShadowing.ts b/tests/cases/compiler/noCrashOnImportShadowing.ts new file mode 100644 index 0000000000000..69e8b6a0f8c01 --- /dev/null +++ b/tests/cases/compiler/noCrashOnImportShadowing.ts @@ -0,0 +1,25 @@ +// @filename: b.ts +export const zzz = 123; + +// @filename: a.ts +import * as B from "./b"; + +interface B { + x: string; +} + +const x: B = { x: "" }; +B.zzz; + +export { B }; + +// @filename: index.ts +import { B } from "./a"; + +const x: B = { x: "" }; +B.zzz; + +import * as OriginalB from "./b"; +OriginalB.zzz; + +const y: OriginalB = x; \ No newline at end of file From 3644771ab672c433ad6130428b06f0fc00ba9212 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 25 Aug 2017 14:11:52 -0700 Subject: [PATCH 24/60] Test for action description of code actions, and simplify description for extracting method to file (#18030) (#18044) * Test for action description of code actions, and simplify description for extracting method to file * Add unit test file missing from tsconfig.json (only affects gulp) and update tests * Use the actual number * Use "module scope" or "global scope" instead of "this file" --- src/compiler/diagnosticMessages.json | 2 +- src/harness/fourslash.ts | 47 +++++++++++++------ src/harness/tsconfig.json | 1 + src/services/refactors/extractMethod.ts | 18 +++---- .../reference/extractMethod/extractMethod1.js | 8 ++-- .../extractMethod/extractMethod10.js | 6 +-- .../extractMethod/extractMethod11.js | 6 +-- .../extractMethod/extractMethod12.js | 2 +- .../reference/extractMethod/extractMethod2.js | 8 ++-- .../reference/extractMethod/extractMethod3.js | 8 ++-- .../reference/extractMethod/extractMethod4.js | 8 ++-- .../reference/extractMethod/extractMethod5.js | 8 ++-- .../reference/extractMethod/extractMethod6.js | 8 ++-- .../reference/extractMethod/extractMethod7.js | 8 ++-- .../reference/extractMethod/extractMethod8.js | 8 ++-- .../reference/extractMethod/extractMethod9.js | 8 ++-- tests/cases/fourslash/extract-method1.ts | 7 ++- tests/cases/fourslash/extract-method10.ts | 9 +++- tests/cases/fourslash/extract-method13.ts | 12 ++++- tests/cases/fourslash/extract-method14.ts | 6 ++- tests/cases/fourslash/extract-method15.ts | 6 ++- tests/cases/fourslash/extract-method18.ts | 7 ++- tests/cases/fourslash/extract-method19.ts | 9 ++-- tests/cases/fourslash/extract-method2.ts | 7 ++- tests/cases/fourslash/extract-method21.ts | 6 ++- tests/cases/fourslash/extract-method24.ts | 6 ++- tests/cases/fourslash/extract-method25.ts | 6 ++- tests/cases/fourslash/extract-method3.ts | 2 +- tests/cases/fourslash/extract-method5.ts | 6 ++- tests/cases/fourslash/extract-method7.ts | 6 ++- tests/cases/fourslash/fourslash.ts | 4 +- 31 files changed, 163 insertions(+), 90 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 77e7f7e7b6246..974224e39e93b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3688,7 +3688,7 @@ "code": 95003 }, - "Extract function into '{0}'": { + "Extract function into {0}": { "category": "Message", "code": 95004 } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 2b28ecbbfec21..77639dcc0787b 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2743,20 +2743,25 @@ namespace FourSlash { }); } - public verifyRefactorAvailable(negative: boolean, name?: string, subName?: string) { + public verifyRefactorAvailable(negative: boolean, name: string, actionName?: string) { const selection = this.getSelection(); let refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, selection) || []; - if (name) { - refactors = refactors.filter(r => r.name === name && (subName === undefined || r.actions.some(a => a.name === subName))); - } + refactors = refactors.filter(r => r.name === name && (actionName === undefined || r.actions.some(a => a.name === actionName))); const isAvailable = refactors.length > 0; - if (negative && isAvailable) { - this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found some: ${refactors.map(r => r.name).join(", ")}`); + if (negative) { + if (isAvailable) { + this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found: ${refactors.map(r => r.name).join(", ")}`); + } } - else if (!negative && !isAvailable) { - this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`); + else { + if (!isAvailable) { + this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`); + } + if (refactors.length > 1) { + this.raiseError(`${refactors.length} available refactors both have name ${name} and action ${actionName}`); + } } } @@ -2776,14 +2781,22 @@ namespace FourSlash { } } - public applyRefactor(refactorName: string, actionName: string) { + public applyRefactor({ refactorName, actionName, actionDescription }: FourSlashInterface.ApplyRefactorOptions) { const range = this.getSelection(); const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range); - const refactor = ts.find(refactors, r => r.name === refactorName); + const refactor = refactors.find(r => r.name === refactorName); if (!refactor) { this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.`); } + const action = refactor.actions.find(a => a.name === actionName); + if (!action) { + this.raiseError(`The expected action: ${action} is not included in: ${refactor.actions.map(a => a.name)}`); + } + if (action.description !== actionDescription) { + this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`); + } + const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName); for (const edit of editInfo.edits) { this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false); @@ -3660,8 +3673,8 @@ namespace FourSlashInterface { this.state.verifyApplicableRefactorAvailableForRange(this.negative); } - public refactorAvailable(name?: string, subName?: string) { - this.state.verifyRefactorAvailable(this.negative, name, subName); + public refactorAvailable(name: string, actionName?: string) { + this.state.verifyRefactorAvailable(this.negative, name, actionName); } } @@ -4059,8 +4072,8 @@ namespace FourSlashInterface { this.state.enableFormatting = false; } - public applyRefactor(refactorName: string, actionName: string) { - this.state.applyRefactor(refactorName, actionName); + public applyRefactor(options: ApplyRefactorOptions) { + this.state.applyRefactor(options); } } @@ -4273,4 +4286,10 @@ namespace FourSlashInterface { return { classificationType, text, textSpan }; } } + + export interface ApplyRefactorOptions { + refactorName: string; + actionName: string; + actionDescription: string; + } } diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 66ca2fc3f4837..f8ad5e6992ae3 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -123,6 +123,7 @@ "./unittests/printer.ts", "./unittests/transform.ts", "./unittests/customTransforms.ts", + "./unittests/extractMethods.ts", "./unittests/textChanges.ts", "./unittests/telemetry.ts", "./unittests/programMissingFiles.ts" diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts index f0f85ee6e8167..ac1c8383efa2a 100644 --- a/src/services/refactors/extractMethod.ts +++ b/src/services/refactors/extractMethod.ts @@ -560,32 +560,32 @@ namespace ts.refactor.extractMethod { return "constructor"; case SyntaxKind.FunctionExpression: return scope.name - ? `function expression ${scope.name.getText()}` + ? `function expression ${scope.name.text}` : "anonymous function expression"; case SyntaxKind.FunctionDeclaration: - return `function ${scope.name.getText()}`; + return `function '${scope.name.text}'`; case SyntaxKind.ArrowFunction: return "arrow function"; case SyntaxKind.MethodDeclaration: - return `method ${scope.name.getText()}`; + return `method '${scope.name.getText()}`; case SyntaxKind.GetAccessor: - return `get ${scope.name.getText()}`; + return `'get ${scope.name.getText()}'`; case SyntaxKind.SetAccessor: - return `set ${scope.name.getText()}`; + return `'set ${scope.name.getText()}'`; } } else if (isModuleBlock(scope)) { - return `namespace ${scope.parent.name.getText()}`; + return `namespace '${scope.parent.name.getText()}'`; } else if (isClassLike(scope)) { return scope.kind === SyntaxKind.ClassDeclaration - ? `class ${scope.name.text}` + ? `class '${scope.name.text}'` : scope.name.text - ? `class expression ${scope.name.text}` + ? `class expression '${scope.name.text}'` : "anonymous class expression"; } else if (isSourceFile(scope)) { - return `file '${scope.fileName}'`; + return scope.externalModuleIndicator ? "module scope" : "global scope"; } else { return "unknown"; diff --git a/tests/baselines/reference/extractMethod/extractMethod1.js b/tests/baselines/reference/extractMethod/extractMethod1.js index 60c7e301616e8..10bf2648383bf 100644 --- a/tests/baselines/reference/extractMethod/extractMethod1.js +++ b/tests/baselines/reference/extractMethod/extractMethod1.js @@ -14,7 +14,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { let x = 1; function foo() { @@ -34,7 +34,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { let x = 1; function foo() { @@ -55,7 +55,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let x = 1; function foo() { @@ -76,7 +76,7 @@ namespace A { return a; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let x = 1; function foo() { diff --git a/tests/baselines/reference/extractMethod/extractMethod10.js b/tests/baselines/reference/extractMethod/extractMethod10.js index 02923b7ab50c7..b2397744680b2 100644 --- a/tests/baselines/reference/extractMethod/extractMethod10.js +++ b/tests/baselines/reference/extractMethod/extractMethod10.js @@ -9,7 +9,7 @@ namespace A { } } } -==SCOPE::class C== +==SCOPE::class 'C'== namespace A { export interface I { x: number }; class C { @@ -24,7 +24,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { export interface I { x: number }; class C { @@ -39,7 +39,7 @@ namespace A { return a1.x + 10; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { export interface I { x: number }; class C { diff --git a/tests/baselines/reference/extractMethod/extractMethod11.js b/tests/baselines/reference/extractMethod/extractMethod11.js index 77565e7b0a778..21392a07a7a4b 100644 --- a/tests/baselines/reference/extractMethod/extractMethod11.js +++ b/tests/baselines/reference/extractMethod/extractMethod11.js @@ -11,7 +11,7 @@ namespace A { } } } -==SCOPE::class C== +==SCOPE::class 'C'== namespace A { let y = 1; class C { @@ -30,7 +30,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let y = 1; class C { @@ -49,7 +49,7 @@ namespace A { return { __return: a1.x + 10, z }; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let y = 1; class C { diff --git a/tests/baselines/reference/extractMethod/extractMethod12.js b/tests/baselines/reference/extractMethod/extractMethod12.js index 8ff6e130dad2a..7cebab5d3c582 100644 --- a/tests/baselines/reference/extractMethod/extractMethod12.js +++ b/tests/baselines/reference/extractMethod/extractMethod12.js @@ -13,7 +13,7 @@ namespace A { } } } -==SCOPE::class C== +==SCOPE::class 'C'== namespace A { let y = 1; class C { diff --git a/tests/baselines/reference/extractMethod/extractMethod2.js b/tests/baselines/reference/extractMethod/extractMethod2.js index 28c27993d7165..3c0d2e7c7b01c 100644 --- a/tests/baselines/reference/extractMethod/extractMethod2.js +++ b/tests/baselines/reference/extractMethod/extractMethod2.js @@ -12,7 +12,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { let x = 1; function foo() { @@ -30,7 +30,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { let x = 1; function foo() { @@ -48,7 +48,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let x = 1; function foo() { @@ -66,7 +66,7 @@ namespace A { return foo(); } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let x = 1; function foo() { diff --git a/tests/baselines/reference/extractMethod/extractMethod3.js b/tests/baselines/reference/extractMethod/extractMethod3.js index e5903ead18199..cb28e2755e708 100644 --- a/tests/baselines/reference/extractMethod/extractMethod3.js +++ b/tests/baselines/reference/extractMethod/extractMethod3.js @@ -11,7 +11,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { function foo() { } @@ -28,7 +28,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { function foo() { } @@ -45,7 +45,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { function foo() { } @@ -62,7 +62,7 @@ namespace A { return foo(); } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { function foo() { } diff --git a/tests/baselines/reference/extractMethod/extractMethod4.js b/tests/baselines/reference/extractMethod/extractMethod4.js index 6b9e2eed099d3..07029b2d05063 100644 --- a/tests/baselines/reference/extractMethod/extractMethod4.js +++ b/tests/baselines/reference/extractMethod/extractMethod4.js @@ -13,7 +13,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { function foo() { } @@ -32,7 +32,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { function foo() { } @@ -51,7 +51,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { function foo() { } @@ -70,7 +70,7 @@ namespace A { return foo(); } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { function foo() { } diff --git a/tests/baselines/reference/extractMethod/extractMethod5.js b/tests/baselines/reference/extractMethod/extractMethod5.js index cf63cb2a93214..96a76e426b14f 100644 --- a/tests/baselines/reference/extractMethod/extractMethod5.js +++ b/tests/baselines/reference/extractMethod/extractMethod5.js @@ -14,7 +14,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { let x = 1; export function foo() { @@ -34,7 +34,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { let x = 1; export function foo() { @@ -55,7 +55,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let x = 1; export function foo() { @@ -76,7 +76,7 @@ namespace A { return a; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let x = 1; export function foo() { diff --git a/tests/baselines/reference/extractMethod/extractMethod6.js b/tests/baselines/reference/extractMethod/extractMethod6.js index 99f52e9febbe0..d1244ac959649 100644 --- a/tests/baselines/reference/extractMethod/extractMethod6.js +++ b/tests/baselines/reference/extractMethod/extractMethod6.js @@ -14,7 +14,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { let x = 1; export function foo() { @@ -34,7 +34,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { let x = 1; export function foo() { @@ -56,7 +56,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let x = 1; export function foo() { @@ -78,7 +78,7 @@ namespace A { return { __return: foo(), a }; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let x = 1; export function foo() { diff --git a/tests/baselines/reference/extractMethod/extractMethod7.js b/tests/baselines/reference/extractMethod/extractMethod7.js index 09d5edaa2c05d..da400d8b05128 100644 --- a/tests/baselines/reference/extractMethod/extractMethod7.js +++ b/tests/baselines/reference/extractMethod/extractMethod7.js @@ -16,7 +16,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { let x = 1; export namespace C { @@ -38,7 +38,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { let x = 1; export namespace C { @@ -62,7 +62,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let x = 1; export namespace C { @@ -86,7 +86,7 @@ namespace A { return { __return: C.foo(), a }; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let x = 1; export namespace C { diff --git a/tests/baselines/reference/extractMethod/extractMethod8.js b/tests/baselines/reference/extractMethod/extractMethod8.js index fe9cf2a92f0fd..d298387b9026e 100644 --- a/tests/baselines/reference/extractMethod/extractMethod8.js +++ b/tests/baselines/reference/extractMethod/extractMethod8.js @@ -8,7 +8,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { let x = 1; namespace B { @@ -22,7 +22,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { let x = 1; namespace B { @@ -36,7 +36,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { let x = 1; namespace B { @@ -50,7 +50,7 @@ namespace A { return 1 + a1 + x; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { let x = 1; namespace B { diff --git a/tests/baselines/reference/extractMethod/extractMethod9.js b/tests/baselines/reference/extractMethod/extractMethod9.js index fcc5dcd23de07..609e3535d5762 100644 --- a/tests/baselines/reference/extractMethod/extractMethod9.js +++ b/tests/baselines/reference/extractMethod/extractMethod9.js @@ -8,7 +8,7 @@ namespace A { } } } -==SCOPE::function a== +==SCOPE::function 'a'== namespace A { export interface I { x: number }; namespace B { @@ -22,7 +22,7 @@ namespace A { } } } -==SCOPE::namespace B== +==SCOPE::namespace 'B'== namespace A { export interface I { x: number }; namespace B { @@ -36,7 +36,7 @@ namespace A { } } } -==SCOPE::namespace A== +==SCOPE::namespace 'A'== namespace A { export interface I { x: number }; namespace B { @@ -50,7 +50,7 @@ namespace A { return a1.x + 10; } } -==SCOPE::file '/a.ts'== +==SCOPE::global scope== namespace A { export interface I { x: number }; namespace B { diff --git a/tests/cases/fourslash/extract-method1.ts b/tests/cases/fourslash/extract-method1.ts index 7f5c2ac2d500a..ff061295c8c6b 100644 --- a/tests/cases/fourslash/extract-method1.ts +++ b/tests/cases/fourslash/extract-method1.ts @@ -13,8 +13,11 @@ //// } goTo.select('start', 'end') -verify.refactorAvailable('Extract Method'); -edit.applyRefactor('Extract Method', "scope_0"); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into class 'Foo'", +}); verify.currentFileContentIs( `class Foo { someMethod(m: number) { diff --git a/tests/cases/fourslash/extract-method10.ts b/tests/cases/fourslash/extract-method10.ts index 1a02bfa00f53e..ffbee7350e259 100644 --- a/tests/cases/fourslash/extract-method10.ts +++ b/tests/cases/fourslash/extract-method10.ts @@ -1,6 +1,11 @@ /// -//// (x => x)(/*1*/x => x/*2*/)(1); +//// export {}; // Make this a module +//// (x => x)(/*1*/x => x/*2*/)(1); goTo.select('1', '2'); -edit.applyRefactor('Extract Method', 'scope_0'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: 'scope_0', + actionDescription: "Extract function into module scope", +}); diff --git a/tests/cases/fourslash/extract-method13.ts b/tests/cases/fourslash/extract-method13.ts index b9b7c0096aabc..14a146a80c509 100644 --- a/tests/cases/fourslash/extract-method13.ts +++ b/tests/cases/fourslash/extract-method13.ts @@ -10,10 +10,18 @@ //// } goTo.select('a', 'b'); -edit.applyRefactor('Extract Method', 'scope_0'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into class 'C'", +}); goTo.select('c', 'd'); -edit.applyRefactor('Extract Method', 'scope_0'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into class 'C'", +}); verify.currentFileContentIs(`class C { static j = C.newFunction_1(); diff --git a/tests/cases/fourslash/extract-method14.ts b/tests/cases/fourslash/extract-method14.ts index c8bab1b3a56d7..696bb664bd358 100644 --- a/tests/cases/fourslash/extract-method14.ts +++ b/tests/cases/fourslash/extract-method14.ts @@ -11,7 +11,11 @@ //// } goTo.select('a', 'b'); -edit.applyRefactor('Extract Method', 'scope_1'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract function into global scope", +}); verify.currentFileContentIs(`function foo() { var i = 10; var __return: any; diff --git a/tests/cases/fourslash/extract-method15.ts b/tests/cases/fourslash/extract-method15.ts index ef62bd3fd3f74..93aa357cfee2e 100644 --- a/tests/cases/fourslash/extract-method15.ts +++ b/tests/cases/fourslash/extract-method15.ts @@ -9,7 +9,11 @@ //// } goTo.select('a', 'b'); -edit.applyRefactor('Extract Method', 'scope_1'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract function into global scope", +}); verify.currentFileContentIs(`function foo() { var i = 10; diff --git a/tests/cases/fourslash/extract-method18.ts b/tests/cases/fourslash/extract-method18.ts index 9d87979a1ed1c..d99d14bac73f6 100644 --- a/tests/cases/fourslash/extract-method18.ts +++ b/tests/cases/fourslash/extract-method18.ts @@ -9,8 +9,11 @@ //// } goTo.select('a', 'b') -verify.refactorAvailable('Extract Method'); -edit.applyRefactor('Extract Method', "scope_1"); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract function into global scope", +}); verify.currentFileContentIs(`function fn() { const x = { m: 1 }; newFunction(x); diff --git a/tests/cases/fourslash/extract-method19.ts b/tests/cases/fourslash/extract-method19.ts index 54f79311cc72b..e4fb3e6e1110e 100644 --- a/tests/cases/fourslash/extract-method19.ts +++ b/tests/cases/fourslash/extract-method19.ts @@ -5,12 +5,15 @@ //// function fn() { //// /*a*/console.log("hi");/*b*/ //// } -//// +//// //// function newFunction() { } goTo.select('a', 'b') -verify.refactorAvailable('Extract Method'); -edit.applyRefactor('Extract Method', "scope_0"); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into function 'fn'", +}); verify.currentFileContentIs(`function fn() { newFunction_1(); diff --git a/tests/cases/fourslash/extract-method2.ts b/tests/cases/fourslash/extract-method2.ts index 0a4f346307b5f..508836c419922 100644 --- a/tests/cases/fourslash/extract-method2.ts +++ b/tests/cases/fourslash/extract-method2.ts @@ -10,8 +10,11 @@ //// } //// } goTo.select('start', 'end') -verify.refactorAvailable('Extract Method'); -edit.applyRefactor('Extract Method', "scope_2"); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_2", + actionDescription: "Extract function into global scope", +}); verify.currentFileContentIs( `namespace NS { class Q { diff --git a/tests/cases/fourslash/extract-method21.ts b/tests/cases/fourslash/extract-method21.ts index 0168daf5fcb02..c32df5b59798e 100644 --- a/tests/cases/fourslash/extract-method21.ts +++ b/tests/cases/fourslash/extract-method21.ts @@ -12,7 +12,11 @@ goTo.select('start', 'end') verify.refactorAvailable('Extract Method'); -edit.applyRefactor('Extract Method', "scope_0"); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into class 'Foo'", +}); verify.currentFileContentIs(`class Foo { static method() { diff --git a/tests/cases/fourslash/extract-method24.ts b/tests/cases/fourslash/extract-method24.ts index 9eebc00316bd6..615cb2ac4d2f8 100644 --- a/tests/cases/fourslash/extract-method24.ts +++ b/tests/cases/fourslash/extract-method24.ts @@ -7,7 +7,11 @@ //// } goTo.select('a', 'b') -edit.applyRefactor('Extract Method', 'scope_1'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract function into global scope", +}); verify.currentFileContentIs(`function M() { let a = [1,2,3]; let x = 0; diff --git a/tests/cases/fourslash/extract-method25.ts b/tests/cases/fourslash/extract-method25.ts index ac7e7a2300497..8585dd06fd4ea 100644 --- a/tests/cases/fourslash/extract-method25.ts +++ b/tests/cases/fourslash/extract-method25.ts @@ -8,7 +8,11 @@ //// } goTo.select('a', 'b') -edit.applyRefactor('Extract Method', 'scope_0'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into function 'fn'", +}); verify.currentFileContentIs(`function fn() { var q = newFunction() q[0]++ diff --git a/tests/cases/fourslash/extract-method3.ts b/tests/cases/fourslash/extract-method3.ts index af543121eebf2..27a520d0555a4 100644 --- a/tests/cases/fourslash/extract-method3.ts +++ b/tests/cases/fourslash/extract-method3.ts @@ -10,7 +10,7 @@ //// } //// } -// Don't offer to to 'extract method' a single identifier +// Don't offer to 'extract method' a single identifier goTo.marker('a'); verify.not.refactorAvailable('Extract Method'); diff --git a/tests/cases/fourslash/extract-method5.ts b/tests/cases/fourslash/extract-method5.ts index ac09f92cc0520..10294298b085b 100644 --- a/tests/cases/fourslash/extract-method5.ts +++ b/tests/cases/fourslash/extract-method5.ts @@ -9,7 +9,11 @@ //// } goTo.select('start', 'end'); -edit.applyRefactor('Extract Method', 'scope_0'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into function 'f'", +}); verify.currentFileContentIs( `function f() { var x: 1 | 2 | 3 = newFunction(); diff --git a/tests/cases/fourslash/extract-method7.ts b/tests/cases/fourslash/extract-method7.ts index 4c95c6a551d57..95c9cbe9897ec 100644 --- a/tests/cases/fourslash/extract-method7.ts +++ b/tests/cases/fourslash/extract-method7.ts @@ -7,7 +7,11 @@ //// } goTo.select('a', 'b'); -edit.applyRefactor('Extract Method', 'scope_0'); +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into global scope", +}); verify.currentFileContentIs(`function fn(x = newFunction()) { } function newFunction() { diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 5175b52df6c9f..be842680e17ff 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -158,7 +158,7 @@ declare namespace FourSlashInterface { codeFixDiagnosticsAvailableAtMarkers(markerNames: string[], diagnosticCode?: number): void; applicableRefactorAvailableForRange(): void; - refactorAvailable(name?: string, subName?: string); + refactorAvailable(name: string, actionName?: string); } class verify extends verifyNegatable { assertHasRanges(ranges: Range[]): void; @@ -309,7 +309,7 @@ declare namespace FourSlashInterface { enableFormatting(): void; disableFormatting(): void; - applyRefactor(refactorName: string, actionName: string): void; + applyRefactor(options: { refactorName: string, actionName: string, actionDescription: string }): void; } class debug { printCurrentParameterHelp(): void; From 62678cd736a0d7685dca2db32a6768eb5e21a8fc Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 25 Aug 2017 15:12:21 -0700 Subject: [PATCH 25/60] Don't try to extract `import` to a method: simpler fix (#18054) --- src/services/refactors/extractMethod.ts | 26 +++++++++++-------- .../extract-method-not-for-import.ts | 10 +++++++ 2 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 tests/cases/fourslash/extract-method-not-for-import.ts diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts index ac1c8383efa2a..9634b9c817281 100644 --- a/src/services/refactors/extractMethod.ts +++ b/src/services/refactors/extractMethod.ts @@ -232,17 +232,7 @@ namespace ts.refactor.extractMethod { return { errors }; } - // If our selection is the expression in an ExpressionStatement, expand - // the selection to include the enclosing Statement (this stops us - // from trying to care about the return value of the extracted function - // and eliminates double semicolon insertion in certain scenarios) - const range = isStatement(start) - ? [start] - : start.parent && start.parent.kind === SyntaxKind.ExpressionStatement - ? [start.parent as Statement] - : start as Expression; - - return { targetRange: { range, facts: rangeFacts, declarations } }; + return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations } }; } function createErrorResult(sourceFile: SourceFile, start: number, length: number, message: DiagnosticMessage): RangeToExtract { @@ -459,6 +449,20 @@ namespace ts.refactor.extractMethod { } } + function getStatementOrExpressionRange(node: Node): Statement[] | Expression { + if (isStatement(node)) { + return [node]; + } + else if (isPartOfExpression(node)) { + // If our selection is the expression in an ExpressionStatement, expand + // the selection to include the enclosing Statement (this stops us + // from trying to care about the return value of the extracted function + // and eliminates double semicolon insertion in certain scenarios) + return isExpressionStatement(node.parent) ? [node.parent] : node as Expression; + } + return undefined; + } + function isValidExtractionTarget(node: Node): node is Scope { // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method return (node.kind === SyntaxKind.FunctionDeclaration) || isSourceFile(node) || isModuleBlock(node) || isClassLike(node); diff --git a/tests/cases/fourslash/extract-method-not-for-import.ts b/tests/cases/fourslash/extract-method-not-for-import.ts new file mode 100644 index 0000000000000..a72d793611d62 --- /dev/null +++ b/tests/cases/fourslash/extract-method-not-for-import.ts @@ -0,0 +1,10 @@ +/// + +// @Filename: /a.ts +////i/**/mport _ from "./b"; + +// @Filename: /b.ts +////export default function f() {} + +goTo.marker(""); +verify.not.refactorAvailable('Extract Method'); From 187a21cbac09fd23fce8bc14e06a87f26596ef73 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 25 Aug 2017 14:17:48 -0700 Subject: [PATCH 26/60] Fix crash in name resolution with custom transforms and emitDecoratorMetadata --- src/compiler/checker.ts | 9 +++++++ src/compiler/transformers/ts.ts | 2 +- src/harness/unittests/customTransforms.ts | 23 ++++++++++++++-- .../customTransforms/before+decorators.js | 26 +++++++++++++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/customTransforms/before+decorators.js diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bc8223acdc949..1c650a3c41559 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23454,6 +23454,15 @@ namespace ts { } function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind { + // ensure both `typeName` and `location` are parse tree nodes. + typeName = getParseTreeNode(typeName, isEntityName); + if (!typeName) return TypeReferenceSerializationKind.Unknown; + + if (location) { + location = getParseTreeNode(location); + if (!location) return TypeReferenceSerializationKind.Unknown; + } + // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 71a3c7dcb7a0a..692c758bc7504 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1947,7 +1947,7 @@ namespace ts { const name = getMutableClone(node); name.flags &= ~NodeFlags.Synthesized; name.original = undefined; - name.parent = currentScope; + name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node. if (useFallback) { return createLogicalAnd( createStrictInequality( diff --git a/src/harness/unittests/customTransforms.ts b/src/harness/unittests/customTransforms.ts index 4b05ebb9ea7bf..f47bdad5d588d 100644 --- a/src/harness/unittests/customTransforms.ts +++ b/src/harness/unittests/customTransforms.ts @@ -3,12 +3,11 @@ namespace ts { describe("customTransforms", () => { - function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) { + function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) { it(name, () => { const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015)); const fileMap = arrayToMap(roots, file => file.fileName); const outputs = createMap(); - const options: CompilerOptions = {}; const host: CompilerHost = { getSourceFile: (fileName) => fileMap.get(fileName), getDefaultLibFileName: () => "lib.d.ts", @@ -82,5 +81,25 @@ namespace ts { emitsCorrectly("before", sources, { before: [before] }); emitsCorrectly("after", sources, { after: [after] }); emitsCorrectly("both", sources, { before: [before], after: [after] }); + + emitsCorrectly("before+decorators", [{ + file: "source.ts", + text: ` + declare const dec: any; + class B {} + @dec export class C { constructor(b: B) { } } + 'change' + ` + }], {before: [ + context => node => visitNode(node, function visitor(node: Node): Node { + if (isStringLiteral(node) && node.text === "change") return createLiteral("changed"); + return visitEachChild(node, visitor, context); + }) + ]}, { + target: ScriptTarget.ES5, + module: ModuleKind.ES2015, + emitDecoratorMetadata: true, + experimentalDecorators: true + }); }); } \ No newline at end of file diff --git a/tests/baselines/reference/customTransforms/before+decorators.js b/tests/baselines/reference/customTransforms/before+decorators.js new file mode 100644 index 0000000000000..ef705f0c9d850 --- /dev/null +++ b/tests/baselines/reference/customTransforms/before+decorators.js @@ -0,0 +1,26 @@ +// [source.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +var C = /** @class */ (function () { + function C(b) { + } + C = __decorate([ + dec, + __metadata("design:paramtypes", [B]) + ], C); + return C; +}()); +export { C }; +"changed"; From 2a2773fbb40653fba294fd690c9ea4d602c79f81 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 25 Aug 2017 15:36:13 -0700 Subject: [PATCH 27/60] Update LKG --- lib/tsc.js | 231 ++++++++++++++------------- lib/tsserver.js | 266 ++++++++++++++++--------------- lib/tsserverlibrary.d.ts | 2 + lib/tsserverlibrary.js | 266 ++++++++++++++++--------------- lib/typescript.d.ts | 2 + lib/typescript.js | 301 ++++++++++++++++++++---------------- lib/typescriptServices.d.ts | 2 + lib/typescriptServices.js | 301 ++++++++++++++++++++---------------- lib/typingsInstaller.js | 15 +- 9 files changed, 761 insertions(+), 625 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index 76af89c7672b9..96f74044aac98 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -3521,7 +3521,7 @@ var ts; Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), - Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"), }; })(ts || (ts = {})); var ts; @@ -6876,9 +6876,9 @@ var ts; || kind === 265; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; - function nodeIsSynthesized(node) { - return ts.positionIsSynthesized(node.pos) - || ts.positionIsSynthesized(node.end); + function nodeIsSynthesized(range) { + return ts.positionIsSynthesized(range.pos) + || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { @@ -18801,7 +18801,10 @@ var ts; } return true; } - if (usage.parent.kind === 246) { + if (usage.parent.kind === 246 || (usage.parent.kind === 243 && usage.parent.isExportEquals)) { + return true; + } + if (usage.kind === 243 && usage.isExportEquals) { return true; } var container = ts.getEnclosingBlockScopeContainer(declaration); @@ -23469,6 +23472,9 @@ var ts; } return signature.resolvedReturnType; } + function isResolvingReturnTypeOfSignature(signature) { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3) >= 0; + } function getRestTypeOfSignature(signature) { if (signature.hasRestParameter) { var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters)); @@ -28576,7 +28582,7 @@ var ts; return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); } var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); - if (signature) { + if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } return undefined; @@ -30866,7 +30872,7 @@ var ts; return result; } function isJavaScriptConstructor(node) { - if (ts.isInJavaScriptFile(node)) { + if (node && ts.isInJavaScriptFile(node)) { if (ts.getJSDocClassTag(node)) return true; var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) : @@ -30876,6 +30882,20 @@ var ts; } return false; } + function getJavaScriptClassType(symbol) { + if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = getSymbolOfNode(symbol.valueDeclaration.initializer); + } + if (isJavaScriptConstructor(symbol.valueDeclaration)) { + return getInferredClassType(symbol); + } + if (symbol.flags & 3) { + var valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + return getInferredClassType(valueType.symbol); + } + } + } function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { @@ -30904,13 +30924,11 @@ var ts; var funcSymbol = node.expression.kind === 71 ? getResolvedSymbol(node.expression) : checkExpression(node.expression).symbol; - if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) { - funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer); - } - if (funcSymbol && funcSymbol.flags & 16 && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) { - return getInferredClassType(funcSymbol); + var type = funcSymbol && getJavaScriptClassType(funcSymbol); + if (type) { + return type; } - else if (noImplicitAny) { + if (noImplicitAny) { error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -33057,6 +33075,7 @@ var ts; : 4; case 229: case 232: + case 240: return 2 | 1; case 237: var result_3 = 0; @@ -36229,6 +36248,14 @@ var ts; return type.flags & 32768 && getSignaturesOfType(type, 0).length > 0; } function getTypeReferenceSerializationKind(typeName, location) { + typeName = ts.getParseTreeNode(typeName, ts.isEntityName); + if (!typeName) + return ts.TypeReferenceSerializationKind.Unknown; + if (location) { + location = ts.getParseTreeNode(location); + if (!location) + return ts.TypeReferenceSerializationKind.Unknown; + } var valueSymbol = resolveEntityName(typeName, 107455, true, false, location); var typeSymbol = resolveEntityName(typeName, 793064, true, false, location); if (valueSymbol && valueSymbol === typeSymbol) { @@ -39686,6 +39713,10 @@ var ts; return createCall(createFunctionExpression(undefined, undefined, undefined, undefined, param ? [param] : [], undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression; + function createImmediatelyInvokedArrowFunction(statements, param, paramValue) { + return createCall(createArrowFunction(undefined, undefined, param ? [param] : [], undefined, undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []); + } + ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction; function createComma(left, right) { return createBinary(left, 26, right); } @@ -40769,9 +40800,17 @@ var ts; case 288: return ts.updatePartiallyEmittedExpression(outerExpression, expression); } } + function isIgnorableParen(node) { + return node.kind === 185 + && ts.nodeIsSynthesized(node) + && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) + && ts.nodeIsSynthesized(ts.getCommentRange(node)) + && !ts.some(ts.getSyntheticLeadingComments(node)) + && !ts.some(ts.getSyntheticTrailingComments(node)); + } function recreateOuterExpressions(outerExpression, innerExpression, kinds) { if (kinds === void 0) { kinds = 7; } - if (outerExpression && isOuterExpression(outerExpression, kinds)) { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; @@ -41997,7 +42036,7 @@ var ts; } else { var name = node.name; - if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true); exportedNames = ts.append(exportedNames, name); @@ -42670,8 +42709,10 @@ var ts; ts.setEmitFlags(statement, 1536 | 384); statements.push(statement); ts.addRange(statements, context.endLexicalEnvironment()); + var iife = ts.createImmediatelyInvokedArrowFunction(statements); + ts.setEmitFlags(iife, 33554432); var varStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ - ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, ts.createImmediatelyInvokedFunctionExpression(statements)) + ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, iife) ])); ts.setOriginalNode(varStatement, node); ts.setCommentRange(varStatement, node); @@ -43277,7 +43318,7 @@ var ts; var name = ts.getMutableClone(node); name.flags &= ~8; name.original = undefined; - name.parent = currentScope; + name.parent = ts.getParseTreeNode(currentScope); if (useFallback) { return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name); } @@ -44361,7 +44402,7 @@ var ts; chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression))); } else { - chunkObject.push(e); + chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike)); } } } @@ -45307,58 +45348,12 @@ var ts; && node.kind === 219 && !node.expression; } - function isClassLikeVariableStatement(node) { - if (!ts.isVariableStatement(node)) - return false; - var variable = ts.singleOrUndefined(node.declarationList.declarations); - return variable - && variable.initializer - && ts.isIdentifier(variable.name) - && (ts.isClassLike(variable.initializer) - || (ts.isAssignmentExpression(variable.initializer) - && ts.isIdentifier(variable.initializer.left) - && ts.isClassLike(variable.initializer.right))); - } - function isTypeScriptClassWrapper(node) { - var call = ts.tryCast(node, ts.isCallExpression); - if (!call || ts.isParseTreeNode(call) || - ts.some(call.typeArguments) || - ts.some(call.arguments)) { - return false; - } - var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression); - if (!func || ts.isParseTreeNode(func) || - ts.some(func.typeParameters) || - ts.some(func.parameters) || - func.type || - !func.body) { - return false; - } - var statements = func.body.statements; - if (statements.length < 2) { - return false; - } - var firstStatement = statements[0]; - if (ts.isParseTreeNode(firstStatement) || - !ts.isClassLike(firstStatement) && - !isClassLikeVariableStatement(firstStatement)) { - return false; - } - var lastStatement = ts.elementAt(statements, -1); - var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement); - if (!returnStatement || - !returnStatement.expression || - !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) { - return false; - } - return true; - } function shouldVisitNode(node) { return (node.transformFlags & 128) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207))) || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node)) - || isTypeScriptClassWrapper(node); + || (ts.getEmitFlags(node) & 33554432) !== 0; } function visitor(node) { if (shouldVisitNode(node)) { @@ -46838,7 +46833,7 @@ var ts; return ts.visitEachChild(node, visitor, context); } function visitCallExpression(node) { - if (isTypeScriptClassWrapper(node)) { + if (ts.getEmitFlags(node) & 33554432) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & 64) { @@ -46847,7 +46842,7 @@ var ts; return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression)); } function visitTypeScriptClassWrapper(node) { - var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body; + var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock); var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1); var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1); var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement); @@ -48042,8 +48037,12 @@ var ts; } function transformAndEmitContinueStatement(node) { var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label."); - emitBreak(label, node); + if (label > 0) { + emitBreak(label, node); + } + else { + emitStatement(node); + } } function visitContinueStatement(node) { if (inStatementContainingYield) { @@ -48056,8 +48055,12 @@ var ts; } function transformAndEmitBreakStatement(node) { var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label."); - emitBreak(label, node); + if (label > 0) { + emitBreak(label, node); + } + else { + emitStatement(node); + } } function visitBreakStatement(node) { if (inStatementContainingYield) { @@ -48481,43 +48484,45 @@ var ts; return false; } function findBreakTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { - return block.breakLabel; - } - else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.breakLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { + return block.breakLabel; + } + else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.breakLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledBreak(block)) { - return block.breakLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledBreak(block)) { + return block.breakLabel; + } } } } return 0; } function findContinueTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.continueLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.continueLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block)) { - return block.continueLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block)) { + return block.continueLabel; + } } } } @@ -49071,17 +49076,23 @@ var ts; } function addExportEqualsIfNeeded(statements, emitAsReturn) { if (currentModuleInfo.exportEquals) { - if (emitAsReturn) { - var statement = ts.createReturn(currentModuleInfo.exportEquals.expression); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 384 | 1536); - statements.push(statement); - } - else { - var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression)); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 1536); - statements.push(statement); + var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression); + if (expressionResult) { + if (expressionResult instanceof Array) { + return ts.Debug.fail("export= expression should never be replaced with multiple expressions!"); + } + if (emitAsReturn) { + var statement = ts.createReturn(expressionResult); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 384 | 1536); + statements.push(statement); + } + else { + var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult)); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 1536); + statements.push(statement); + } } } } @@ -49415,7 +49426,7 @@ var ts; return statements; } if (ts.hasModifier(decl, 1)) { - var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : decl.name; + var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : ts.getDeclarationName(decl); statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), decl); } if (decl.name) { diff --git a/lib/tsserver.js b/lib/tsserver.js index 29157d2fd8683..afb40f591c181 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1066,6 +1066,7 @@ var ts; EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker"; EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator"; EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping"; + EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper"; })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {})); var ExternalEmitHelpers; (function (ExternalEmitHelpers) { @@ -4557,7 +4558,7 @@ var ts; Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), - Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"), }; })(ts || (ts = {})); var ts; @@ -7133,9 +7134,9 @@ var ts; || kind === 265; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; - function nodeIsSynthesized(node) { - return ts.positionIsSynthesized(node.pos) - || ts.positionIsSynthesized(node.end); + function nodeIsSynthesized(range) { + return ts.positionIsSynthesized(range.pos) + || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { @@ -20010,7 +20011,10 @@ var ts; } return true; } - if (usage.parent.kind === 246) { + if (usage.parent.kind === 246 || (usage.parent.kind === 243 && usage.parent.isExportEquals)) { + return true; + } + if (usage.kind === 243 && usage.isExportEquals) { return true; } var container = ts.getEnclosingBlockScopeContainer(declaration); @@ -24678,6 +24682,9 @@ var ts; } return signature.resolvedReturnType; } + function isResolvingReturnTypeOfSignature(signature) { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3) >= 0; + } function getRestTypeOfSignature(signature) { if (signature.hasRestParameter) { var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters)); @@ -29785,7 +29792,7 @@ var ts; return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); } var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); - if (signature) { + if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } return undefined; @@ -32075,7 +32082,7 @@ var ts; return result; } function isJavaScriptConstructor(node) { - if (ts.isInJavaScriptFile(node)) { + if (node && ts.isInJavaScriptFile(node)) { if (ts.getJSDocClassTag(node)) return true; var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) : @@ -32085,6 +32092,20 @@ var ts; } return false; } + function getJavaScriptClassType(symbol) { + if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = getSymbolOfNode(symbol.valueDeclaration.initializer); + } + if (isJavaScriptConstructor(symbol.valueDeclaration)) { + return getInferredClassType(symbol); + } + if (symbol.flags & 3) { + var valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + return getInferredClassType(valueType.symbol); + } + } + } function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { @@ -32113,13 +32134,11 @@ var ts; var funcSymbol = node.expression.kind === 71 ? getResolvedSymbol(node.expression) : checkExpression(node.expression).symbol; - if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) { - funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer); - } - if (funcSymbol && funcSymbol.flags & 16 && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) { - return getInferredClassType(funcSymbol); + var type = funcSymbol && getJavaScriptClassType(funcSymbol); + if (type) { + return type; } - else if (noImplicitAny) { + if (noImplicitAny) { error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -34280,6 +34299,7 @@ var ts; : 4; case 229: case 232: + case 240: return 2 | 1; case 237: var result_3 = 0; @@ -37452,6 +37472,14 @@ var ts; return type.flags & 32768 && getSignaturesOfType(type, 0).length > 0; } function getTypeReferenceSerializationKind(typeName, location) { + typeName = ts.getParseTreeNode(typeName, ts.isEntityName); + if (!typeName) + return ts.TypeReferenceSerializationKind.Unknown; + if (location) { + location = ts.getParseTreeNode(location); + if (!location) + return ts.TypeReferenceSerializationKind.Unknown; + } var valueSymbol = resolveEntityName(typeName, 107455, true, false, location); var typeSymbol = resolveEntityName(typeName, 793064, true, false, location); if (valueSymbol && valueSymbol === typeSymbol) { @@ -40909,6 +40937,10 @@ var ts; return createCall(createFunctionExpression(undefined, undefined, undefined, undefined, param ? [param] : [], undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression; + function createImmediatelyInvokedArrowFunction(statements, param, paramValue) { + return createCall(createArrowFunction(undefined, undefined, param ? [param] : [], undefined, undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []); + } + ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction; function createComma(left, right) { return createBinary(left, 26, right); } @@ -41999,9 +42031,17 @@ var ts; case 288: return ts.updatePartiallyEmittedExpression(outerExpression, expression); } } + function isIgnorableParen(node) { + return node.kind === 185 + && ts.nodeIsSynthesized(node) + && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) + && ts.nodeIsSynthesized(ts.getCommentRange(node)) + && !ts.some(ts.getSyntheticLeadingComments(node)) + && !ts.some(ts.getSyntheticTrailingComments(node)); + } function recreateOuterExpressions(outerExpression, innerExpression, kinds) { if (kinds === void 0) { kinds = 7; } - if (outerExpression && isOuterExpression(outerExpression, kinds)) { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; @@ -43227,7 +43267,7 @@ var ts; } else { var name = node.name; - if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true); exportedNames = ts.append(exportedNames, name); @@ -43927,8 +43967,10 @@ var ts; ts.setEmitFlags(statement, 1536 | 384); statements.push(statement); ts.addRange(statements, context.endLexicalEnvironment()); + var iife = ts.createImmediatelyInvokedArrowFunction(statements); + ts.setEmitFlags(iife, 33554432); var varStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ - ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, ts.createImmediatelyInvokedFunctionExpression(statements)) + ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, iife) ])); ts.setOriginalNode(varStatement, node); ts.setCommentRange(varStatement, node); @@ -44534,7 +44576,7 @@ var ts; var name = ts.getMutableClone(node); name.flags &= ~8; name.original = undefined; - name.parent = currentScope; + name.parent = ts.getParseTreeNode(currentScope); if (useFallback) { return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name); } @@ -45626,7 +45668,7 @@ var ts; chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression))); } else { - chunkObject.push(e); + chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike)); } } } @@ -46641,58 +46683,12 @@ var ts; && node.kind === 219 && !node.expression; } - function isClassLikeVariableStatement(node) { - if (!ts.isVariableStatement(node)) - return false; - var variable = ts.singleOrUndefined(node.declarationList.declarations); - return variable - && variable.initializer - && ts.isIdentifier(variable.name) - && (ts.isClassLike(variable.initializer) - || (ts.isAssignmentExpression(variable.initializer) - && ts.isIdentifier(variable.initializer.left) - && ts.isClassLike(variable.initializer.right))); - } - function isTypeScriptClassWrapper(node) { - var call = ts.tryCast(node, ts.isCallExpression); - if (!call || ts.isParseTreeNode(call) || - ts.some(call.typeArguments) || - ts.some(call.arguments)) { - return false; - } - var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression); - if (!func || ts.isParseTreeNode(func) || - ts.some(func.typeParameters) || - ts.some(func.parameters) || - func.type || - !func.body) { - return false; - } - var statements = func.body.statements; - if (statements.length < 2) { - return false; - } - var firstStatement = statements[0]; - if (ts.isParseTreeNode(firstStatement) || - !ts.isClassLike(firstStatement) && - !isClassLikeVariableStatement(firstStatement)) { - return false; - } - var lastStatement = ts.elementAt(statements, -1); - var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement); - if (!returnStatement || - !returnStatement.expression || - !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) { - return false; - } - return true; - } function shouldVisitNode(node) { return (node.transformFlags & 128) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207))) || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node)) - || isTypeScriptClassWrapper(node); + || (ts.getEmitFlags(node) & 33554432) !== 0; } function visitor(node) { if (shouldVisitNode(node)) { @@ -48172,7 +48168,7 @@ var ts; return ts.visitEachChild(node, visitor, context); } function visitCallExpression(node) { - if (isTypeScriptClassWrapper(node)) { + if (ts.getEmitFlags(node) & 33554432) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & 64) { @@ -48181,7 +48177,7 @@ var ts; return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression)); } function visitTypeScriptClassWrapper(node) { - var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body; + var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock); var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1); var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1); var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement); @@ -49351,8 +49347,12 @@ var ts; } function transformAndEmitContinueStatement(node) { var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label."); - emitBreak(label, node); + if (label > 0) { + emitBreak(label, node); + } + else { + emitStatement(node); + } } function visitContinueStatement(node) { if (inStatementContainingYield) { @@ -49365,8 +49365,12 @@ var ts; } function transformAndEmitBreakStatement(node) { var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label."); - emitBreak(label, node); + if (label > 0) { + emitBreak(label, node); + } + else { + emitStatement(node); + } } function visitBreakStatement(node) { if (inStatementContainingYield) { @@ -49790,43 +49794,45 @@ var ts; return false; } function findBreakTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { - return block.breakLabel; - } - else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.breakLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { + return block.breakLabel; + } + else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.breakLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledBreak(block)) { - return block.breakLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledBreak(block)) { + return block.breakLabel; + } } } } return 0; } function findContinueTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.continueLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.continueLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block)) { - return block.continueLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block)) { + return block.continueLabel; + } } } } @@ -50450,17 +50456,23 @@ var ts; } function addExportEqualsIfNeeded(statements, emitAsReturn) { if (currentModuleInfo.exportEquals) { - if (emitAsReturn) { - var statement = ts.createReturn(currentModuleInfo.exportEquals.expression); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 384 | 1536); - statements.push(statement); - } - else { - var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression)); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 1536); - statements.push(statement); + var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression); + if (expressionResult) { + if (expressionResult instanceof Array) { + return ts.Debug.fail("export= expression should never be replaced with multiple expressions!"); + } + if (emitAsReturn) { + var statement = ts.createReturn(expressionResult); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 384 | 1536); + statements.push(statement); + } + else { + var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult)); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 1536); + statements.push(statement); + } } } } @@ -50794,7 +50806,7 @@ var ts; return statements; } if (ts.hasModifier(decl, 1)) { - var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : decl.name; + var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : ts.getDeclarationName(decl); statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), decl); } if (decl.name) { @@ -74613,12 +74625,7 @@ var ts; if (errors) { return { errors: errors }; } - var range = ts.isStatement(start) - ? [start] - : start.parent && start.parent.kind === 210 - ? [start.parent] - : start; - return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } }; } function createErrorResult(sourceFile, start, length, message) { return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; @@ -74803,6 +74810,15 @@ var ts; } } extractMethod_1.getRangeToExtract = getRangeToExtract; + function getStatementOrExpressionRange(node) { + if (ts.isStatement(node)) { + return [node]; + } + else if (ts.isPartOfExpression(node)) { + return ts.isExpressionStatement(node.parent) ? [node.parent] : node; + } + return undefined; + } function isValidExtractionTarget(node) { return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); } @@ -74871,32 +74887,32 @@ var ts; return "constructor"; case 186: return scope.name - ? "function expression " + scope.name.getText() + ? "function expression " + scope.name.text : "anonymous function expression"; case 228: - return "function " + scope.name.getText(); + return "function '" + scope.name.text + "'"; case 187: return "arrow function"; case 151: - return "method " + scope.name.getText(); + return "method '" + scope.name.getText(); case 153: - return "get " + scope.name.getText(); + return "'get " + scope.name.getText() + "'"; case 154: - return "set " + scope.name.getText(); + return "'set " + scope.name.getText() + "'"; } } else if (isModuleBlock(scope)) { - return "namespace " + scope.parent.name.getText(); + return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { return scope.kind === 229 - ? "class " + scope.name.text + ? "class '" + scope.name.text + "'" : scope.name.text - ? "class expression " + scope.name.text + ? "class expression '" + scope.name.text + "'" : "anonymous class expression"; } else if (ts.isSourceFile(scope)) { - return "file '" + scope.fileName + "'"; + return scope.externalModuleIndicator ? "module scope" : "global scope"; } else { return "unknown"; diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index a51e9e77838a9..4c27618e03201 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2996,6 +2996,8 @@ declare namespace ts { function updateBundle(node: Bundle, sourceFiles: SourceFile[]): Bundle; function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression; function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; function createComma(left: Expression, right: Expression): Expression; function createLessThan(left: Expression, right: Expression): Expression; function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 164733f4e69ba..62fb59bbcd19d 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -1066,6 +1066,7 @@ var ts; EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker"; EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator"; EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping"; + EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper"; })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {})); var ExternalEmitHelpers; (function (ExternalEmitHelpers) { @@ -4557,7 +4558,7 @@ var ts; Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), - Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"), }; })(ts || (ts = {})); var ts; @@ -6330,9 +6331,9 @@ var ts; || kind === 265; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; - function nodeIsSynthesized(node) { - return ts.positionIsSynthesized(node.pos) - || ts.positionIsSynthesized(node.end); + function nodeIsSynthesized(range) { + return ts.positionIsSynthesized(range.pos) + || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { @@ -21716,7 +21717,10 @@ var ts; } return true; } - if (usage.parent.kind === 246) { + if (usage.parent.kind === 246 || (usage.parent.kind === 243 && usage.parent.isExportEquals)) { + return true; + } + if (usage.kind === 243 && usage.isExportEquals) { return true; } var container = ts.getEnclosingBlockScopeContainer(declaration); @@ -26384,6 +26388,9 @@ var ts; } return signature.resolvedReturnType; } + function isResolvingReturnTypeOfSignature(signature) { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3) >= 0; + } function getRestTypeOfSignature(signature) { if (signature.hasRestParameter) { var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters)); @@ -31491,7 +31498,7 @@ var ts; return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); } var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); - if (signature) { + if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } return undefined; @@ -33781,7 +33788,7 @@ var ts; return result; } function isJavaScriptConstructor(node) { - if (ts.isInJavaScriptFile(node)) { + if (node && ts.isInJavaScriptFile(node)) { if (ts.getJSDocClassTag(node)) return true; var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) : @@ -33791,6 +33798,20 @@ var ts; } return false; } + function getJavaScriptClassType(symbol) { + if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = getSymbolOfNode(symbol.valueDeclaration.initializer); + } + if (isJavaScriptConstructor(symbol.valueDeclaration)) { + return getInferredClassType(symbol); + } + if (symbol.flags & 3) { + var valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + return getInferredClassType(valueType.symbol); + } + } + } function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { @@ -33819,13 +33840,11 @@ var ts; var funcSymbol = node.expression.kind === 71 ? getResolvedSymbol(node.expression) : checkExpression(node.expression).symbol; - if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) { - funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer); - } - if (funcSymbol && funcSymbol.flags & 16 && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) { - return getInferredClassType(funcSymbol); + var type = funcSymbol && getJavaScriptClassType(funcSymbol); + if (type) { + return type; } - else if (noImplicitAny) { + if (noImplicitAny) { error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -35986,6 +36005,7 @@ var ts; : 4; case 229: case 232: + case 240: return 2 | 1; case 237: var result_3 = 0; @@ -39158,6 +39178,14 @@ var ts; return type.flags & 32768 && getSignaturesOfType(type, 0).length > 0; } function getTypeReferenceSerializationKind(typeName, location) { + typeName = ts.getParseTreeNode(typeName, ts.isEntityName); + if (!typeName) + return ts.TypeReferenceSerializationKind.Unknown; + if (location) { + location = ts.getParseTreeNode(location); + if (!location) + return ts.TypeReferenceSerializationKind.Unknown; + } var valueSymbol = resolveEntityName(typeName, 107455, true, false, location); var typeSymbol = resolveEntityName(typeName, 793064, true, false, location); if (valueSymbol && valueSymbol === typeSymbol) { @@ -42615,6 +42643,10 @@ var ts; return createCall(createFunctionExpression(undefined, undefined, undefined, undefined, param ? [param] : [], undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression; + function createImmediatelyInvokedArrowFunction(statements, param, paramValue) { + return createCall(createArrowFunction(undefined, undefined, param ? [param] : [], undefined, undefined, createBlock(statements, true)), undefined, paramValue ? [paramValue] : []); + } + ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction; function createComma(left, right) { return createBinary(left, 26, right); } @@ -43705,9 +43737,17 @@ var ts; case 288: return ts.updatePartiallyEmittedExpression(outerExpression, expression); } } + function isIgnorableParen(node) { + return node.kind === 185 + && ts.nodeIsSynthesized(node) + && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) + && ts.nodeIsSynthesized(ts.getCommentRange(node)) + && !ts.some(ts.getSyntheticLeadingComments(node)) + && !ts.some(ts.getSyntheticTrailingComments(node)); + } function recreateOuterExpressions(outerExpression, innerExpression, kinds) { if (kinds === void 0) { kinds = 7; } - if (outerExpression && isOuterExpression(outerExpression, kinds)) { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; @@ -44933,7 +44973,7 @@ var ts; } else { var name = node.name; - if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true); exportedNames = ts.append(exportedNames, name); @@ -45633,8 +45673,10 @@ var ts; ts.setEmitFlags(statement, 1536 | 384); statements.push(statement); ts.addRange(statements, context.endLexicalEnvironment()); + var iife = ts.createImmediatelyInvokedArrowFunction(statements); + ts.setEmitFlags(iife, 33554432); var varStatement = ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ - ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, ts.createImmediatelyInvokedFunctionExpression(statements)) + ts.createVariableDeclaration(ts.getLocalName(node, false, false), undefined, iife) ])); ts.setOriginalNode(varStatement, node); ts.setCommentRange(varStatement, node); @@ -46240,7 +46282,7 @@ var ts; var name = ts.getMutableClone(node); name.flags &= ~8; name.original = undefined; - name.parent = currentScope; + name.parent = ts.getParseTreeNode(currentScope); if (useFallback) { return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name); } @@ -47332,7 +47374,7 @@ var ts; chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression))); } else { - chunkObject.push(e); + chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike)); } } } @@ -48347,58 +48389,12 @@ var ts; && node.kind === 219 && !node.expression; } - function isClassLikeVariableStatement(node) { - if (!ts.isVariableStatement(node)) - return false; - var variable = ts.singleOrUndefined(node.declarationList.declarations); - return variable - && variable.initializer - && ts.isIdentifier(variable.name) - && (ts.isClassLike(variable.initializer) - || (ts.isAssignmentExpression(variable.initializer) - && ts.isIdentifier(variable.initializer.left) - && ts.isClassLike(variable.initializer.right))); - } - function isTypeScriptClassWrapper(node) { - var call = ts.tryCast(node, ts.isCallExpression); - if (!call || ts.isParseTreeNode(call) || - ts.some(call.typeArguments) || - ts.some(call.arguments)) { - return false; - } - var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression); - if (!func || ts.isParseTreeNode(func) || - ts.some(func.typeParameters) || - ts.some(func.parameters) || - func.type || - !func.body) { - return false; - } - var statements = func.body.statements; - if (statements.length < 2) { - return false; - } - var firstStatement = statements[0]; - if (ts.isParseTreeNode(firstStatement) || - !ts.isClassLike(firstStatement) && - !isClassLikeVariableStatement(firstStatement)) { - return false; - } - var lastStatement = ts.elementAt(statements, -1); - var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement); - if (!returnStatement || - !returnStatement.expression || - !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) { - return false; - } - return true; - } function shouldVisitNode(node) { return (node.transformFlags & 128) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & 4096 && (ts.isStatement(node) || (node.kind === 207))) || (ts.isIterationStatement(node, false) && shouldConvertIterationStatementBody(node)) - || isTypeScriptClassWrapper(node); + || (ts.getEmitFlags(node) & 33554432) !== 0; } function visitor(node) { if (shouldVisitNode(node)) { @@ -49878,7 +49874,7 @@ var ts; return ts.visitEachChild(node, visitor, context); } function visitCallExpression(node) { - if (isTypeScriptClassWrapper(node)) { + if (ts.getEmitFlags(node) & 33554432) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & 64) { @@ -49887,7 +49883,7 @@ var ts; return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression)); } function visitTypeScriptClassWrapper(node) { - var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body; + var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock); var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1); var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1); var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement); @@ -51057,8 +51053,12 @@ var ts; } function transformAndEmitContinueStatement(node) { var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label."); - emitBreak(label, node); + if (label > 0) { + emitBreak(label, node); + } + else { + emitStatement(node); + } } function visitContinueStatement(node) { if (inStatementContainingYield) { @@ -51071,8 +51071,12 @@ var ts; } function transformAndEmitBreakStatement(node) { var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label."); - emitBreak(label, node); + if (label > 0) { + emitBreak(label, node); + } + else { + emitStatement(node); + } } function visitBreakStatement(node) { if (inStatementContainingYield) { @@ -51496,43 +51500,45 @@ var ts; return false; } function findBreakTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { - return block.breakLabel; - } - else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.breakLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { + return block.breakLabel; + } + else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.breakLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledBreak(block)) { - return block.breakLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledBreak(block)) { + return block.breakLabel; + } } } } return 0; } function findContinueTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.continueLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.continueLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block)) { - return block.continueLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block)) { + return block.continueLabel; + } } } } @@ -52156,17 +52162,23 @@ var ts; } function addExportEqualsIfNeeded(statements, emitAsReturn) { if (currentModuleInfo.exportEquals) { - if (emitAsReturn) { - var statement = ts.createReturn(currentModuleInfo.exportEquals.expression); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 384 | 1536); - statements.push(statement); - } - else { - var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression)); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 1536); - statements.push(statement); + var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression); + if (expressionResult) { + if (expressionResult instanceof Array) { + return ts.Debug.fail("export= expression should never be replaced with multiple expressions!"); + } + if (emitAsReturn) { + var statement = ts.createReturn(expressionResult); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 384 | 1536); + statements.push(statement); + } + else { + var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult)); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 1536); + statements.push(statement); + } } } } @@ -52500,7 +52512,7 @@ var ts; return statements; } if (ts.hasModifier(decl, 1)) { - var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : decl.name; + var exportName = ts.hasModifier(decl, 512) ? ts.createIdentifier("default") : ts.getDeclarationName(decl); statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), decl); } if (decl.name) { @@ -74613,12 +74625,7 @@ var ts; if (errors) { return { errors: errors }; } - var range = ts.isStatement(start) - ? [start] - : start.parent && start.parent.kind === 210 - ? [start.parent] - : start; - return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } }; } function createErrorResult(sourceFile, start, length, message) { return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; @@ -74803,6 +74810,15 @@ var ts; } } extractMethod_1.getRangeToExtract = getRangeToExtract; + function getStatementOrExpressionRange(node) { + if (ts.isStatement(node)) { + return [node]; + } + else if (ts.isPartOfExpression(node)) { + return ts.isExpressionStatement(node.parent) ? [node.parent] : node; + } + return undefined; + } function isValidExtractionTarget(node) { return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); } @@ -74871,32 +74887,32 @@ var ts; return "constructor"; case 186: return scope.name - ? "function expression " + scope.name.getText() + ? "function expression " + scope.name.text : "anonymous function expression"; case 228: - return "function " + scope.name.getText(); + return "function '" + scope.name.text + "'"; case 187: return "arrow function"; case 151: - return "method " + scope.name.getText(); + return "method '" + scope.name.getText(); case 153: - return "get " + scope.name.getText(); + return "'get " + scope.name.getText() + "'"; case 154: - return "set " + scope.name.getText(); + return "'set " + scope.name.getText() + "'"; } } else if (isModuleBlock(scope)) { - return "namespace " + scope.parent.name.getText(); + return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { return scope.kind === 229 - ? "class " + scope.name.text + ? "class '" + scope.name.text + "'" : scope.name.text - ? "class expression " + scope.name.text + ? "class expression '" + scope.name.text + "'" : "anonymous class expression"; } else if (ts.isSourceFile(scope)) { - return "file '" + scope.fileName + "'"; + return scope.externalModuleIndicator ? "module scope" : "global scope"; } else { return "unknown"; diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index bec9e8609c820..2ebd420e7c8c1 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -3388,6 +3388,8 @@ declare namespace ts { function updateBundle(node: Bundle, sourceFiles: SourceFile[]): Bundle; function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression; function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; function createComma(left: Expression, right: Expression): Expression; function createLessThan(left: Expression, right: Expression): Expression; function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; diff --git a/lib/typescript.js b/lib/typescript.js index 3b497d4c471b4..5762e9133e61c 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -1201,6 +1201,7 @@ var ts; EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker"; EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator"; EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping"; + /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper"; })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {})); /** * Used by the checker, this enum keeps track of external emit helpers that should be type @@ -5080,7 +5081,7 @@ var ts; Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), - Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"), }; })(ts || (ts = {})); /// @@ -8844,9 +8845,9 @@ var ts; || kind === 265 /* SourceFile */; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; - function nodeIsSynthesized(node) { - return ts.positionIsSynthesized(node.pos) - || ts.positionIsSynthesized(node.end); + function nodeIsSynthesized(range) { + return ts.positionIsSynthesized(range.pos) + || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { @@ -23319,12 +23320,17 @@ var ts; // 2. inside a function // 3. inside an instance property initializer, a reference to a non-instance property // 4. inside a static property initializer, a reference to a static method in the same class + // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ) // or if usage is in a type context: // 1. inside a type query (typeof in type position) - if (usage.parent.kind === 246 /* ExportSpecifier */) { + if (usage.parent.kind === 246 /* ExportSpecifier */ || (usage.parent.kind === 243 /* ExportAssignment */ && usage.parent.isExportEquals)) { // export specifiers do not use the variable, they only make it available for use return true; } + // When resolving symbols for exports, the `usage` location passed in can be the export site directly + if (usage.kind === 243 /* ExportAssignment */ && usage.isExportEquals) { + return true; + } var container = ts.getEnclosingBlockScopeContainer(declaration); return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container); function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) { @@ -28615,6 +28621,9 @@ var ts; } return signature.resolvedReturnType; } + function isResolvingReturnTypeOfSignature(signature) { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0; + } function getRestTypeOfSignature(signature) { if (signature.hasRestParameter) { var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters)); @@ -34496,7 +34505,7 @@ var ts; // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature // and that call signature is non-generic, return statements are contextually typed by the return type of the signature var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); - if (signature) { + if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } return undefined; @@ -37549,7 +37558,7 @@ var ts; * file. */ function isJavaScriptConstructor(node) { - if (ts.isInJavaScriptFile(node)) { + if (node && ts.isInJavaScriptFile(node)) { // If the node has a @class tag, treat it like a constructor. if (ts.getJSDocClassTag(node)) return true; @@ -37561,6 +37570,20 @@ var ts; } return false; } + function getJavaScriptClassType(symbol) { + if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = getSymbolOfNode(symbol.valueDeclaration.initializer); + } + if (isJavaScriptConstructor(symbol.valueDeclaration)) { + return getInferredClassType(symbol); + } + if (symbol.flags & 3 /* Variable */) { + var valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + return getInferredClassType(valueType.symbol); + } + } + } function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { @@ -37600,13 +37623,11 @@ var ts; var funcSymbol = node.expression.kind === 71 /* Identifier */ ? getResolvedSymbol(node.expression) : checkExpression(node.expression).symbol; - if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) { - funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer); - } - if (funcSymbol && funcSymbol.flags & 16 /* Function */ && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) { - return getInferredClassType(funcSymbol); + var type = funcSymbol && getJavaScriptClassType(funcSymbol); + if (type) { + return type; } - else if (noImplicitAny) { + if (noImplicitAny) { error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -40064,6 +40085,8 @@ var ts; : 4 /* ExportNamespace */; case 229 /* ClassDeclaration */: case 232 /* EnumDeclaration */: + // A NamespaceImport declares an Alias, which is allowed to merge with other values within the module + case 240 /* NamespaceImport */: return 2 /* ExportType */ | 1 /* ExportValue */; case 237 /* ImportEqualsDeclaration */: var result_3 = 0 /* None */; @@ -43921,6 +43944,15 @@ var ts; return type.flags & 32768 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0; } function getTypeReferenceSerializationKind(typeName, location) { + // ensure both `typeName` and `location` are parse tree nodes. + typeName = ts.getParseTreeNode(typeName, ts.isEntityName); + if (!typeName) + return ts.TypeReferenceSerializationKind.Unknown; + if (location) { + location = ts.getParseTreeNode(location); + if (!location) + return ts.TypeReferenceSerializationKind.Unknown; + } // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. var valueSymbol = resolveEntityName(typeName, 107455 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. @@ -47563,6 +47595,17 @@ var ts; /*argumentsArray*/ paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression; + function createImmediatelyInvokedArrowFunction(statements, param, paramValue) { + return createCall(createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ param ? [param] : [], + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), + /*typeArguments*/ undefined, + /*argumentsArray*/ paramValue ? [paramValue] : []); + } + ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction; function createComma(left, right) { return createBinary(left, 26 /* CommaToken */, right); } @@ -48963,9 +49006,31 @@ var ts; case 288 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression); } } + /** + * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. + * + * A parenthesized expression can be ignored when all of the following are true: + * + * - It's `pos` and `end` are not -1 + * - It does not have a custom source map range + * - It does not have a custom comment range + * - It does not have synthetic leading or trailing comments + * + * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around + * the expression to maintain precedence, a new parenthesized expression should be created automatically when + * the containing expression is created/updated. + */ + function isIgnorableParen(node) { + return node.kind === 185 /* ParenthesizedExpression */ + && ts.nodeIsSynthesized(node) + && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) + && ts.nodeIsSynthesized(ts.getCommentRange(node)) + && !ts.some(ts.getSyntheticLeadingComments(node)) + && !ts.some(ts.getSyntheticTrailingComments(node)); + } function recreateOuterExpressions(outerExpression, innerExpression, kinds) { if (kinds === void 0) { kinds = 7 /* All */; } - if (outerExpression && isOuterExpression(outerExpression, kinds)) { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; @@ -50417,7 +50482,7 @@ var ts; else { // export class x { } var name = node.name; - if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true); exportedNames = ts.append(exportedNames, name); @@ -51435,10 +51500,12 @@ var ts; ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */); statements.push(statement); ts.addRange(statements, context.endLexicalEnvironment()); + var iife = ts.createImmediatelyInvokedArrowFunction(statements); + ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */); var varStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), - /*type*/ undefined, ts.createImmediatelyInvokedFunctionExpression(statements)) + /*type*/ undefined, iife) ])); ts.setOriginalNode(varStatement, node); ts.setCommentRange(varStatement, node); @@ -52541,7 +52608,7 @@ var ts; var name = ts.getMutableClone(node); name.flags &= ~8 /* Synthesized */; name.original = undefined; - name.parent = currentScope; + name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node. if (useFallback) { return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name); } @@ -54222,7 +54289,7 @@ var ts; chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression))); } else { - chunkObject.push(e); + chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike)); } } } @@ -55457,58 +55524,12 @@ var ts; && node.kind === 219 /* ReturnStatement */ && !node.expression; } - function isClassLikeVariableStatement(node) { - if (!ts.isVariableStatement(node)) - return false; - var variable = ts.singleOrUndefined(node.declarationList.declarations); - return variable - && variable.initializer - && ts.isIdentifier(variable.name) - && (ts.isClassLike(variable.initializer) - || (ts.isAssignmentExpression(variable.initializer) - && ts.isIdentifier(variable.initializer.left) - && ts.isClassLike(variable.initializer.right))); - } - function isTypeScriptClassWrapper(node) { - var call = ts.tryCast(node, ts.isCallExpression); - if (!call || ts.isParseTreeNode(call) || - ts.some(call.typeArguments) || - ts.some(call.arguments)) { - return false; - } - var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression); - if (!func || ts.isParseTreeNode(func) || - ts.some(func.typeParameters) || - ts.some(func.parameters) || - func.type || - !func.body) { - return false; - } - var statements = func.body.statements; - if (statements.length < 2) { - return false; - } - var firstStatement = statements[0]; - if (ts.isParseTreeNode(firstStatement) || - !ts.isClassLike(firstStatement) && - !isClassLikeVariableStatement(firstStatement)) { - return false; - } - var lastStatement = ts.elementAt(statements, -1); - var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement); - if (!returnStatement || - !returnStatement.expression || - !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) { - return false; - } - return true; - } function shouldVisitNode(node) { return (node.transformFlags & 128 /* ContainsES2015 */) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */))) || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)) - || isTypeScriptClassWrapper(node); + || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0; } function visitor(node) { if (shouldVisitNode(node)) { @@ -57643,7 +57664,7 @@ var ts; * @param node a CallExpression. */ function visitCallExpression(node) { - if (isTypeScriptClassWrapper(node)) { + if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & 64 /* ES2015 */) { @@ -57685,7 +57706,7 @@ var ts; // }()) // We skip any outer expressions in a number of places to get to the innermost // expression, but we will restore them later to preserve comments and source maps. - var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body; + var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock); // The class statements are the statements generated by visiting the first statement of the // body (1), while all other statements are added to remainingStatements (2) var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1); @@ -59725,8 +59746,13 @@ var ts; } function transformAndEmitContinueStatement(node) { var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label."); - emitBreak(label, /*location*/ node); + if (label > 0) { + emitBreak(label, /*location*/ node); + } + else { + // invalid continue without a containing loop. Leave the node as is, per #17875. + emitStatement(node); + } } function visitContinueStatement(node) { if (inStatementContainingYield) { @@ -59739,8 +59765,13 @@ var ts; } function transformAndEmitBreakStatement(node) { var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label."); - emitBreak(label, /*location*/ node); + if (label > 0) { + emitBreak(label, /*location*/ node); + } + else { + // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875. + emitStatement(node); + } } function visitBreakStatement(node) { if (inStatementContainingYield) { @@ -60344,23 +60375,24 @@ var ts; * @param labelText An optional name of a containing labeled statement. */ function findBreakTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { - return block.breakLabel; - } - else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.breakLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { + return block.breakLabel; + } + else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.breakLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledBreak(block)) { - return block.breakLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledBreak(block)) { + return block.breakLabel; + } } } } @@ -60372,20 +60404,21 @@ var ts; * @param labelText An optional name of a containing labeled statement. */ function findContinueTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.continueLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.continueLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block)) { - return block.continueLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block)) { + return block.continueLabel; + } } } } @@ -61344,17 +61377,23 @@ var ts; */ function addExportEqualsIfNeeded(statements, emitAsReturn) { if (currentModuleInfo.exportEquals) { - if (emitAsReturn) { - var statement = ts.createReturn(currentModuleInfo.exportEquals.expression); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */); - statements.push(statement); - } - else { - var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression)); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 1536 /* NoComments */); - statements.push(statement); + var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression); + if (expressionResult) { + if (expressionResult instanceof Array) { + return ts.Debug.fail("export= expression should never be replaced with multiple expressions!"); + } + if (emitAsReturn) { + var statement = ts.createReturn(expressionResult); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */); + statements.push(statement); + } + else { + var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult)); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 1536 /* NoComments */); + statements.push(statement); + } } } } @@ -61899,7 +61938,7 @@ var ts; return statements; } if (ts.hasModifier(decl, 1 /* Export */)) { - var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : decl.name; + var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl); statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl); } if (decl.name) { @@ -89591,16 +89630,7 @@ var ts; if (errors) { return { errors: errors }; } - // If our selection is the expression in an ExpressionStatement, expand - // the selection to include the enclosing Statement (this stops us - // from trying to care about the return value of the extracted function - // and eliminates double semicolon insertion in certain scenarios) - var range = ts.isStatement(start) - ? [start] - : start.parent && start.parent.kind === 210 /* ExpressionStatement */ - ? [start.parent] - : start; - return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } }; } function createErrorResult(sourceFile, start, length, message) { return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; @@ -89802,6 +89832,19 @@ var ts; } } extractMethod_1.getRangeToExtract = getRangeToExtract; + function getStatementOrExpressionRange(node) { + if (ts.isStatement(node)) { + return [node]; + } + else if (ts.isPartOfExpression(node)) { + // If our selection is the expression in an ExpressionStatement, expand + // the selection to include the enclosing Statement (this stops us + // from trying to care about the return value of the extracted function + // and eliminates double semicolon insertion in certain scenarios) + return ts.isExpressionStatement(node.parent) ? [node.parent] : node; + } + return undefined; + } function isValidExtractionTarget(node) { // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); @@ -89889,32 +89932,32 @@ var ts; return "constructor"; case 186 /* FunctionExpression */: return scope.name - ? "function expression " + scope.name.getText() + ? "function expression " + scope.name.text : "anonymous function expression"; case 228 /* FunctionDeclaration */: - return "function " + scope.name.getText(); + return "function '" + scope.name.text + "'"; case 187 /* ArrowFunction */: return "arrow function"; case 151 /* MethodDeclaration */: - return "method " + scope.name.getText(); + return "method '" + scope.name.getText(); case 153 /* GetAccessor */: - return "get " + scope.name.getText(); + return "'get " + scope.name.getText() + "'"; case 154 /* SetAccessor */: - return "set " + scope.name.getText(); + return "'set " + scope.name.getText() + "'"; } } else if (isModuleBlock(scope)) { - return "namespace " + scope.parent.name.getText(); + return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { return scope.kind === 229 /* ClassDeclaration */ - ? "class " + scope.name.text + ? "class '" + scope.name.text + "'" : scope.name.text - ? "class expression " + scope.name.text + ? "class expression '" + scope.name.text + "'" : "anonymous class expression"; } else if (ts.isSourceFile(scope)) { - return "file '" + scope.fileName + "'"; + return scope.externalModuleIndicator ? "module scope" : "global scope"; } else { return "unknown"; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index c41b2e65a9552..7051b32c4ac0b 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -3388,6 +3388,8 @@ declare namespace ts { function updateBundle(node: Bundle, sourceFiles: SourceFile[]): Bundle; function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression; function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; function createComma(left: Expression, right: Expression): Expression; function createLessThan(left: Expression, right: Expression): Expression; function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 3b497d4c471b4..5762e9133e61c 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -1201,6 +1201,7 @@ var ts; EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker"; EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator"; EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping"; + /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper"; })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {})); /** * Used by the checker, this enum keeps track of external emit helpers that should be type @@ -5080,7 +5081,7 @@ var ts; Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), - Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"), }; })(ts || (ts = {})); /// @@ -8844,9 +8845,9 @@ var ts; || kind === 265 /* SourceFile */; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; - function nodeIsSynthesized(node) { - return ts.positionIsSynthesized(node.pos) - || ts.positionIsSynthesized(node.end); + function nodeIsSynthesized(range) { + return ts.positionIsSynthesized(range.pos) + || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { @@ -23319,12 +23320,17 @@ var ts; // 2. inside a function // 3. inside an instance property initializer, a reference to a non-instance property // 4. inside a static property initializer, a reference to a static method in the same class + // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ) // or if usage is in a type context: // 1. inside a type query (typeof in type position) - if (usage.parent.kind === 246 /* ExportSpecifier */) { + if (usage.parent.kind === 246 /* ExportSpecifier */ || (usage.parent.kind === 243 /* ExportAssignment */ && usage.parent.isExportEquals)) { // export specifiers do not use the variable, they only make it available for use return true; } + // When resolving symbols for exports, the `usage` location passed in can be the export site directly + if (usage.kind === 243 /* ExportAssignment */ && usage.isExportEquals) { + return true; + } var container = ts.getEnclosingBlockScopeContainer(declaration); return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container); function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) { @@ -28615,6 +28621,9 @@ var ts; } return signature.resolvedReturnType; } + function isResolvingReturnTypeOfSignature(signature) { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0; + } function getRestTypeOfSignature(signature) { if (signature.hasRestParameter) { var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters)); @@ -34496,7 +34505,7 @@ var ts; // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature // and that call signature is non-generic, return statements are contextually typed by the return type of the signature var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); - if (signature) { + if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } return undefined; @@ -37549,7 +37558,7 @@ var ts; * file. */ function isJavaScriptConstructor(node) { - if (ts.isInJavaScriptFile(node)) { + if (node && ts.isInJavaScriptFile(node)) { // If the node has a @class tag, treat it like a constructor. if (ts.getJSDocClassTag(node)) return true; @@ -37561,6 +37570,20 @@ var ts; } return false; } + function getJavaScriptClassType(symbol) { + if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { + symbol = getSymbolOfNode(symbol.valueDeclaration.initializer); + } + if (isJavaScriptConstructor(symbol.valueDeclaration)) { + return getInferredClassType(symbol); + } + if (symbol.flags & 3 /* Variable */) { + var valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + return getInferredClassType(valueType.symbol); + } + } + } function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { @@ -37600,13 +37623,11 @@ var ts; var funcSymbol = node.expression.kind === 71 /* Identifier */ ? getResolvedSymbol(node.expression) : checkExpression(node.expression).symbol; - if (funcSymbol && ts.isDeclarationOfFunctionOrClassExpression(funcSymbol)) { - funcSymbol = getSymbolOfNode(funcSymbol.valueDeclaration.initializer); - } - if (funcSymbol && funcSymbol.flags & 16 /* Function */ && (funcSymbol.members || ts.getJSDocClassTag(funcSymbol.valueDeclaration))) { - return getInferredClassType(funcSymbol); + var type = funcSymbol && getJavaScriptClassType(funcSymbol); + if (type) { + return type; } - else if (noImplicitAny) { + if (noImplicitAny) { error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -40064,6 +40085,8 @@ var ts; : 4 /* ExportNamespace */; case 229 /* ClassDeclaration */: case 232 /* EnumDeclaration */: + // A NamespaceImport declares an Alias, which is allowed to merge with other values within the module + case 240 /* NamespaceImport */: return 2 /* ExportType */ | 1 /* ExportValue */; case 237 /* ImportEqualsDeclaration */: var result_3 = 0 /* None */; @@ -43921,6 +43944,15 @@ var ts; return type.flags & 32768 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0; } function getTypeReferenceSerializationKind(typeName, location) { + // ensure both `typeName` and `location` are parse tree nodes. + typeName = ts.getParseTreeNode(typeName, ts.isEntityName); + if (!typeName) + return ts.TypeReferenceSerializationKind.Unknown; + if (location) { + location = ts.getParseTreeNode(location); + if (!location) + return ts.TypeReferenceSerializationKind.Unknown; + } // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. var valueSymbol = resolveEntityName(typeName, 107455 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. @@ -47563,6 +47595,17 @@ var ts; /*argumentsArray*/ paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression; + function createImmediatelyInvokedArrowFunction(statements, param, paramValue) { + return createCall(createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ param ? [param] : [], + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), + /*typeArguments*/ undefined, + /*argumentsArray*/ paramValue ? [paramValue] : []); + } + ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction; function createComma(left, right) { return createBinary(left, 26 /* CommaToken */, right); } @@ -48963,9 +49006,31 @@ var ts; case 288 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression); } } + /** + * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. + * + * A parenthesized expression can be ignored when all of the following are true: + * + * - It's `pos` and `end` are not -1 + * - It does not have a custom source map range + * - It does not have a custom comment range + * - It does not have synthetic leading or trailing comments + * + * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around + * the expression to maintain precedence, a new parenthesized expression should be created automatically when + * the containing expression is created/updated. + */ + function isIgnorableParen(node) { + return node.kind === 185 /* ParenthesizedExpression */ + && ts.nodeIsSynthesized(node) + && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) + && ts.nodeIsSynthesized(ts.getCommentRange(node)) + && !ts.some(ts.getSyntheticLeadingComments(node)) + && !ts.some(ts.getSyntheticTrailingComments(node)); + } function recreateOuterExpressions(outerExpression, innerExpression, kinds) { if (kinds === void 0) { kinds = 7 /* All */; } - if (outerExpression && isOuterExpression(outerExpression, kinds)) { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; @@ -50417,7 +50482,7 @@ var ts; else { // export class x { } var name = node.name; - if (!uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(ts.unescapeLeadingUnderscores(name.escapedText))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.unescapeLeadingUnderscores(name.escapedText), true); exportedNames = ts.append(exportedNames, name); @@ -51435,10 +51500,12 @@ var ts; ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */); statements.push(statement); ts.addRange(statements, context.endLexicalEnvironment()); + var iife = ts.createImmediatelyInvokedArrowFunction(statements); + ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */); var varStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), - /*type*/ undefined, ts.createImmediatelyInvokedFunctionExpression(statements)) + /*type*/ undefined, iife) ])); ts.setOriginalNode(varStatement, node); ts.setCommentRange(varStatement, node); @@ -52541,7 +52608,7 @@ var ts; var name = ts.getMutableClone(node); name.flags &= ~8 /* Synthesized */; name.original = undefined; - name.parent = currentScope; + name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node. if (useFallback) { return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name); } @@ -54222,7 +54289,7 @@ var ts; chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression))); } else { - chunkObject.push(e); + chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike)); } } } @@ -55457,58 +55524,12 @@ var ts; && node.kind === 219 /* ReturnStatement */ && !node.expression; } - function isClassLikeVariableStatement(node) { - if (!ts.isVariableStatement(node)) - return false; - var variable = ts.singleOrUndefined(node.declarationList.declarations); - return variable - && variable.initializer - && ts.isIdentifier(variable.name) - && (ts.isClassLike(variable.initializer) - || (ts.isAssignmentExpression(variable.initializer) - && ts.isIdentifier(variable.initializer.left) - && ts.isClassLike(variable.initializer.right))); - } - function isTypeScriptClassWrapper(node) { - var call = ts.tryCast(node, ts.isCallExpression); - if (!call || ts.isParseTreeNode(call) || - ts.some(call.typeArguments) || - ts.some(call.arguments)) { - return false; - } - var func = ts.tryCast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression); - if (!func || ts.isParseTreeNode(func) || - ts.some(func.typeParameters) || - ts.some(func.parameters) || - func.type || - !func.body) { - return false; - } - var statements = func.body.statements; - if (statements.length < 2) { - return false; - } - var firstStatement = statements[0]; - if (ts.isParseTreeNode(firstStatement) || - !ts.isClassLike(firstStatement) && - !isClassLikeVariableStatement(firstStatement)) { - return false; - } - var lastStatement = ts.elementAt(statements, -1); - var returnStatement = ts.tryCast(ts.isVariableStatement(lastStatement) ? ts.elementAt(statements, -2) : lastStatement, ts.isReturnStatement); - if (!returnStatement || - !returnStatement.expression || - !ts.isIdentifier(ts.skipOuterExpressions(returnStatement.expression))) { - return false; - } - return true; - } function shouldVisitNode(node) { return (node.transformFlags & 128 /* ContainsES2015 */) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 207 /* Block */))) || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)) - || isTypeScriptClassWrapper(node); + || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0; } function visitor(node) { if (shouldVisitNode(node)) { @@ -57643,7 +57664,7 @@ var ts; * @param node a CallExpression. */ function visitCallExpression(node) { - if (isTypeScriptClassWrapper(node)) { + if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & 64 /* ES2015 */) { @@ -57685,7 +57706,7 @@ var ts; // }()) // We skip any outer expressions in a number of places to get to the innermost // expression, but we will restore them later to preserve comments and source maps. - var body = ts.cast(ts.skipOuterExpressions(node.expression), ts.isFunctionExpression).body; + var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock); // The class statements are the statements generated by visiting the first statement of the // body (1), while all other statements are added to remainingStatements (2) var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1); @@ -59725,8 +59746,13 @@ var ts; } function transformAndEmitContinueStatement(node) { var label = findContinueTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected continue statment to point to a valid Label."); - emitBreak(label, /*location*/ node); + if (label > 0) { + emitBreak(label, /*location*/ node); + } + else { + // invalid continue without a containing loop. Leave the node as is, per #17875. + emitStatement(node); + } } function visitContinueStatement(node) { if (inStatementContainingYield) { @@ -59739,8 +59765,13 @@ var ts; } function transformAndEmitBreakStatement(node) { var label = findBreakTarget(node.label ? ts.unescapeLeadingUnderscores(node.label.escapedText) : undefined); - ts.Debug.assert(label > 0, "Expected break statment to point to a valid Label."); - emitBreak(label, /*location*/ node); + if (label > 0) { + emitBreak(label, /*location*/ node); + } + else { + // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875. + emitStatement(node); + } } function visitBreakStatement(node) { if (inStatementContainingYield) { @@ -60344,23 +60375,24 @@ var ts; * @param labelText An optional name of a containing labeled statement. */ function findBreakTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { - return block.breakLabel; - } - else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.breakLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { + return block.breakLabel; + } + else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.breakLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledBreak(block)) { - return block.breakLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledBreak(block)) { + return block.breakLabel; + } } } } @@ -60372,20 +60404,21 @@ var ts; * @param labelText An optional name of a containing labeled statement. */ function findContinueTarget(labelText) { - ts.Debug.assert(blocks !== undefined); - if (labelText) { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { - return block.continueLabel; + if (blockStack) { + if (labelText) { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { + return block.continueLabel; + } } } - } - else { - for (var i = blockStack.length - 1; i >= 0; i--) { - var block = blockStack[i]; - if (supportsUnlabeledContinue(block)) { - return block.continueLabel; + else { + for (var i = blockStack.length - 1; i >= 0; i--) { + var block = blockStack[i]; + if (supportsUnlabeledContinue(block)) { + return block.continueLabel; + } } } } @@ -61344,17 +61377,23 @@ var ts; */ function addExportEqualsIfNeeded(statements, emitAsReturn) { if (currentModuleInfo.exportEquals) { - if (emitAsReturn) { - var statement = ts.createReturn(currentModuleInfo.exportEquals.expression); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */); - statements.push(statement); - } - else { - var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), currentModuleInfo.exportEquals.expression)); - ts.setTextRange(statement, currentModuleInfo.exportEquals); - ts.setEmitFlags(statement, 1536 /* NoComments */); - statements.push(statement); + var expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression); + if (expressionResult) { + if (expressionResult instanceof Array) { + return ts.Debug.fail("export= expression should never be replaced with multiple expressions!"); + } + if (emitAsReturn) { + var statement = ts.createReturn(expressionResult); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */); + statements.push(statement); + } + else { + var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult)); + ts.setTextRange(statement, currentModuleInfo.exportEquals); + ts.setEmitFlags(statement, 1536 /* NoComments */); + statements.push(statement); + } } } } @@ -61899,7 +61938,7 @@ var ts; return statements; } if (ts.hasModifier(decl, 1 /* Export */)) { - var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : decl.name; + var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl); statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl); } if (decl.name) { @@ -89591,16 +89630,7 @@ var ts; if (errors) { return { errors: errors }; } - // If our selection is the expression in an ExpressionStatement, expand - // the selection to include the enclosing Statement (this stops us - // from trying to care about the return value of the extracted function - // and eliminates double semicolon insertion in certain scenarios) - var range = ts.isStatement(start) - ? [start] - : start.parent && start.parent.kind === 210 /* ExpressionStatement */ - ? [start.parent] - : start; - return { targetRange: { range: range, facts: rangeFacts, declarations: declarations } }; + return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations: declarations } }; } function createErrorResult(sourceFile, start, length, message) { return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; @@ -89802,6 +89832,19 @@ var ts; } } extractMethod_1.getRangeToExtract = getRangeToExtract; + function getStatementOrExpressionRange(node) { + if (ts.isStatement(node)) { + return [node]; + } + else if (ts.isPartOfExpression(node)) { + // If our selection is the expression in an ExpressionStatement, expand + // the selection to include the enclosing Statement (this stops us + // from trying to care about the return value of the extracted function + // and eliminates double semicolon insertion in certain scenarios) + return ts.isExpressionStatement(node.parent) ? [node.parent] : node; + } + return undefined; + } function isValidExtractionTarget(node) { // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); @@ -89889,32 +89932,32 @@ var ts; return "constructor"; case 186 /* FunctionExpression */: return scope.name - ? "function expression " + scope.name.getText() + ? "function expression " + scope.name.text : "anonymous function expression"; case 228 /* FunctionDeclaration */: - return "function " + scope.name.getText(); + return "function '" + scope.name.text + "'"; case 187 /* ArrowFunction */: return "arrow function"; case 151 /* MethodDeclaration */: - return "method " + scope.name.getText(); + return "method '" + scope.name.getText(); case 153 /* GetAccessor */: - return "get " + scope.name.getText(); + return "'get " + scope.name.getText() + "'"; case 154 /* SetAccessor */: - return "set " + scope.name.getText(); + return "'set " + scope.name.getText() + "'"; } } else if (isModuleBlock(scope)) { - return "namespace " + scope.parent.name.getText(); + return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { return scope.kind === 229 /* ClassDeclaration */ - ? "class " + scope.name.text + ? "class '" + scope.name.text + "'" : scope.name.text - ? "class expression " + scope.name.text + ? "class expression '" + scope.name.text + "'" : "anonymous class expression"; } else if (ts.isSourceFile(scope)) { - return "file '" + scope.fileName + "'"; + return scope.externalModuleIndicator ? "module scope" : "global scope"; } else { return "unknown"; diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 9f38426db2613..712acfff85b8e 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -3531,7 +3531,7 @@ var ts; Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_function: diag(95003, ts.DiagnosticCategory.Message, "Extract_function_95003", "Extract function"), - Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into '{0}'"), + Extract_function_into_0: diag(95004, ts.DiagnosticCategory.Message, "Extract_function_into_0_95004", "Extract function into {0}"), }; })(ts || (ts = {})); var ts; @@ -5290,9 +5290,9 @@ var ts; || kind === 265; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; - function nodeIsSynthesized(node) { - return ts.positionIsSynthesized(node.pos) - || ts.positionIsSynthesized(node.end); + function nodeIsSynthesized(range) { + return ts.positionIsSynthesized(range.pos) + || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { @@ -17565,6 +17565,7 @@ var ts; } }; TypingsInstaller.prototype.install = function (req) { + var _this = this; if (this.log.isEnabled()) { this.log.writeLine("Got install request " + JSON.stringify(req)); } @@ -17577,7 +17578,7 @@ var ts; if (this.safeList === undefined) { this.safeList = ts.JsTyping.loadSafeList(this.installTypingHost, this.safeListPath); } - var discoverTypingsResult = ts.JsTyping.discoverTypings(this.installTypingHost, this.log.isEnabled() ? this.log.writeLine : undefined, req.fileNames, req.projectRootPath, this.safeList, this.packageNameToTypingLocation, req.typeAcquisition, req.unresolvedImports); + var discoverTypingsResult = ts.JsTyping.discoverTypings(this.installTypingHost, this.log.isEnabled() ? (function (s) { return _this.log.writeLine(s); }) : undefined, req.fileNames, req.projectRootPath, this.safeList, this.packageNameToTypingLocation, req.typeAcquisition, req.unresolvedImports); if (this.log.isEnabled()) { this.log.writeLine("Finished typings discovery: " + JSON.stringify(discoverTypingsResult)); } @@ -17919,7 +17920,7 @@ var ts; if (_this.log.isEnabled()) { _this.log.writeLine("Updating " + TypesRegistryPackageName + " npm package..."); } - _this.execSync(_this.npmPath + " install " + TypesRegistryPackageName, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); + _this.execSync(_this.npmPath + " install --ignore-scripts " + TypesRegistryPackageName, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); if (_this.log.isEnabled()) { _this.log.writeLine("Updated " + TypesRegistryPackageName + " npm package"); } @@ -17965,7 +17966,7 @@ var ts; if (this.log.isEnabled()) { this.log.writeLine("#" + requestId + " with arguments'" + JSON.stringify(args) + "'."); } - var command = this.npmPath + " install " + args.join(" ") + " --save-dev --user-agent=\"typesInstaller/" + ts.version + "\""; + var command = this.npmPath + " install --ignore-scripts " + args.join(" ") + " --save-dev --user-agent=\"typesInstaller/" + ts.version + "\""; var start = Date.now(); var stdout; var stderr; From 15a0d3fef4d00dd12773f3095a898932889d78c1 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 29 Aug 2017 13:17:33 -0700 Subject: [PATCH 28/60] Update version --- package.json | 2 +- src/compiler/core.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 845c37127afa0..f9424a10bb237 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "2.5.1", + "version": "2.5.2", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/core.ts b/src/compiler/core.ts index eea8793e74532..8e2ef6e25a25c 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -6,7 +6,7 @@ namespace ts { // If changing the text in this section, be sure to test `configureNightly` too. export const versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - export const version = `${versionMajorMinor}.1`; + export const version = `${versionMajorMinor}.2`; } /* @internal */ From 6ffe829e9d6bb5e7abd955d6b44f739f17fa32df Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 29 Aug 2017 13:19:51 -0700 Subject: [PATCH 29/60] Update LKG --- lib/tsc.js | 2 +- lib/tsserver.js | 2 +- lib/tsserverlibrary.js | 2 +- lib/typescript.js | 2 +- lib/typescriptServices.js | 2 +- lib/typingsInstaller.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index 96f74044aac98..f5d3a50661225 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -152,7 +152,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".1"; + ts.version = ts.versionMajorMinor + ".2"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; diff --git a/lib/tsserver.js b/lib/tsserver.js index afb40f591c181..bb47b9be938b7 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1164,7 +1164,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".1"; + ts.version = ts.versionMajorMinor + ".2"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 62fb59bbcd19d..d653883477ae8 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -1164,7 +1164,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".1"; + ts.version = ts.versionMajorMinor + ".2"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; diff --git a/lib/typescript.js b/lib/typescript.js index 5762e9133e61c..26b8c9eb88c28 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -1349,7 +1349,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".1"; + ts.version = ts.versionMajorMinor + ".2"; })(ts || (ts = {})); /* @internal */ (function (ts) { diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 5762e9133e61c..26b8c9eb88c28 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -1349,7 +1349,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".1"; + ts.version = ts.versionMajorMinor + ".2"; })(ts || (ts = {})); /* @internal */ (function (ts) { diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 712acfff85b8e..f92f5afca5199 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -162,7 +162,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".1"; + ts.version = ts.versionMajorMinor + ".2"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; From 6425ea29c90d2fd8fee679b6b081b6609f726f82 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 29 Aug 2017 13:29:56 -0700 Subject: [PATCH 30/60] Don't crash when a JS file appears in an inferred context --- .../unittests/tsserverProjectSystem.ts | 28 +++++++++++++++++-- src/server/editorServices.ts | 2 +- src/services/documentRegistry.ts | 20 ++++++------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 6e548231c9140..96d278f31be20 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1760,6 +1760,28 @@ namespace ts.projectSystem { checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]); }); + it("regression test for crash in acquireOrUpdateDocument", () => { + const tsFile = { + fileName: "/a/b/file1.ts", + path: "/a/b/file1.ts", + content: "" + }; + const jsFile = { + path: "/a/b/file1.js", + content: "var x = 10;", + fileName: "/a/b/file1.js", + scriptKind: "JS" as "JS" + }; + + const host = createServerHost([]); + const projectService = createProjectService(host); + projectService.applyChangesInOpenFiles([tsFile], [], []); + const projs = projectService.synchronizeProjectList([]); + projectService.findProject(projs[0].info.projectName).getLanguageService().getNavigationBarItems(tsFile.fileName); + projectService.synchronizeProjectList([projs[0].info]); + projectService.applyChangesInOpenFiles([jsFile], [], []); + }); + it("config file is deleted", () => { const file1 = { path: "/a/b/f1.ts", @@ -1860,7 +1882,7 @@ namespace ts.projectSystem { // Open HTML file projectService.applyChangesInOpenFiles( - /*openFiles*/ [{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }], + /*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }], /*changedFiles*/ undefined, /*closedFiles*/ undefined); @@ -1877,7 +1899,7 @@ namespace ts.projectSystem { projectService.applyChangesInOpenFiles( /*openFiles*/ undefined, /*changedFiles*/ undefined, - /*closedFiles*/ [file2.path]); + /*closedFiles*/[file2.path]); // HTML file is still included in project checkNumberOfProjects(projectService, { configuredProjects: 1 }); @@ -3308,7 +3330,7 @@ namespace ts.projectSystem { const error1Result = session.executeCommand(dTsFile1GetErrRequest).response; assert.isTrue(error1Result.length === 0); - const dTsFile2GetErrRequest = makeSessionRequest( + const dTsFile2GetErrRequest = makeSessionRequest( CommandNames.SemanticDiagnosticsSync, { file: dTsFile2.path } ); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index cb497ff774f1c..1843504369654 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1609,7 +1609,7 @@ namespace ts.server { if (openFiles) { for (const file of openFiles) { const scriptInfo = this.getScriptInfo(file.fileName); - Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen()); + Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already"); const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName); this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent); } diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index bc01f2a96a67a..0c3d4d1cb485f 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -173,14 +173,12 @@ namespace ts { const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true); let entry = bucket.get(path); if (!entry) { - Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); - // Have never seen this file with these settings. Create a new source file for it. const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind); entry = { sourceFile, - languageServiceRefCount: 0, + languageServiceRefCount: 1, owners: [] }; bucket.set(path, entry); @@ -193,15 +191,15 @@ namespace ts { entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } - } - // If we're acquiring, then this is the first time this LS is asking for this document. - // Increase our ref count so we know there's another LS using the document. If we're - // not acquiring, then that means the LS is 'updating' the file instead, and that means - // it has already acquired the document previously. As such, we do not need to increase - // the ref count. - if (acquiring) { - entry.languageServiceRefCount++; + // If we're acquiring, then this is the first time this LS is asking for this document. + // Increase our ref count so we know there's another LS using the document. If we're + // not acquiring, then that means the LS is 'updating' the file instead, and that means + // it has already acquired the document previously. As such, we do not need to increase + // the ref count. + if (acquiring) { + entry.languageServiceRefCount++; + } } return entry.sourceFile; From 171c664fefd945301ab0aaf287b3d1f288c67900 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 29 Aug 2017 17:26:58 -0700 Subject: [PATCH 31/60] Update LKG --- lib/tsserver.js | 11 +++++------ lib/tsserverlibrary.js | 11 +++++------ lib/typescript.js | 19 +++++++++---------- lib/typescriptServices.js | 19 +++++++++---------- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/lib/tsserver.js b/lib/tsserver.js index bb47b9be938b7..ddbefc72ce9db 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -64887,11 +64887,10 @@ var ts; var bucket = getBucketForCompilationSettings(key, true); var entry = bucket.get(path); if (!entry) { - ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, false, scriptKind); entry = { sourceFile: sourceFile, - languageServiceRefCount: 0, + languageServiceRefCount: 1, owners: [] }; bucket.set(path, entry); @@ -64900,9 +64899,9 @@ var ts; if (entry.sourceFile.version !== version) { entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } - } - if (acquiring) { - entry.languageServiceRefCount++; + if (acquiring) { + entry.languageServiceRefCount++; + } } return entry.sourceFile; } @@ -80823,7 +80822,7 @@ var ts; for (var _i = 0, openFiles_1 = openFiles; _i < openFiles_1.length; _i++) { var file = openFiles_1[_i]; var scriptInfo = this.getScriptInfo(file.fileName); - ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen()); + ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already"); var normalizedPath = scriptInfo ? scriptInfo.fileName : server.toNormalizedPath(file.fileName); this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent); } diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index d653883477ae8..60d8bc0001239 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -64887,11 +64887,10 @@ var ts; var bucket = getBucketForCompilationSettings(key, true); var entry = bucket.get(path); if (!entry) { - ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, false, scriptKind); entry = { sourceFile: sourceFile, - languageServiceRefCount: 0, + languageServiceRefCount: 1, owners: [] }; bucket.set(path, entry); @@ -64900,9 +64899,9 @@ var ts; if (entry.sourceFile.version !== version) { entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } - } - if (acquiring) { - entry.languageServiceRefCount++; + if (acquiring) { + entry.languageServiceRefCount++; + } } return entry.sourceFile; } @@ -82561,7 +82560,7 @@ var ts; for (var _i = 0, openFiles_1 = openFiles; _i < openFiles_1.length; _i++) { var file = openFiles_1[_i]; var scriptInfo = this.getScriptInfo(file.fileName); - ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen()); + ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already"); var normalizedPath = scriptInfo ? scriptInfo.fileName : server.toNormalizedPath(file.fileName); this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent); } diff --git a/lib/typescript.js b/lib/typescript.js index 26b8c9eb88c28..d8b76261f704e 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -78177,12 +78177,11 @@ var ts; var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true); var entry = bucket.get(path); if (!entry) { - ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind); entry = { sourceFile: sourceFile, - languageServiceRefCount: 0, + languageServiceRefCount: 1, owners: [] }; bucket.set(path, entry); @@ -78194,14 +78193,14 @@ var ts; if (entry.sourceFile.version !== version) { entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } - } - // If we're acquiring, then this is the first time this LS is asking for this document. - // Increase our ref count so we know there's another LS using the document. If we're - // not acquiring, then that means the LS is 'updating' the file instead, and that means - // it has already acquired the document previously. As such, we do not need to increase - // the ref count. - if (acquiring) { - entry.languageServiceRefCount++; + // If we're acquiring, then this is the first time this LS is asking for this document. + // Increase our ref count so we know there's another LS using the document. If we're + // not acquiring, then that means the LS is 'updating' the file instead, and that means + // it has already acquired the document previously. As such, we do not need to increase + // the ref count. + if (acquiring) { + entry.languageServiceRefCount++; + } } return entry.sourceFile; } diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 26b8c9eb88c28..d8b76261f704e 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -78177,12 +78177,11 @@ var ts; var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true); var entry = bucket.get(path); if (!entry) { - ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind); entry = { sourceFile: sourceFile, - languageServiceRefCount: 0, + languageServiceRefCount: 1, owners: [] }; bucket.set(path, entry); @@ -78194,14 +78193,14 @@ var ts; if (entry.sourceFile.version !== version) { entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } - } - // If we're acquiring, then this is the first time this LS is asking for this document. - // Increase our ref count so we know there's another LS using the document. If we're - // not acquiring, then that means the LS is 'updating' the file instead, and that means - // it has already acquired the document previously. As such, we do not need to increase - // the ref count. - if (acquiring) { - entry.languageServiceRefCount++; + // If we're acquiring, then this is the first time this LS is asking for this document. + // Increase our ref count so we know there's another LS using the document. If we're + // not acquiring, then that means the LS is 'updating' the file instead, and that means + // it has already acquired the document previously. As such, we do not need to increase + // the ref count. + if (acquiring) { + entry.languageServiceRefCount++; + } } return entry.sourceFile; } From 4925f2f05f2c05445d2748afb8063674e34e1bf2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 22 Aug 2017 10:13:08 +0100 Subject: [PATCH 32/60] Optimize relations for type references with unconstrained type arguments --- src/compiler/checker.ts | 44 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1c650a3c41559..ebd62c32722b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8800,8 +8800,7 @@ namespace ts { return true; } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { - const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - const related = relation.get(id); + const related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === RelationComparisonResult.Succeeded; } @@ -9202,7 +9201,7 @@ namespace ts { if (overflow) { return Ternary.False; } - const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; + const id = getRelationKey(source, target, relation); const related = relation.get(id); if (related !== undefined) { if (reportErrors && related === RelationComparisonResult.Failed) { @@ -9767,6 +9766,45 @@ namespace ts { } } + function isUnconstrainedTypeParameter(type: Type) { + return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter(type); + } + + function isTypeReferenceWithGenericArguments(type: Type) { + return getObjectFlags(type) & ObjectFlags.Reference && some((type).typeArguments, isUnconstrainedTypeParameter); + } + + function getTypeReferenceId(type: TypeReference, typeParameters: Type[]) { + let result = "" + type.id; + for (const t of type.typeArguments) { + if (isUnconstrainedTypeParameter(t)) { + let index = indexOf(typeParameters, t); + if (index < 0) { + index = typeParameters.length; + typeParameters.push(t); + } + result += "=" + index; + } + else { + result += "-" + t.id; + } + } + return result; + } + + function getRelationKey(source: Type, target: Type, relation: Map) { + if (relation === identityRelation && source.id > target.id) { + const temp = source; + source = target; + target = temp; + } + if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { + const typeParameters: Type[] = []; + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + } + return source.id + "," + target.id; + } + // Invoke the callback for each underlying property symbol of the given symbol and return the first // value that isn't undefined. function forEachProperty(prop: Symbol, callback: (p: Symbol) => T): T { From 251017759365e16570a3c6755d007227391b7e99 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 22 Aug 2017 17:41:07 +0100 Subject: [PATCH 33/60] Fix to use correct target type ID --- 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 ebd62c32722b4..e07ab5c7a286d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9775,7 +9775,7 @@ namespace ts { } function getTypeReferenceId(type: TypeReference, typeParameters: Type[]) { - let result = "" + type.id; + let result = "" + type.target.id; for (const t of type.typeArguments) { if (isUnconstrainedTypeParameter(t)) { let index = indexOf(typeParameters, t); From f3700f645d9c4e23b99819740682d9dd3ea05c05 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 21 Aug 2017 10:09:21 -0700 Subject: [PATCH 34/60] Test performance improvement:nested reference skip --- .../complexRecursiveCollections.errors.txt | 847 ++++++++++++++++++ .../compiler/complexRecursiveCollections.ts | 532 +++++++++++ 2 files changed, 1379 insertions(+) create mode 100644 tests/baselines/reference/complexRecursiveCollections.errors.txt create mode 100644 tests/cases/compiler/complexRecursiveCollections.ts diff --git a/tests/baselines/reference/complexRecursiveCollections.errors.txt b/tests/baselines/reference/complexRecursiveCollections.errors.txt new file mode 100644 index 0000000000000..38f66b7456a7f --- /dev/null +++ b/tests/baselines/reference/complexRecursiveCollections.errors.txt @@ -0,0 +1,847 @@ +tests/cases/compiler/immutable.d.ts(25,39): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(46,20): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(47,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(48,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(49,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(50,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(51,22): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(52,26): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(58,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(60,63): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(68,41): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(69,38): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(69,47): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(78,21): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(79,21): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(89,20): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(90,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(91,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(92,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(93,23): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(94,22): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(95,26): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(101,42): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(106,58): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(113,48): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(114,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(114,54): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(120,42): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(125,58): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(134,33): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(134,42): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(135,29): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(135,38): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(139,38): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(155,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(157,62): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(169,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(172,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(174,62): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(188,40): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(195,22): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(198,19): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(205,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(207,63): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(217,30): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(218,34): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(226,22): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(227,22): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(234,48): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(235,52): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(236,109): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(237,109): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(242,22): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(243,25): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(244,24): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(245,28): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(246,25): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(247,25): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(258,8): error TS2304: Cannot find name 'Symbol'. +tests/cases/compiler/immutable.d.ts(258,28): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(266,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(274,44): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(279,60): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(288,44): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(293,47): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(295,65): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(304,40): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(309,47): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(311,64): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(320,38): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(329,58): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(339,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(341,22): error TS2430: Interface 'Keyed' incorrectly extends interface 'Collection'. + Types of property 'toSeq' are incompatible. + Type '() => Keyed' is not assignable to type '() => this'. + Type 'Keyed' is not assignable to type 'this'. +tests/cases/compiler/immutable.d.ts(347,44): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(352,60): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(355,8): error TS2304: Cannot find name 'Symbol'. +tests/cases/compiler/immutable.d.ts(355,28): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(358,44): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(359,22): error TS2430: Interface 'Indexed' incorrectly extends interface 'Collection'. + Types of property 'toSeq' are incompatible. + Type '() => Indexed' is not assignable to type '() => this'. + Type 'Indexed' is not assignable to type 'this'. +tests/cases/compiler/immutable.d.ts(382,47): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(384,65): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(387,8): error TS2304: Cannot find name 'Symbol'. +tests/cases/compiler/immutable.d.ts(387,28): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(390,40): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(391,22): error TS2430: Interface 'Set' incorrectly extends interface 'Collection'. + Types of property 'toSeq' are incompatible. + Type '() => Set' is not assignable to type '() => this'. + Type 'Set' is not assignable to type 'this'. +tests/cases/compiler/immutable.d.ts(396,47): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(398,64): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(401,8): error TS2304: Cannot find name 'Symbol'. +tests/cases/compiler/immutable.d.ts(401,28): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(405,45): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(420,26): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(421,26): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(442,13): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(443,15): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(444,16): error TS2304: Cannot find name 'IterableIterator'. +tests/cases/compiler/immutable.d.ts(476,58): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(503,20): error TS2304: Cannot find name 'Iterable'. +tests/cases/compiler/immutable.d.ts(504,22): error TS2304: Cannot find name 'Iterable'. + + +==== tests/cases/compiler/complex.d.ts (0 errors) ==== + interface Ara { t: T } + interface Collection { + map(mapper: (value: V, key: K, iter: this) => M): Collection; + flatMap(mapper: (value: V, key: K, iter: this) => Ara, context?: any): Collection; + // these seem necessary to push it over the top for memory usage + reduce(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R; + reduce(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + toSeq(): Seq; + } + interface Seq extends Collection { + } + interface N1 extends Collection { + map(mapper: (value: T, key: void, iter: this) => M): N1; + flatMap(mapper: (value: T, key: void, iter: this) => Ara, context?: any): N1; + } + interface N2 extends N1 { + map(mapper: (value: T, key: void, iter: this) => M): N2; + flatMap(mapper: (value: T, key: void, iter: this) => Ara, context?: any): N2; + toSeq(): N2; + } +==== tests/cases/compiler/immutable.d.ts (98 errors) ==== + // Test that complex recursive collections can pass the `extends` assignability check without + // running out of memory. This bug was exposed in Typescript 2.4 when more generic signatures + // started being checked. + declare module Immutable { + export function fromJS(jsValue: any, reviver?: (key: string | number, sequence: Collection.Keyed | Collection.Indexed, path?: Array) => any): any; + export function is(first: any, second: any): boolean; + export function hash(value: any): number; + export function isImmutable(maybeImmutable: any): maybeImmutable is Collection; + export function isCollection(maybeCollection: any): maybeCollection is Collection; + export function isKeyed(maybeKeyed: any): maybeKeyed is Collection.Keyed; + export function isIndexed(maybeIndexed: any): maybeIndexed is Collection.Indexed; + export function isAssociative(maybeAssociative: any): maybeAssociative is Collection.Keyed | Collection.Indexed; + export function isOrdered(maybeOrdered: any): boolean; + export function isValueObject(maybeValue: any): maybeValue is ValueObject; + export interface ValueObject { + equals(other: any): boolean; + hashCode(): number; + } + export module List { + function isList(maybeList: any): maybeList is List; + function of(...values: Array): List; + } + export function List(): List; + export function List(): List; + export function List(collection: Iterable): List; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface List extends Collection.Indexed { + // Persistent changes + set(index: number, value: T): List; + delete(index: number): List; + remove(index: number): List; + insert(index: number, value: T): List; + clear(): List; + push(...values: Array): List; + pop(): List; + unshift(...values: Array): List; + shift(): List; + update(index: number, notSetValue: T, updater: (value: T) => T): this; + update(index: number, updater: (value: T) => T): this; + update(updater: (value: this) => R): R; + merge(...collections: Array | Array>): this; + mergeWith(merger: (oldVal: T, newVal: T, key: number) => T, ...collections: Array | Array>): this; + mergeDeep(...collections: Array | Array>): this; + mergeDeepWith(merger: (oldVal: T, newVal: T, key: number) => T, ...collections: Array | Array>): this; + setSize(size: number): List; + // Deep persistent changes + setIn(keyPath: Iterable, value: any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + deleteIn(keyPath: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + removeIn(keyPath: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + updateIn(keyPath: Iterable, notSetValue: any, updater: (value: any) => any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + updateIn(keyPath: Iterable, updater: (value: any) => any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeIn(keyPath: Iterable, ...collections: Array): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeDeepIn(keyPath: Iterable, ...collections: Array): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): List; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: number, iter: this) => M, context?: any): List; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): List; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): List; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + } + export module Map { + function isMap(maybeMap: any): maybeMap is Map; + function of(...keyValues: Array): Map; + } + export function Map(collection: Iterable<[K, V]>): Map; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function Map(collection: Iterable>): Map; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function Map(obj: {[key: string]: V}): Map; + export function Map(): Map; + export function Map(): Map; + export interface Map extends Collection.Keyed { + // Persistent changes + set(key: K, value: V): this; + delete(key: K): this; + remove(key: K): this; + deleteAll(keys: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + removeAll(keys: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + clear(): this; + update(key: K, notSetValue: V, updater: (value: V) => V): this; + update(key: K, updater: (value: V) => V): this; + update(updater: (value: this) => R): R; + merge(...collections: Array | {[key: string]: V}>): this; + mergeWith(merger: (oldVal: V, newVal: V, key: K) => V, ...collections: Array | {[key: string]: V}>): this; + mergeDeep(...collections: Array | {[key: string]: V}>): this; + mergeDeepWith(merger: (oldVal: V, newVal: V, key: K) => V, ...collections: Array | {[key: string]: V}>): this; + // Deep persistent changes + setIn(keyPath: Iterable, value: any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + deleteIn(keyPath: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + removeIn(keyPath: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + updateIn(keyPath: Iterable, notSetValue: any, updater: (value: any) => any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + updateIn(keyPath: Iterable, updater: (value: any) => any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeIn(keyPath: Iterable, ...collections: Array): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeDeepIn(keyPath: Iterable, ...collections: Array): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...collections: Array>): Map; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + concat(...collections: Array<{[key: string]: C}>): Map; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Map; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): Map; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Map; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Map; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Map; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + export module OrderedMap { + function isOrderedMap(maybeOrderedMap: any): maybeOrderedMap is OrderedMap; + } + export function OrderedMap(collection: Iterable<[K, V]>): OrderedMap; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function OrderedMap(collection: Iterable>): OrderedMap; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function OrderedMap(obj: {[key: string]: V}): OrderedMap; + export function OrderedMap(): OrderedMap; + export function OrderedMap(): OrderedMap; + export interface OrderedMap extends Map { + // Sequence algorithms + concat(...collections: Array>): OrderedMap; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + concat(...collections: Array<{[key: string]: C}>): OrderedMap; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): OrderedMap; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): OrderedMap; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): OrderedMap; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): OrderedMap; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): OrderedMap; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + export module Set { + function isSet(maybeSet: any): maybeSet is Set; + function of(...values: Array): Set; + function fromKeys(iter: Collection): Set; + function fromKeys(obj: {[key: string]: any}): Set; + function intersect(sets: Iterable>): Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + function union(sets: Iterable>): Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + } + export function Set(): Set; + export function Set(): Set; + export function Set(collection: Iterable): Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface Set extends Collection.Set { + // Persistent changes + add(value: T): this; + delete(value: T): this; + remove(value: T): this; + clear(): this; + union(...collections: Array | Array>): this; + merge(...collections: Array | Array>): this; + intersect(...collections: Array | Array>): this; + subtract(...collections: Array | Array>): this; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: never, iter: this) => M, context?: any): Set; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Set; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + } + export module OrderedSet { + function isOrderedSet(maybeOrderedSet: any): boolean; + function of(...values: Array): OrderedSet; + function fromKeys(iter: Collection): OrderedSet; + function fromKeys(obj: {[key: string]: any}): OrderedSet; + } + export function OrderedSet(): OrderedSet; + export function OrderedSet(): OrderedSet; + export function OrderedSet(collection: Iterable): OrderedSet; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface OrderedSet extends Set { + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): OrderedSet; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: never, iter: this) => M, context?: any): OrderedSet; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): OrderedSet; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): OrderedSet; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + zip(...collections: Array>): OrderedSet; + zipWith(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection): OrderedSet; + zipWith(zipper: (value: T, otherValue: U, thirdValue: V) => Z, otherCollection: Collection, thirdCollection: Collection): OrderedSet; + zipWith(zipper: (...any: Array) => Z, ...collections: Array>): OrderedSet; + } + export module Stack { + function isStack(maybeStack: any): maybeStack is Stack; + function of(...values: Array): Stack; + } + export function Stack(): Stack; + export function Stack(): Stack; + export function Stack(collection: Iterable): Stack; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface Stack extends Collection.Indexed { + // Reading values + peek(): T | undefined; + // Persistent changes + clear(): Stack; + unshift(...values: Array): Stack; + unshiftAll(iter: Iterable): Stack; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + shift(): Stack; + push(...values: Array): Stack; + pushAll(iter: Iterable): Stack; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + pop(): Stack; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Stack; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: number, iter: this) => M, context?: any): Stack; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): Stack; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Set; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + } + export function Range(start?: number, end?: number, step?: number): Seq.Indexed; + export function Repeat(value: T, times?: number): Seq.Indexed; + export module Record { + export function isRecord(maybeRecord: any): maybeRecord is Record.Instance; + export function getDescriptiveName(record: Instance): string; + export interface Class { + (values?: Partial | Iterable<[string, any]>): Instance & Readonly; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + new (values?: Partial | Iterable<[string, any]>): Instance & Readonly; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + } + export interface Instance { + readonly size: number; + // Reading values + has(key: string): boolean; + get(key: K): T[K]; + // Reading deep values + hasIn(keyPath: Iterable): boolean; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + getIn(keyPath: Iterable): any; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + // Value equality + equals(other: any): boolean; + hashCode(): number; + // Persistent changes + set(key: K, value: T[K]): this; + update(key: K, updater: (value: T[K]) => T[K]): this; + merge(...collections: Array | Iterable<[string, any]>>): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeDeep(...collections: Array | Iterable<[string, any]>>): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeWith(merger: (oldVal: any, newVal: any, key: keyof T) => any, ...collections: Array | Iterable<[string, any]>>): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeDeepWith(merger: (oldVal: any, newVal: any, key: any) => any, ...collections: Array | Iterable<[string, any]>>): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + delete(key: K): this; + remove(key: K): this; + clear(): this; + // Deep persistent changes + setIn(keyPath: Iterable, value: any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + updateIn(keyPath: Iterable, updater: (value: any) => any): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeIn(keyPath: Iterable, ...collections: Array): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + mergeDeepIn(keyPath: Iterable, ...collections: Array): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + deleteIn(keyPath: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + removeIn(keyPath: Iterable): this; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + // Conversion to JavaScript types + toJS(): { [K in keyof T]: any }; + toJSON(): T; + toObject(): T; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + toSeq(): Seq.Keyed; + [Symbol.iterator](): IterableIterator<[keyof T, T[keyof T]]>; + ~~~~~~ +!!! error TS2304: Cannot find name 'Symbol'. + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + } + } + export function Record(defaultValues: T, name?: string): Record.Class; + export module Seq { + function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed | Seq.Keyed; + function of(...values: Array): Seq.Indexed; + export module Keyed {} + export function Keyed(collection: Iterable<[K, V]>): Seq.Keyed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function Keyed(obj: {[key: string]: V}): Seq.Keyed; + export function Keyed(): Seq.Keyed; + export function Keyed(): Seq.Keyed; + export interface Keyed extends Seq, Collection.Keyed { + toJS(): Object; + toJSON(): { [key: string]: V }; + toSeq(): this; + concat(...collections: Array>): Seq.Keyed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + concat(...collections: Array<{[key: string]: C}>): Seq.Keyed; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Seq.Keyed; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): Seq.Keyed; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Seq.Keyed; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Seq.Keyed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Seq.Keyed; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + module Indexed { + function of(...values: Array): Seq.Indexed; + } + export function Indexed(): Seq.Indexed; + export function Indexed(): Seq.Indexed; + export function Indexed(collection: Iterable): Seq.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface Indexed extends Seq, Collection.Indexed { + toJS(): Array; + toJSON(): Array; + toSeq(): this; + concat(...valuesOrCollections: Array | C>): Seq.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: number, iter: this) => M, context?: any): Seq.Indexed; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): Seq.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Seq.Indexed; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + } + export module Set { + function of(...values: Array): Seq.Set; + } + export function Set(): Seq.Set; + export function Set(): Seq.Set; + export function Set(collection: Iterable): Seq.Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface Set extends Seq, Collection.Set { + toJS(): Array; + toJSON(): Array; + toSeq(): this; + concat(...valuesOrCollections: Array | C>): Seq.Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: never, iter: this) => M, context?: any): Seq.Set; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): Seq.Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Seq.Set; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + } + } + export function Seq>(seq: S): S; + export function Seq(collection: Collection.Keyed): Seq.Keyed; + export function Seq(collection: Collection.Indexed): Seq.Indexed; + export function Seq(collection: Collection.Set): Seq.Set; + export function Seq(collection: Iterable): Seq.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function Seq(obj: {[key: string]: V}): Seq.Keyed; + export function Seq(): Seq; + export interface Seq extends Collection { + readonly size: number | undefined; + // Force evaluation + cacheResult(): this; + // Sequence algorithms + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Seq; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Seq; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Seq; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + export module Collection { + function isKeyed(maybeKeyed: any): maybeKeyed is Collection.Keyed; + function isIndexed(maybeIndexed: any): maybeIndexed is Collection.Indexed; + function isAssociative(maybeAssociative: any): maybeAssociative is Collection.Keyed | Collection.Indexed; + function isOrdered(maybeOrdered: any): boolean; + export module Keyed {} + export function Keyed(collection: Iterable<[K, V]>): Collection.Keyed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function Keyed(obj: {[key: string]: V}): Collection.Keyed; + export interface Keyed extends Collection { + ~~~~~ +!!! error TS2430: Interface 'Keyed' incorrectly extends interface 'Collection'. +!!! error TS2430: Types of property 'toSeq' are incompatible. +!!! error TS2430: Type '() => Keyed' is not assignable to type '() => this'. +!!! error TS2430: Type 'Keyed' is not assignable to type 'this'. + toJS(): Object; + toJSON(): { [key: string]: V }; + toSeq(): Seq.Keyed; + // Sequence functions + flip(): this; + concat(...collections: Array>): Collection.Keyed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + concat(...collections: Array<{[key: string]: C}>): Collection.Keyed; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Collection.Keyed; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): Collection.Keyed; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Collection.Keyed; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Collection.Keyed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Collection.Keyed; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + [Symbol.iterator](): IterableIterator<[K, V]>; + ~~~~~~ +!!! error TS2304: Cannot find name 'Symbol'. + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + } + export module Indexed {} + export function Indexed(collection: Iterable): Collection.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface Indexed extends Collection { + ~~~~~~~ +!!! error TS2430: Interface 'Indexed' incorrectly extends interface 'Collection'. +!!! error TS2430: Types of property 'toSeq' are incompatible. +!!! error TS2430: Type '() => Indexed' is not assignable to type '() => this'. +!!! error TS2430: Type 'Indexed' is not assignable to type 'this'. + toJS(): Array; + toJSON(): Array; + // Reading values + get(index: number, notSetValue: NSV): T | NSV; + get(index: number): T | undefined; + // Conversion to Seq + toSeq(): Seq.Indexed; + fromEntrySeq(): Seq.Keyed; + // Combination + interpose(separator: T): this; + interleave(...collections: Array>): this; + splice(index: number, removeNum: number, ...values: Array): this; + zip(...collections: Array>): Collection.Indexed; + zipWith(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection): Collection.Indexed; + zipWith(zipper: (value: T, otherValue: U, thirdValue: V) => Z, otherCollection: Collection, thirdCollection: Collection): Collection.Indexed; + zipWith(zipper: (...any: Array) => Z, ...collections: Array>): Collection.Indexed; + // Search for value + indexOf(searchValue: T): number; + lastIndexOf(searchValue: T): number; + findIndex(predicate: (value: T, index: number, iter: this) => boolean, context?: any): number; + findLastIndex(predicate: (value: T, index: number, iter: this) => boolean, context?: any): number; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Collection.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: number, iter: this) => M, context?: any): Collection.Indexed; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): Collection.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Collection.Indexed; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + [Symbol.iterator](): IterableIterator; + ~~~~~~ +!!! error TS2304: Cannot find name 'Symbol'. + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + } + export module Set {} + export function Set(collection: Iterable): Collection.Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export interface Set extends Collection { + ~~~ +!!! error TS2430: Interface 'Set' incorrectly extends interface 'Collection'. +!!! error TS2430: Types of property 'toSeq' are incompatible. +!!! error TS2430: Type '() => Set' is not assignable to type '() => this'. +!!! error TS2430: Type 'Set' is not assignable to type 'this'. + toJS(): Array; + toJSON(): Array; + toSeq(): Seq.Set; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Collection.Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + map(mapper: (value: T, key: never, iter: this) => M, context?: any): Collection.Set; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): Collection.Set; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Collection.Set; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + [Symbol.iterator](): IterableIterator; + ~~~~~~ +!!! error TS2304: Cannot find name 'Symbol'. + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + } + } + export function Collection>(collection: I): I; + export function Collection(collection: Iterable): Collection.Indexed; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + export function Collection(obj: {[key: string]: V}): Collection.Keyed; + export interface Collection extends ValueObject { + // Value equality + equals(other: any): boolean; + hashCode(): number; + // Reading values + get(key: K, notSetValue: NSV): V | NSV; + get(key: K): V | undefined; + has(key: K): boolean; + includes(value: V): boolean; + contains(value: V): boolean; + first(): V | undefined; + last(): V | undefined; + // Reading deep values + getIn(searchKeyPath: Iterable, notSetValue?: any): any; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + hasIn(searchKeyPath: Iterable): boolean; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + // Persistent changes + update(updater: (value: this) => R): R; + // Conversion to JavaScript types + toJS(): Array | { [key: string]: any }; + toJSON(): Array | { [key: string]: V }; + toArray(): Array; + toObject(): { [key: string]: V }; + // Conversion to Collections + toMap(): Map; + toOrderedMap(): OrderedMap; + toSet(): Set; + toOrderedSet(): OrderedSet; + toList(): List; + toStack(): Stack; + // Conversion to Seq + toSeq(): this; + toKeyedSeq(): Seq.Keyed; + toIndexedSeq(): Seq.Indexed; + toSetSeq(): Seq.Set; + // Iterators + keys(): IterableIterator; + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + values(): IterableIterator; + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + entries(): IterableIterator<[K, V]>; + ~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'IterableIterator'. + // Collections (Seq) + keySeq(): Seq.Indexed; + valueSeq(): Seq.Indexed; + entrySeq(): Seq.Indexed<[K, V]>; + // Sequence algorithms + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Collection; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Collection; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + filterNot(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + reverse(): this; + sort(comparator?: (valueA: V, valueB: V) => number): this; + sortBy(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): this; + groupBy(grouper: (value: V, key: K, iter: this) => G, context?: any): /*Map*/Seq.Keyed>; + // Side effects + forEach(sideEffect: (value: V, key: K, iter: this) => any, context?: any): number; + // Creating subsets + slice(begin?: number, end?: number): this; + rest(): this; + butLast(): this; + skip(amount: number): this; + skipLast(amount: number): this; + skipWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + skipUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + take(amount: number): this; + takeLast(amount: number): this; + takeWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + takeUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + // Combination + concat(...valuesOrCollections: Array): Collection; + flatten(depth?: number): Collection; + flatten(shallow?: boolean): Collection; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Collection; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + // Reducing a value + reduce(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R; + reduce(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + reduceRight(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R; + reduceRight(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + every(predicate: (value: V, key: K, iter: this) => boolean, context?: any): boolean; + some(predicate: (value: V, key: K, iter: this) => boolean, context?: any): boolean; + join(separator?: string): string; + isEmpty(): boolean; + count(): number; + count(predicate: (value: V, key: K, iter: this) => boolean, context?: any): number; + countBy(grouper: (value: V, key: K, iter: this) => G, context?: any): Map; + // Search for value + find(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): V | undefined; + findLast(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): V | undefined; + findEntry(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): [K, V] | undefined; + findLastEntry(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): [K, V] | undefined; + findKey(predicate: (value: V, key: K, iter: this) => boolean, context?: any): K | undefined; + findLastKey(predicate: (value: V, key: K, iter: this) => boolean, context?: any): K | undefined; + keyOf(searchValue: V): K | undefined; + lastKeyOf(searchValue: V): K | undefined; + max(comparator?: (valueA: V, valueB: V) => number): V | undefined; + maxBy(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): V | undefined; + min(comparator?: (valueA: V, valueB: V) => number): V | undefined; + minBy(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): V | undefined; + // Comparison + isSubset(iter: Iterable): boolean; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + isSuperset(iter: Iterable): boolean; + ~~~~~~~~ +!!! error TS2304: Cannot find name 'Iterable'. + readonly size: number; + } + } + declare module "immutable" { + export = Immutable + } + \ No newline at end of file diff --git a/tests/cases/compiler/complexRecursiveCollections.ts b/tests/cases/compiler/complexRecursiveCollections.ts new file mode 100644 index 0000000000000..a79b429f20435 --- /dev/null +++ b/tests/cases/compiler/complexRecursiveCollections.ts @@ -0,0 +1,532 @@ +// @Filename: complex.d.ts +interface Ara { t: T } +interface Collection { + map(mapper: (value: V, key: K, iter: this) => M): Collection; + flatMap(mapper: (value: V, key: K, iter: this) => Ara, context?: any): Collection; + // these seem necessary to push it over the top for memory usage + reduce(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R; + reduce(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + toSeq(): Seq; +} +interface Seq extends Collection { +} +interface N1 extends Collection { + map(mapper: (value: T, key: void, iter: this) => M): N1; + flatMap(mapper: (value: T, key: void, iter: this) => Ara, context?: any): N1; +} +interface N2 extends N1 { + map(mapper: (value: T, key: void, iter: this) => M): N2; + flatMap(mapper: (value: T, key: void, iter: this) => Ara, context?: any): N2; + toSeq(): N2; +} +// @Filename: immutable.d.ts +// Test that complex recursive collections can pass the `extends` assignability check without +// running out of memory. This bug was exposed in Typescript 2.4 when more generic signatures +// started being checked. +declare module Immutable { + export function fromJS(jsValue: any, reviver?: (key: string | number, sequence: Collection.Keyed | Collection.Indexed, path?: Array) => any): any; + export function is(first: any, second: any): boolean; + export function hash(value: any): number; + export function isImmutable(maybeImmutable: any): maybeImmutable is Collection; + export function isCollection(maybeCollection: any): maybeCollection is Collection; + export function isKeyed(maybeKeyed: any): maybeKeyed is Collection.Keyed; + export function isIndexed(maybeIndexed: any): maybeIndexed is Collection.Indexed; + export function isAssociative(maybeAssociative: any): maybeAssociative is Collection.Keyed | Collection.Indexed; + export function isOrdered(maybeOrdered: any): boolean; + export function isValueObject(maybeValue: any): maybeValue is ValueObject; + export interface ValueObject { + equals(other: any): boolean; + hashCode(): number; + } + export module List { + function isList(maybeList: any): maybeList is List; + function of(...values: Array): List; + } + export function List(): List; + export function List(): List; + export function List(collection: Iterable): List; + export interface List extends Collection.Indexed { + // Persistent changes + set(index: number, value: T): List; + delete(index: number): List; + remove(index: number): List; + insert(index: number, value: T): List; + clear(): List; + push(...values: Array): List; + pop(): List; + unshift(...values: Array): List; + shift(): List; + update(index: number, notSetValue: T, updater: (value: T) => T): this; + update(index: number, updater: (value: T) => T): this; + update(updater: (value: this) => R): R; + merge(...collections: Array | Array>): this; + mergeWith(merger: (oldVal: T, newVal: T, key: number) => T, ...collections: Array | Array>): this; + mergeDeep(...collections: Array | Array>): this; + mergeDeepWith(merger: (oldVal: T, newVal: T, key: number) => T, ...collections: Array | Array>): this; + setSize(size: number): List; + // Deep persistent changes + setIn(keyPath: Iterable, value: any): this; + deleteIn(keyPath: Iterable): this; + removeIn(keyPath: Iterable): this; + updateIn(keyPath: Iterable, notSetValue: any, updater: (value: any) => any): this; + updateIn(keyPath: Iterable, updater: (value: any) => any): this; + mergeIn(keyPath: Iterable, ...collections: Array): this; + mergeDeepIn(keyPath: Iterable, ...collections: Array): this; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): List; + map(mapper: (value: T, key: number, iter: this) => M, context?: any): List; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): List; + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): List; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + } + export module Map { + function isMap(maybeMap: any): maybeMap is Map; + function of(...keyValues: Array): Map; + } + export function Map(collection: Iterable<[K, V]>): Map; + export function Map(collection: Iterable>): Map; + export function Map(obj: {[key: string]: V}): Map; + export function Map(): Map; + export function Map(): Map; + export interface Map extends Collection.Keyed { + // Persistent changes + set(key: K, value: V): this; + delete(key: K): this; + remove(key: K): this; + deleteAll(keys: Iterable): this; + removeAll(keys: Iterable): this; + clear(): this; + update(key: K, notSetValue: V, updater: (value: V) => V): this; + update(key: K, updater: (value: V) => V): this; + update(updater: (value: this) => R): R; + merge(...collections: Array | {[key: string]: V}>): this; + mergeWith(merger: (oldVal: V, newVal: V, key: K) => V, ...collections: Array | {[key: string]: V}>): this; + mergeDeep(...collections: Array | {[key: string]: V}>): this; + mergeDeepWith(merger: (oldVal: V, newVal: V, key: K) => V, ...collections: Array | {[key: string]: V}>): this; + // Deep persistent changes + setIn(keyPath: Iterable, value: any): this; + deleteIn(keyPath: Iterable): this; + removeIn(keyPath: Iterable): this; + updateIn(keyPath: Iterable, notSetValue: any, updater: (value: any) => any): this; + updateIn(keyPath: Iterable, updater: (value: any) => any): this; + mergeIn(keyPath: Iterable, ...collections: Array): this; + mergeDeepIn(keyPath: Iterable, ...collections: Array): this; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...collections: Array>): Map; + concat(...collections: Array<{[key: string]: C}>): Map; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Map; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): Map; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Map; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Map; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Map; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + export module OrderedMap { + function isOrderedMap(maybeOrderedMap: any): maybeOrderedMap is OrderedMap; + } + export function OrderedMap(collection: Iterable<[K, V]>): OrderedMap; + export function OrderedMap(collection: Iterable>): OrderedMap; + export function OrderedMap(obj: {[key: string]: V}): OrderedMap; + export function OrderedMap(): OrderedMap; + export function OrderedMap(): OrderedMap; + export interface OrderedMap extends Map { + // Sequence algorithms + concat(...collections: Array>): OrderedMap; + concat(...collections: Array<{[key: string]: C}>): OrderedMap; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): OrderedMap; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): OrderedMap; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): OrderedMap; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): OrderedMap; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): OrderedMap; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + export module Set { + function isSet(maybeSet: any): maybeSet is Set; + function of(...values: Array): Set; + function fromKeys(iter: Collection): Set; + function fromKeys(obj: {[key: string]: any}): Set; + function intersect(sets: Iterable>): Set; + function union(sets: Iterable>): Set; + } + export function Set(): Set; + export function Set(): Set; + export function Set(collection: Iterable): Set; + export interface Set extends Collection.Set { + // Persistent changes + add(value: T): this; + delete(value: T): this; + remove(value: T): this; + clear(): this; + union(...collections: Array | Array>): this; + merge(...collections: Array | Array>): this; + intersect(...collections: Array | Array>): this; + subtract(...collections: Array | Array>): this; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Set; + map(mapper: (value: T, key: never, iter: this) => M, context?: any): Set; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): Set; + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Set; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + } + export module OrderedSet { + function isOrderedSet(maybeOrderedSet: any): boolean; + function of(...values: Array): OrderedSet; + function fromKeys(iter: Collection): OrderedSet; + function fromKeys(obj: {[key: string]: any}): OrderedSet; + } + export function OrderedSet(): OrderedSet; + export function OrderedSet(): OrderedSet; + export function OrderedSet(collection: Iterable): OrderedSet; + export interface OrderedSet extends Set { + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): OrderedSet; + map(mapper: (value: T, key: never, iter: this) => M, context?: any): OrderedSet; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): OrderedSet; + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): OrderedSet; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + zip(...collections: Array>): OrderedSet; + zipWith(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection): OrderedSet; + zipWith(zipper: (value: T, otherValue: U, thirdValue: V) => Z, otherCollection: Collection, thirdCollection: Collection): OrderedSet; + zipWith(zipper: (...any: Array) => Z, ...collections: Array>): OrderedSet; + } + export module Stack { + function isStack(maybeStack: any): maybeStack is Stack; + function of(...values: Array): Stack; + } + export function Stack(): Stack; + export function Stack(): Stack; + export function Stack(collection: Iterable): Stack; + export interface Stack extends Collection.Indexed { + // Reading values + peek(): T | undefined; + // Persistent changes + clear(): Stack; + unshift(...values: Array): Stack; + unshiftAll(iter: Iterable): Stack; + shift(): Stack; + push(...values: Array): Stack; + pushAll(iter: Iterable): Stack; + pop(): Stack; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Stack; + map(mapper: (value: T, key: number, iter: this) => M, context?: any): Stack; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): Stack; + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Set; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + } + export function Range(start?: number, end?: number, step?: number): Seq.Indexed; + export function Repeat(value: T, times?: number): Seq.Indexed; + export module Record { + export function isRecord(maybeRecord: any): maybeRecord is Record.Instance; + export function getDescriptiveName(record: Instance): string; + export interface Class { + (values?: Partial | Iterable<[string, any]>): Instance & Readonly; + new (values?: Partial | Iterable<[string, any]>): Instance & Readonly; + } + export interface Instance { + readonly size: number; + // Reading values + has(key: string): boolean; + get(key: K): T[K]; + // Reading deep values + hasIn(keyPath: Iterable): boolean; + getIn(keyPath: Iterable): any; + // Value equality + equals(other: any): boolean; + hashCode(): number; + // Persistent changes + set(key: K, value: T[K]): this; + update(key: K, updater: (value: T[K]) => T[K]): this; + merge(...collections: Array | Iterable<[string, any]>>): this; + mergeDeep(...collections: Array | Iterable<[string, any]>>): this; + mergeWith(merger: (oldVal: any, newVal: any, key: keyof T) => any, ...collections: Array | Iterable<[string, any]>>): this; + mergeDeepWith(merger: (oldVal: any, newVal: any, key: any) => any, ...collections: Array | Iterable<[string, any]>>): this; + delete(key: K): this; + remove(key: K): this; + clear(): this; + // Deep persistent changes + setIn(keyPath: Iterable, value: any): this; + updateIn(keyPath: Iterable, updater: (value: any) => any): this; + mergeIn(keyPath: Iterable, ...collections: Array): this; + mergeDeepIn(keyPath: Iterable, ...collections: Array): this; + deleteIn(keyPath: Iterable): this; + removeIn(keyPath: Iterable): this; + // Conversion to JavaScript types + toJS(): { [K in keyof T]: any }; + toJSON(): T; + toObject(): T; + // Transient changes + withMutations(mutator: (mutable: this) => any): this; + asMutable(): this; + asImmutable(): this; + // Sequence algorithms + toSeq(): Seq.Keyed; + [Symbol.iterator](): IterableIterator<[keyof T, T[keyof T]]>; + } + } + export function Record(defaultValues: T, name?: string): Record.Class; + export module Seq { + function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed | Seq.Keyed; + function of(...values: Array): Seq.Indexed; + export module Keyed {} + export function Keyed(collection: Iterable<[K, V]>): Seq.Keyed; + export function Keyed(obj: {[key: string]: V}): Seq.Keyed; + export function Keyed(): Seq.Keyed; + export function Keyed(): Seq.Keyed; + export interface Keyed extends Seq, Collection.Keyed { + toJS(): Object; + toJSON(): { [key: string]: V }; + toSeq(): this; + concat(...collections: Array>): Seq.Keyed; + concat(...collections: Array<{[key: string]: C}>): Seq.Keyed; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Seq.Keyed; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): Seq.Keyed; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Seq.Keyed; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Seq.Keyed; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Seq.Keyed; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + module Indexed { + function of(...values: Array): Seq.Indexed; + } + export function Indexed(): Seq.Indexed; + export function Indexed(): Seq.Indexed; + export function Indexed(collection: Iterable): Seq.Indexed; + export interface Indexed extends Seq, Collection.Indexed { + toJS(): Array; + toJSON(): Array; + toSeq(): this; + concat(...valuesOrCollections: Array | C>): Seq.Indexed; + map(mapper: (value: T, key: number, iter: this) => M, context?: any): Seq.Indexed; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): Seq.Indexed; + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Seq.Indexed; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + } + export module Set { + function of(...values: Array): Seq.Set; + } + export function Set(): Seq.Set; + export function Set(): Seq.Set; + export function Set(collection: Iterable): Seq.Set; + export interface Set extends Seq, Collection.Set { + toJS(): Array; + toJSON(): Array; + toSeq(): this; + concat(...valuesOrCollections: Array | C>): Seq.Set; + map(mapper: (value: T, key: never, iter: this) => M, context?: any): Seq.Set; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): Seq.Set; + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Seq.Set; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + } + } + export function Seq>(seq: S): S; + export function Seq(collection: Collection.Keyed): Seq.Keyed; + export function Seq(collection: Collection.Indexed): Seq.Indexed; + export function Seq(collection: Collection.Set): Seq.Set; + export function Seq(collection: Iterable): Seq.Indexed; + export function Seq(obj: {[key: string]: V}): Seq.Keyed; + export function Seq(): Seq; + export interface Seq extends Collection { + readonly size: number | undefined; + // Force evaluation + cacheResult(): this; + // Sequence algorithms + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Seq; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Seq; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Seq; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + } + export module Collection { + function isKeyed(maybeKeyed: any): maybeKeyed is Collection.Keyed; + function isIndexed(maybeIndexed: any): maybeIndexed is Collection.Indexed; + function isAssociative(maybeAssociative: any): maybeAssociative is Collection.Keyed | Collection.Indexed; + function isOrdered(maybeOrdered: any): boolean; + export module Keyed {} + export function Keyed(collection: Iterable<[K, V]>): Collection.Keyed; + export function Keyed(obj: {[key: string]: V}): Collection.Keyed; + export interface Keyed extends Collection { + toJS(): Object; + toJSON(): { [key: string]: V }; + toSeq(): Seq.Keyed; + // Sequence functions + flip(): this; + concat(...collections: Array>): Collection.Keyed; + concat(...collections: Array<{[key: string]: C}>): Collection.Keyed; + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Collection.Keyed; + mapKeys(mapper: (key: K, value: V, iter: this) => M, context?: any): Collection.Keyed; + mapEntries(mapper: (entry: [K, V], index: number, iter: this) => [KM, VM], context?: any): Collection.Keyed; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Collection.Keyed; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Collection.Keyed; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + [Symbol.iterator](): IterableIterator<[K, V]>; + } + export module Indexed {} + export function Indexed(collection: Iterable): Collection.Indexed; + export interface Indexed extends Collection { + toJS(): Array; + toJSON(): Array; + // Reading values + get(index: number, notSetValue: NSV): T | NSV; + get(index: number): T | undefined; + // Conversion to Seq + toSeq(): Seq.Indexed; + fromEntrySeq(): Seq.Keyed; + // Combination + interpose(separator: T): this; + interleave(...collections: Array>): this; + splice(index: number, removeNum: number, ...values: Array): this; + zip(...collections: Array>): Collection.Indexed; + zipWith(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection): Collection.Indexed; + zipWith(zipper: (value: T, otherValue: U, thirdValue: V) => Z, otherCollection: Collection, thirdCollection: Collection): Collection.Indexed; + zipWith(zipper: (...any: Array) => Z, ...collections: Array>): Collection.Indexed; + // Search for value + indexOf(searchValue: T): number; + lastIndexOf(searchValue: T): number; + findIndex(predicate: (value: T, index: number, iter: this) => boolean, context?: any): number; + findLastIndex(predicate: (value: T, index: number, iter: this) => boolean, context?: any): number; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Collection.Indexed; + map(mapper: (value: T, key: number, iter: this) => M, context?: any): Collection.Indexed; + flatMap(mapper: (value: T, key: number, iter: this) => Iterable, context?: any): Collection.Indexed; + filter(predicate: (value: T, index: number, iter: this) => value is F, context?: any): Collection.Indexed; + filter(predicate: (value: T, index: number, iter: this) => any, context?: any): this; + [Symbol.iterator](): IterableIterator; + } + export module Set {} + export function Set(collection: Iterable): Collection.Set; + export interface Set extends Collection { + toJS(): Array; + toJSON(): Array; + toSeq(): Seq.Set; + // Sequence algorithms + concat(...valuesOrCollections: Array | C>): Collection.Set; + map(mapper: (value: T, key: never, iter: this) => M, context?: any): Collection.Set; + flatMap(mapper: (value: T, key: never, iter: this) => Iterable, context?: any): Collection.Set; + filter(predicate: (value: T, key: never, iter: this) => value is F, context?: any): Collection.Set; + filter(predicate: (value: T, key: never, iter: this) => any, context?: any): this; + [Symbol.iterator](): IterableIterator; + } + } + export function Collection>(collection: I): I; + export function Collection(collection: Iterable): Collection.Indexed; + export function Collection(obj: {[key: string]: V}): Collection.Keyed; + export interface Collection extends ValueObject { + // Value equality + equals(other: any): boolean; + hashCode(): number; + // Reading values + get(key: K, notSetValue: NSV): V | NSV; + get(key: K): V | undefined; + has(key: K): boolean; + includes(value: V): boolean; + contains(value: V): boolean; + first(): V | undefined; + last(): V | undefined; + // Reading deep values + getIn(searchKeyPath: Iterable, notSetValue?: any): any; + hasIn(searchKeyPath: Iterable): boolean; + // Persistent changes + update(updater: (value: this) => R): R; + // Conversion to JavaScript types + toJS(): Array | { [key: string]: any }; + toJSON(): Array | { [key: string]: V }; + toArray(): Array; + toObject(): { [key: string]: V }; + // Conversion to Collections + toMap(): Map; + toOrderedMap(): OrderedMap; + toSet(): Set; + toOrderedSet(): OrderedSet; + toList(): List; + toStack(): Stack; + // Conversion to Seq + toSeq(): this; + toKeyedSeq(): Seq.Keyed; + toIndexedSeq(): Seq.Indexed; + toSetSeq(): Seq.Set; + // Iterators + keys(): IterableIterator; + values(): IterableIterator; + entries(): IterableIterator<[K, V]>; + // Collections (Seq) + keySeq(): Seq.Indexed; + valueSeq(): Seq.Indexed; + entrySeq(): Seq.Indexed<[K, V]>; + // Sequence algorithms + map(mapper: (value: V, key: K, iter: this) => M, context?: any): Collection; + filter(predicate: (value: V, key: K, iter: this) => value is F, context?: any): Collection; + filter(predicate: (value: V, key: K, iter: this) => any, context?: any): this; + filterNot(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + reverse(): this; + sort(comparator?: (valueA: V, valueB: V) => number): this; + sortBy(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): this; + groupBy(grouper: (value: V, key: K, iter: this) => G, context?: any): /*Map*/Seq.Keyed>; + // Side effects + forEach(sideEffect: (value: V, key: K, iter: this) => any, context?: any): number; + // Creating subsets + slice(begin?: number, end?: number): this; + rest(): this; + butLast(): this; + skip(amount: number): this; + skipLast(amount: number): this; + skipWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + skipUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + take(amount: number): this; + takeLast(amount: number): this; + takeWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + takeUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: any): this; + // Combination + concat(...valuesOrCollections: Array): Collection; + flatten(depth?: number): Collection; + flatten(shallow?: boolean): Collection; + flatMap(mapper: (value: V, key: K, iter: this) => Iterable, context?: any): Collection; + // Reducing a value + reduce(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R; + reduce(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + reduceRight(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: any): R; + reduceRight(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R; + every(predicate: (value: V, key: K, iter: this) => boolean, context?: any): boolean; + some(predicate: (value: V, key: K, iter: this) => boolean, context?: any): boolean; + join(separator?: string): string; + isEmpty(): boolean; + count(): number; + count(predicate: (value: V, key: K, iter: this) => boolean, context?: any): number; + countBy(grouper: (value: V, key: K, iter: this) => G, context?: any): Map; + // Search for value + find(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): V | undefined; + findLast(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): V | undefined; + findEntry(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): [K, V] | undefined; + findLastEntry(predicate: (value: V, key: K, iter: this) => boolean, context?: any, notSetValue?: V): [K, V] | undefined; + findKey(predicate: (value: V, key: K, iter: this) => boolean, context?: any): K | undefined; + findLastKey(predicate: (value: V, key: K, iter: this) => boolean, context?: any): K | undefined; + keyOf(searchValue: V): K | undefined; + lastKeyOf(searchValue: V): K | undefined; + max(comparator?: (valueA: V, valueB: V) => number): V | undefined; + maxBy(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): V | undefined; + min(comparator?: (valueA: V, valueB: V) => number): V | undefined; + minBy(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number): V | undefined; + // Comparison + isSubset(iter: Iterable): boolean; + isSuperset(iter: Iterable): boolean; + readonly size: number; + } +} +declare module "immutable" { + export = Immutable +} From 05477e4d008861ef8492447764b220268961be72 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 23 Aug 2017 11:49:24 -0700 Subject: [PATCH 35/60] Update baselines --- .../reference/typeParameterAssignmentCompat1.errors.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/baselines/reference/typeParameterAssignmentCompat1.errors.txt b/tests/baselines/reference/typeParameterAssignmentCompat1.errors.txt index 9665ef017c02e..2ca4299c7f8d6 100644 --- a/tests/baselines/reference/typeParameterAssignmentCompat1.errors.txt +++ b/tests/baselines/reference/typeParameterAssignmentCompat1.errors.txt @@ -1,11 +1,8 @@ tests/cases/compiler/typeParameterAssignmentCompat1.ts(8,5): error TS2322: Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'T'. tests/cases/compiler/typeParameterAssignmentCompat1.ts(9,5): error TS2322: Type 'Foo' is not assignable to type 'Foo'. - Type 'T' is not assignable to type 'U'. tests/cases/compiler/typeParameterAssignmentCompat1.ts(16,9): error TS2322: Type 'Foo' is not assignable to type 'Foo'. - Type 'U' is not assignable to type 'T'. tests/cases/compiler/typeParameterAssignmentCompat1.ts(17,9): error TS2322: Type 'Foo' is not assignable to type 'Foo'. - Type 'T' is not assignable to type 'U'. ==== tests/cases/compiler/typeParameterAssignmentCompat1.ts (4 errors) ==== @@ -23,7 +20,6 @@ tests/cases/compiler/typeParameterAssignmentCompat1.ts(17,9): error TS2322: Type return x; ~~~~~~~~~ !!! error TS2322: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. } class C { @@ -33,10 +29,8 @@ tests/cases/compiler/typeParameterAssignmentCompat1.ts(17,9): error TS2322: Type x = y; // should be an error ~ !!! error TS2322: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2322: Type 'U' is not assignable to type 'T'. return x; ~~~~~~~~~ !!! error TS2322: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. } } \ No newline at end of file From 0ff8eeb308e1aa322cce35db125715cbaffc2341 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 23 Aug 2017 11:57:06 -0700 Subject: [PATCH 36/60] Comment getTypeReferenceId and getRelationKey --- src/compiler/checker.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e07ab5c7a286d..272369df1ef6d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9774,6 +9774,10 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Reference && some((type).typeArguments, isUnconstrainedTypeParameter); } + /** + * getTypeReferenceId(A) returns "111=0-12=1" + * where A.id=111 and number.id=12 + */ function getTypeReferenceId(type: TypeReference, typeParameters: Type[]) { let result = "" + type.target.id; for (const t of type.typeArguments) { @@ -9792,6 +9796,10 @@ namespace ts { return result; } + /** + * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. + * For other cases, the types ids are used. + */ function getRelationKey(source: Type, target: Type, relation: Map) { if (relation === identityRelation && source.id > target.id) { const temp = source; From 16a4997565e7ff356c910fd5f4415223782fbb29 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 6 Sep 2017 22:09:38 -0700 Subject: [PATCH 37/60] Fix 18224 (#18259) (#18292) * Probably fix 18224 * Corrected test --- src/compiler/checker.ts | 2 +- tests/baselines/reference/jsdocTypecastNoTypeNoCrash.js | 8 ++++++++ .../reference/jsdocTypecastNoTypeNoCrash.symbols | 8 ++++++++ .../baselines/reference/jsdocTypecastNoTypeNoCrash.types | 9 +++++++++ tests/cases/compiler/jsdocTypecastNoTypeNoCrash.ts | 5 +++++ 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/jsdocTypecastNoTypeNoCrash.js create mode 100644 tests/baselines/reference/jsdocTypecastNoTypeNoCrash.symbols create mode 100644 tests/baselines/reference/jsdocTypecastNoTypeNoCrash.types create mode 100644 tests/cases/compiler/jsdocTypecastNoTypeNoCrash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 272369df1ef6d..e2668c2fa68a7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18034,7 +18034,7 @@ namespace ts { function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type { if (isInJavaScriptFile(node) && node.jsDoc) { - const typecasts = flatMap(node.jsDoc, doc => filter(doc.tags, tag => tag.kind === SyntaxKind.JSDocTypeTag)); + const typecasts = flatMap(node.jsDoc, doc => filter(doc.tags, tag => tag.kind === SyntaxKind.JSDocTypeTag && !!(tag as JSDocTypeTag).typeExpression && !!(tag as JSDocTypeTag).typeExpression.type)); if (typecasts && typecasts.length) { // We should have already issued an error if there were multiple type jsdocs const cast = typecasts[0] as JSDocTypeTag; diff --git a/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.js b/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.js new file mode 100644 index 0000000000000..06c7924440b4d --- /dev/null +++ b/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.js @@ -0,0 +1,8 @@ +//// [index.js] +function Foo() {} +const a = /* @type string */(Foo); + + +//// [index.js] +function Foo() { } +var a = (Foo); diff --git a/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.symbols b/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.symbols new file mode 100644 index 0000000000000..7a9d98e39ecc6 --- /dev/null +++ b/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/index.js === +function Foo() {} +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + +const a = /* @type string */(Foo); +>a : Symbol(a, Decl(index.js, 1, 5)) +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + diff --git a/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.types b/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.types new file mode 100644 index 0000000000000..590940b51ffd7 --- /dev/null +++ b/tests/baselines/reference/jsdocTypecastNoTypeNoCrash.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/index.js === +function Foo() {} +>Foo : () => void + +const a = /* @type string */(Foo); +>a : () => void +>(Foo) : () => void +>Foo : () => void + diff --git a/tests/cases/compiler/jsdocTypecastNoTypeNoCrash.ts b/tests/cases/compiler/jsdocTypecastNoTypeNoCrash.ts new file mode 100644 index 0000000000000..8c5e52d34f001 --- /dev/null +++ b/tests/cases/compiler/jsdocTypecastNoTypeNoCrash.ts @@ -0,0 +1,5 @@ +// @allowJS: true +// @outDir: ./out +// @filename: index.js +function Foo() {} +const a = /* @type string */(Foo); From f5b9e30986d2195b286c6a9b71a1de6ce89d8e9c Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 7 Sep 2017 16:21:51 -0700 Subject: [PATCH 38/60] Ensure that emitter calls callbacks (#18284) (#18325) * Ensure that emitter calls calbacks * Move new parameter to end of parameters * Fix for ConditionalExpression * Make suggested changes to emitter * Fix parameter ordering * Respond to minor comments * Remove potentially expensive assertion * More emitter cleanup --- src/compiler/emitter.ts | 123 ++++++++-------- src/compiler/factory.ts | 60 +++++++- src/compiler/transformers/es2017.ts | 3 +- src/compiler/transformers/esnext.ts | 3 +- src/compiler/transformers/ts.ts | 3 +- src/compiler/types.ts | 9 +- src/compiler/utilities.ts | 3 +- src/compiler/visitor.ts | 3 + src/services/formatting/formatting.ts | 1 + src/services/refactors/extractMethod.ts | 4 +- src/services/textChanges.ts | 28 ++-- .../reference/extractMethod/extractMethod4.js | 24 ++-- .../sourceMapValidationStatements.js.map | 2 +- ...ourceMapValidationStatements.sourcemap.txt | 132 +++++++++++------- .../ternaryExpressionSourceMap.js.map | 2 +- .../ternaryExpressionSourceMap.sourcemap.txt | 90 ++++++------ ...ypeGuardsInRightOperandOfAndAndOperator.js | 2 + .../typeGuardsInRightOperandOfOrOrOperator.js | 2 + .../fourslash/extract-method-formatting.ts | 24 ++++ 19 files changed, 322 insertions(+), 196 deletions(-) create mode 100644 tests/cases/fourslash/extract-method-formatting.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5444c618353bd..54baf9c8a7e8b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -406,6 +406,14 @@ namespace ts { setWriter(/*output*/ undefined); } + // TODO: Should this just be `emit`? + // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034 + function emitIfPresent(node: Node | undefined) { + if (node) { + emit(node); + } + } + function emit(node: Node) { pipelineEmitWithNotification(EmitHint.Unspecified, node); } @@ -451,6 +459,7 @@ namespace ts { case EmitHint.SourceFile: return pipelineEmitSourceFile(node); case EmitHint.IdentifierName: return pipelineEmitIdentifierName(node); case EmitHint.Expression: return pipelineEmitExpression(node); + case EmitHint.MappedTypeParameter: return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration)); case EmitHint.Unspecified: return pipelineEmitUnspecified(node); } } @@ -465,6 +474,12 @@ namespace ts { emitIdentifier(node); } + function emitMappedTypeParameter(node: TypeParameterDeclaration): void { + emit(node.name); + write(" in "); + emit(node.constraint); + } + function pipelineEmitUnspecified(node: Node): void { const kind = node.kind; @@ -898,9 +913,9 @@ namespace ts { function emitParameter(node: ParameterDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -918,7 +933,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -927,7 +942,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -937,7 +952,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -947,9 +962,9 @@ namespace ts { function emitMethodDeclaration(node: MethodDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } @@ -1035,10 +1050,8 @@ namespace ts { function emitTypeLiteral(node: TypeLiteralNode) { write("{"); - // If the literal is empty, do not add spaces between braces. - if (node.members.length > 0) { - emitList(node, node.members, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers); - } + const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers; + emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty); write("}"); } @@ -1094,13 +1107,16 @@ namespace ts { writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); + } + write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); + pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter); write("]"); - writeIfPresent(node.questionToken, "?"); + + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -1148,7 +1164,7 @@ namespace ts { function emitBindingElement(node: BindingElement) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } @@ -1159,33 +1175,22 @@ namespace ts { function emitArrayLiteralExpression(node: ArrayLiteralExpression) { const elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine); - } + const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; + emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine); } function emitObjectLiteralExpression(node: ObjectLiteralExpression) { - const properties = node.properties; - if (properties.length === 0) { - write("{}"); + const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + if (indentedFlag) { + increaseIndent(); } - else { - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; - if (indentedFlag) { - increaseIndent(); - } - const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None; - emitList(node, properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); + const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; + const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None; + emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + if (indentedFlag) { + decreaseIndent(); } } @@ -1286,7 +1291,8 @@ namespace ts { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node: DeleteExpression) { @@ -1364,13 +1370,13 @@ namespace ts { emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); @@ -1382,7 +1388,8 @@ namespace ts { } function emitYieldExpression(node: YieldExpression) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } @@ -1662,7 +1669,9 @@ namespace ts { function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + emitIfPresent(node.asteriskToken); + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -2068,9 +2077,7 @@ namespace ts { function emitJsxExpression(node: JsxExpression) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -2128,13 +2135,12 @@ namespace ts { emitTrailingCommentsOfPosition(statements.pos); } + let format = ListFormat.CaseOrDefaultClauseStatements; if (emitAsSingleStatement) { write(" "); - emit(statements[0]); - } - else { - emitList(parentNode, statements, ListFormat.CaseOrDefaultClauseStatements); + format &= ~(ListFormat.MultiLine | ListFormat.Indented); } + emitList(parentNode, statements, format); } function emitHeritageClause(node: HeritageClause) { @@ -2384,7 +2390,7 @@ namespace ts { function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis); } else { emitParameters(parentNode, parameters); @@ -2427,7 +2433,7 @@ namespace ts { if (format & ListFormat.MultiLine) { writeLine(); } - else if (format & ListFormat.SpaceBetweenBraces) { + else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) { write(" "); } } @@ -2568,12 +2574,6 @@ namespace ts { } } - function writeIfPresent(node: Node, text: string) { - if (node) { - write(text); - } - } - function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) @@ -2584,7 +2584,7 @@ namespace ts { if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } @@ -3107,6 +3107,9 @@ namespace ts { NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. NoInterveningComments = 1 << 17, // Do not emit comments between each node + NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. + SingleElement = 1 << 19, + // Precomputed Formats Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, HeritageClauses = SingleLine | SpaceBetweenSiblings, @@ -3118,7 +3121,7 @@ namespace ts { IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings, ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings, - ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces, + ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 04e6b5553e894..25209c6278b4f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -281,7 +281,7 @@ namespace ts { || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } @@ -1016,19 +1016,49 @@ namespace ts { return node; } + /* @deprecated */ export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: ConciseBody): ArrowFunction; export function updateArrowFunction( node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, - body: ConciseBody) { + equalsGreaterThanToken: Token, + body: ConciseBody): ArrowFunction; + export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + equalsGreaterThanTokenOrBody: Token | ConciseBody, + bodyOrUndefined?: ConciseBody, + ): ArrowFunction { + let equalsGreaterThanToken: Token; + let body: ConciseBody; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = cast(equalsGreaterThanTokenOrBody, isConciseBody); + } + else { + equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token => + n.kind === SyntaxKind.EqualsGreaterThanToken); + body = bodyOrUndefined; + } + return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } @@ -1135,11 +1165,31 @@ namespace ts { return node; } - export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) { + /* @deprecated */ export function updateConditional( + node: ConditionalExpression, + condition: Expression, + whenTrue: Expression, + whenFalse: Expression): ConditionalExpression; + export function updateConditional( + node: ConditionalExpression, + condition: Expression, + questionToken: Token, + whenTrue: Expression, + colonToken: Token, + whenFalse: Expression): ConditionalExpression; + export function updateConditional(node: ConditionalExpression, condition: Expression, ...args: any[]) { + if (args.length === 2) { + const [whenTrue, whenFalse] = args; + return updateConditional(node, condition, node.questionToken, whenTrue, node.colonToken, whenFalse); + } + Debug.assert(args.length === 4); + const [questionToken, whenTrue, colonToken, whenFalse] = args; return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 43058358ee5f7..85a44e35983d4 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -197,9 +197,10 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + node.equalsGreaterThanToken, getFunctionFlags(node) & FunctionFlags.Async ? transformAsyncFunctionBody(node) - : visitFunctionBody(node.body, visitor, context) + : visitFunctionBody(node.body, visitor, context), ); } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 3bdcc9e9ee722..0fca09b454017 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -595,7 +595,8 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - transformFunctionBody(node) + node.equalsGreaterThanToken, + transformFunctionBody(node), ); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 692c758bc7504..ad7aaab252471 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2291,7 +2291,8 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - visitFunctionBody(node.body, visitor, context) + node.equalsGreaterThanToken, + visitFunctionBody(node.body, visitor, context), ); return updated; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5a5724503c082..1deef10a6138b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4223,10 +4223,11 @@ namespace ts { } export const enum EmitHint { - SourceFile, // Emitting a SourceFile - Expression, // Emitting an Expression - IdentifierName, // Emitting an IdentifierName - Unspecified, // Emitting an otherwise unspecified node + SourceFile, // Emitting a SourceFile + Expression, // Emitting an Expression + IdentifierName, // Emitting an IdentifierName + MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode + Unspecified, // Emitting an otherwise unspecified node } /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 25ba99cb15403..f116794c9c6c5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4628,8 +4628,7 @@ namespace ts { /* @internal */ export function isNodeArray(array: ReadonlyArray): array is NodeArray { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } // Literals diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 1ce42199372d8..7d46630e227d4 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -488,6 +488,7 @@ namespace ts { nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), + visitNode((node).equalsGreaterThanToken, visitor, isToken), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.DeleteExpression: @@ -523,7 +524,9 @@ namespace ts { case SyntaxKind.ConditionalExpression: return updateConditional(node, visitNode((node).condition, visitor, isExpression), + visitNode((node).questionToken, visitor, isToken), visitNode((node).whenTrue, visitor, isExpression), + visitNode((node).colonToken, visitor, isToken), visitNode((node).whenFalse, visitor, isExpression)); case SyntaxKind.TemplateExpression: diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index ad9b2f179aac6..8be7f0e9e7384 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -729,6 +729,7 @@ namespace ts.formatting { parent: Node, parentStartLine: number, parentDynamicIndentation: DynamicIndentation): void { + Debug.assert(isNodeArray(nodes)); const listStartToken = getOpenTokenForList(parent, nodes); const listEndToken = getCloseTokenForOpenToken(listStartToken); diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts index 9634b9c817281..4cec56474b953 100644 --- a/src/services/refactors/extractMethod.ts +++ b/src/services/refactors/extractMethod.ts @@ -678,7 +678,7 @@ namespace ts.refactor.extractMethod { range.facts & RangeFacts.IsGenerator ? createToken(SyntaxKind.AsteriskToken) : undefined, functionName, /*questionToken*/ undefined, - /*typeParameters*/[], + /*typeParameters*/ undefined, parameters, returnType, body @@ -690,7 +690,7 @@ namespace ts.refactor.extractMethod { range.facts & RangeFacts.IsAsyncFunction ? [createToken(SyntaxKind.AsyncKeyword)] : undefined, range.facts & RangeFacts.IsGenerator ? createToken(SyntaxKind.AsteriskToken) : undefined, functionName, - /*typeParameters*/[], + /*typeParameters*/ undefined, parameters, returnType, body diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index bddfc205db4c4..1c2c40e77f218 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -5,19 +5,25 @@ namespace ts.textChanges { * Currently for simplicity we store recovered positions on the node itself. * It can be changed to side-table later if we decide that current design is too invasive. */ - function getPos(n: TextRange) { - return (n)["__pos"]; + function getPos(n: TextRange): number { + const result = (n)["__pos"]; + Debug.assert(typeof result === "number"); + return result; } - function setPos(n: TextRange, pos: number) { + function setPos(n: TextRange, pos: number): void { + Debug.assert(typeof pos === "number"); (n)["__pos"] = pos; } - function getEnd(n: TextRange) { - return (n)["__end"]; + function getEnd(n: TextRange): number { + const result = (n)["__end"]; + Debug.assert(typeof result === "number"); + return result; } - function setEnd(n: TextRange, end: number) { + function setEnd(n: TextRange, end: number): void { + Debug.assert(typeof end === "number"); (n)["__end"] = end; } @@ -582,7 +588,7 @@ namespace ts.textChanges { readonly node: Node; } - export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText { + function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText { const options = { newLine, target: sourceFile && sourceFile.languageVersion }; const writer = new Writer(getNewLineCharacter(options)); const printer = createPrinter(options, writer); @@ -590,7 +596,7 @@ namespace ts.textChanges { return { text: writer.getText(), node: assignPositionsToNode(node) }; } - export function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) { + function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) { const lineMap = computeLineStarts(nonFormattedText.text); const file: SourceFileLike = { text: nonFormattedText.text, @@ -616,14 +622,10 @@ namespace ts.textChanges { function assignPositionsToNode(node: Node): Node { const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes - const newNode = nodeIsSynthesized(visited) - ? visited - : (Proxy.prototype = visited, new (Proxy)()); + const newNode = nodeIsSynthesized(visited) ? visited : Object.create(visited) as Node; newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; - - function Proxy() { } } function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { diff --git a/tests/baselines/reference/extractMethod/extractMethod4.js b/tests/baselines/reference/extractMethod/extractMethod4.js index 07029b2d05063..8d4feb3ea2364 100644 --- a/tests/baselines/reference/extractMethod/extractMethod4.js +++ b/tests/baselines/reference/extractMethod/extractMethod4.js @@ -24,9 +24,9 @@ namespace A { async function newFunction() { let y = 5; - if(z) { - await z1; - } + if (z) { + await z1; + } return foo(); } } @@ -44,9 +44,9 @@ namespace A { async function newFunction(z: number, z1: any) { let y = 5; - if(z) { - await z1; - } + if (z) { + await z1; + } return foo(); } } @@ -64,9 +64,9 @@ namespace A { async function newFunction(z: number, z1: any) { let y = 5; - if(z) { - await z1; - } + if (z) { + await z1; + } return foo(); } } @@ -83,8 +83,8 @@ namespace A { } async function newFunction(z: number, z1: any, foo: () => void) { let y = 5; - if(z) { - await z1; -} + if (z) { + await z1; + } return foo(); } diff --git a/tests/baselines/reference/sourceMapValidationStatements.js.map b/tests/baselines/reference/sourceMapValidationStatements.js.map index 5841f329e5edf..40d65e0106c1c 100644 --- a/tests/baselines/reference/sourceMapValidationStatements.js.map +++ b/tests/baselines/reference/sourceMapValidationStatements.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationStatements.js.map] -{"version":3,"file":"sourceMapValidationStatements.js","sourceRoot":"","sources":["sourceMapValidationStatements.ts"],"names":[],"mappings":"AAAA;IACI,IAAI,CAAC,CAAC;IACN,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,CAAC,IAAI,CAAC,CAAC;QACP,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IACD,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACT,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IAAC,IAAI,CAAC,CAAC;QACJ,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,EAAE,CAAC;IACR,CAAC;IACD,IAAI,CAAC,GAAG;QACJ,CAAC;QACD,CAAC;QACD,CAAC;KACJ,CAAC;IACF,IAAI,GAAG,GAAG;QACN,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,OAAO;KACb,CAAC;IACF,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACD,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACnB,CAAC;IAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACT,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACb,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QAClB,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACD,MAAM,IAAI,KAAK,EAAE,CAAC;IACtB,CAAC;IAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACV,IAAI,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;YAAS,CAAC;QACP,CAAC,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,GAAG,EAAE,CAAC;QACR,CAAC,GAAG,CAAC,CAAC;QACN,CAAC,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACZ,KAAK,CAAC,EAAE,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,KAAK,CAAC;QAEV,CAAC;QACD,KAAK,CAAC,EAAE,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,KAAK,CAAC;QAEV,CAAC;QACD,SAAS,CAAC;YACN,CAAC,IAAI,CAAC,CAAC;YACP,CAAC,GAAG,EAAE,CAAC;YACP,KAAK,CAAC;QAEV,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;QACZ,CAAC,EAAE,CAAC;IACR,CAAC;IACD,GAAG,CAAC;QACA,CAAC,EAAE,CAAC;IACR,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAC;IACf,CAAC,GAAG,CAAC,CAAC;IACN,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC,KAAK,CAAC,CAAC;IACR,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,CAAC;AACX,CAAC;AACD,IAAI,CAAC,GAAG;IACJ,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationStatements.js","sourceRoot":"","sources":["sourceMapValidationStatements.ts"],"names":[],"mappings":"AAAA;IACI,IAAI,CAAC,CAAC;IACN,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,CAAC,IAAI,CAAC,CAAC;QACP,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IACD,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACT,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IAAC,IAAI,CAAC,CAAC;QACJ,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,EAAE,CAAC;IACR,CAAC;IACD,IAAI,CAAC,GAAG;QACJ,CAAC;QACD,CAAC;QACD,CAAC;KACJ,CAAC;IACF,IAAI,GAAG,GAAG;QACN,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,OAAO;KACb,CAAC;IACF,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACD,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACnB,CAAC;IAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACT,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACb,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QAClB,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACD,MAAM,IAAI,KAAK,EAAE,CAAC;IACtB,CAAC;IAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACV,IAAI,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;YAAS,CAAC;QACP,CAAC,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,GAAG,EAAE,CAAC;QACR,CAAC,GAAG,CAAC,CAAC;QACN,CAAC,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACZ,KAAK,CAAC,EAAE,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,KAAK,CAAC;QAEV,CAAC;QACD,KAAK,CAAC,EAAE,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,KAAK,CAAC;QAEV,CAAC;QACD,SAAS,CAAC;YACN,CAAC,IAAI,CAAC,CAAC;YACP,CAAC,GAAG,EAAE,CAAC;YACP,KAAK,CAAC;QAEV,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;QACZ,CAAC,EAAE,CAAC;IACR,CAAC;IACD,GAAG,CAAC;QACA,CAAC,EAAE,CAAC;IACR,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAC;IACf,CAAC,GAAG,CAAC,CAAC;IACN,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC,KAAK,CAAC,CAAC;IACR,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,CAAC;AACX,CAAC;AACD,IAAI,CAAC,GAAG;IACJ,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt b/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt index 7c5c5bfcfeba6..aec7eaafc0629 100644 --- a/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt @@ -1251,15 +1251,19 @@ sourceFile:sourceMapValidationStatements.ts 7 > ^^^^ 8 > ^ 9 > ^ -10> ^^^ -11> ^ -12> ^^^ -13> ^ -14> ^^^ -15> ^ -16> ^^^ -17> ^ -18> ^ +10> ^ +11> ^ +12> ^ +13> ^ +14> ^^^ +15> ^ +16> ^ +17> ^ +18> ^ +19> ^ +20> ^^^ +21> ^ +22> ^ 1-> > 2 > var @@ -1270,15 +1274,19 @@ sourceFile:sourceMapValidationStatements.ts 7 > == 8 > 1 9 > ) -10> ? -11> x -12> + -13> 1 -14> : -15> x -16> - -17> 1 -18> ; +10> +11> ? +12> +13> x +14> + +15> 1 +16> +17> : +18> +19> x +20> - +21> 1 +22> ; 1->Emitted(74, 5) Source(72, 5) + SourceIndex(0) 2 >Emitted(74, 9) Source(72, 9) + SourceIndex(0) 3 >Emitted(74, 10) Source(72, 10) + SourceIndex(0) @@ -1288,15 +1296,19 @@ sourceFile:sourceMapValidationStatements.ts 7 >Emitted(74, 19) Source(72, 19) + SourceIndex(0) 8 >Emitted(74, 20) Source(72, 20) + SourceIndex(0) 9 >Emitted(74, 21) Source(72, 21) + SourceIndex(0) -10>Emitted(74, 24) Source(72, 24) + SourceIndex(0) -11>Emitted(74, 25) Source(72, 25) + SourceIndex(0) -12>Emitted(74, 28) Source(72, 28) + SourceIndex(0) -13>Emitted(74, 29) Source(72, 29) + SourceIndex(0) -14>Emitted(74, 32) Source(72, 32) + SourceIndex(0) -15>Emitted(74, 33) Source(72, 33) + SourceIndex(0) -16>Emitted(74, 36) Source(72, 36) + SourceIndex(0) -17>Emitted(74, 37) Source(72, 37) + SourceIndex(0) -18>Emitted(74, 38) Source(72, 38) + SourceIndex(0) +10>Emitted(74, 22) Source(72, 22) + SourceIndex(0) +11>Emitted(74, 23) Source(72, 23) + SourceIndex(0) +12>Emitted(74, 24) Source(72, 24) + SourceIndex(0) +13>Emitted(74, 25) Source(72, 25) + SourceIndex(0) +14>Emitted(74, 28) Source(72, 28) + SourceIndex(0) +15>Emitted(74, 29) Source(72, 29) + SourceIndex(0) +16>Emitted(74, 30) Source(72, 30) + SourceIndex(0) +17>Emitted(74, 31) Source(72, 31) + SourceIndex(0) +18>Emitted(74, 32) Source(72, 32) + SourceIndex(0) +19>Emitted(74, 33) Source(72, 33) + SourceIndex(0) +20>Emitted(74, 36) Source(72, 36) + SourceIndex(0) +21>Emitted(74, 37) Source(72, 37) + SourceIndex(0) +22>Emitted(74, 38) Source(72, 38) + SourceIndex(0) --- >>> (x == 1) ? x + 1 : x - 1; 1 >^^^^ @@ -1305,15 +1317,19 @@ sourceFile:sourceMapValidationStatements.ts 4 > ^^^^ 5 > ^ 6 > ^ -7 > ^^^ -8 > ^ -9 > ^^^ -10> ^ -11> ^^^ -12> ^ -13> ^^^ -14> ^ -15> ^ +7 > ^ +8 > ^ +9 > ^ +10> ^ +11> ^^^ +12> ^ +13> ^ +14> ^ +15> ^ +16> ^ +17> ^^^ +18> ^ +19> ^ 1 > > 2 > ( @@ -1321,30 +1337,38 @@ sourceFile:sourceMapValidationStatements.ts 4 > == 5 > 1 6 > ) -7 > ? -8 > x -9 > + -10> 1 -11> : -12> x -13> - -14> 1 -15> ; +7 > +8 > ? +9 > +10> x +11> + +12> 1 +13> +14> : +15> +16> x +17> - +18> 1 +19> ; 1 >Emitted(75, 5) Source(73, 5) + SourceIndex(0) 2 >Emitted(75, 6) Source(73, 6) + SourceIndex(0) 3 >Emitted(75, 7) Source(73, 7) + SourceIndex(0) 4 >Emitted(75, 11) Source(73, 11) + SourceIndex(0) 5 >Emitted(75, 12) Source(73, 12) + SourceIndex(0) 6 >Emitted(75, 13) Source(73, 13) + SourceIndex(0) -7 >Emitted(75, 16) Source(73, 16) + SourceIndex(0) -8 >Emitted(75, 17) Source(73, 17) + SourceIndex(0) -9 >Emitted(75, 20) Source(73, 20) + SourceIndex(0) -10>Emitted(75, 21) Source(73, 21) + SourceIndex(0) -11>Emitted(75, 24) Source(73, 24) + SourceIndex(0) -12>Emitted(75, 25) Source(73, 25) + SourceIndex(0) -13>Emitted(75, 28) Source(73, 28) + SourceIndex(0) -14>Emitted(75, 29) Source(73, 29) + SourceIndex(0) -15>Emitted(75, 30) Source(73, 30) + SourceIndex(0) +7 >Emitted(75, 14) Source(73, 14) + SourceIndex(0) +8 >Emitted(75, 15) Source(73, 15) + SourceIndex(0) +9 >Emitted(75, 16) Source(73, 16) + SourceIndex(0) +10>Emitted(75, 17) Source(73, 17) + SourceIndex(0) +11>Emitted(75, 20) Source(73, 20) + SourceIndex(0) +12>Emitted(75, 21) Source(73, 21) + SourceIndex(0) +13>Emitted(75, 22) Source(73, 22) + SourceIndex(0) +14>Emitted(75, 23) Source(73, 23) + SourceIndex(0) +15>Emitted(75, 24) Source(73, 24) + SourceIndex(0) +16>Emitted(75, 25) Source(73, 25) + SourceIndex(0) +17>Emitted(75, 28) Source(73, 28) + SourceIndex(0) +18>Emitted(75, 29) Source(73, 29) + SourceIndex(0) +19>Emitted(75, 30) Source(73, 30) + SourceIndex(0) --- >>> x === 1; 1 >^^^^ diff --git a/tests/baselines/reference/ternaryExpressionSourceMap.js.map b/tests/baselines/reference/ternaryExpressionSourceMap.js.map index 9340c972274f0..27160910378f4 100644 --- a/tests/baselines/reference/ternaryExpressionSourceMap.js.map +++ b/tests/baselines/reference/ternaryExpressionSourceMap.js.map @@ -1,2 +1,2 @@ //// [ternaryExpressionSourceMap.js.map] -{"version":3,"file":"ternaryExpressionSourceMap.js","sourceRoot":"","sources":["ternaryExpressionSourceMap.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,CAAC,CAAC;AACV,IAAI,GAAG,GAAG,CAAC,GAAG,cAAM,OAAA,CAAC,EAAD,CAAC,GAAG,cAAM,OAAA,CAAC,EAAD,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"ternaryExpressionSourceMap.js","sourceRoot":"","sources":["ternaryExpressionSourceMap.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,CAAC,CAAC;AACV,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,cAAM,OAAA,CAAC,EAAD,CAAC,CAAC,CAAC,CAAC,cAAM,OAAA,CAAC,EAAD,CAAC,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt b/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt index d46e703e3570d..87e3ce023047a 100644 --- a/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt +++ b/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt @@ -35,55 +35,67 @@ sourceFile:ternaryExpressionSourceMap.ts 3 > ^^^ 4 > ^^^ 5 > ^ -6 > ^^^ -7 > ^^^^^^^^^^^^^^ -8 > ^^^^^^^ -9 > ^ -10> ^^ -11> ^ -12> ^^^ -13> ^^^^^^^^^^^^^^ -14> ^^^^^^^ -15> ^ -16> ^^ -17> ^ -18> ^ +6 > ^ +7 > ^ +8 > ^ +9 > ^^^^^^^^^^^^^^ +10> ^^^^^^^ +11> ^ +12> ^^ +13> ^ +14> ^ +15> ^ +16> ^ +17> ^^^^^^^^^^^^^^ +18> ^^^^^^^ +19> ^ +20> ^^ +21> ^ +22> ^ 1-> > 2 >var 3 > foo 4 > = 5 > x -6 > ? -7 > () => -8 > -9 > 0 -10> -11> 0 -12> : -13> () => -14> -15> 0 -16> -17> 0 -18> ; +6 > +7 > ? +8 > +9 > () => +10> +11> 0 +12> +13> 0 +14> +15> : +16> +17> () => +18> +19> 0 +20> +21> 0 +22> ; 1->Emitted(2, 1) Source(2, 1) + SourceIndex(0) 2 >Emitted(2, 5) Source(2, 5) + SourceIndex(0) 3 >Emitted(2, 8) Source(2, 8) + SourceIndex(0) 4 >Emitted(2, 11) Source(2, 11) + SourceIndex(0) 5 >Emitted(2, 12) Source(2, 12) + SourceIndex(0) -6 >Emitted(2, 15) Source(2, 15) + SourceIndex(0) -7 >Emitted(2, 29) Source(2, 21) + SourceIndex(0) -8 >Emitted(2, 36) Source(2, 21) + SourceIndex(0) -9 >Emitted(2, 37) Source(2, 22) + SourceIndex(0) -10>Emitted(2, 39) Source(2, 21) + SourceIndex(0) -11>Emitted(2, 40) Source(2, 22) + SourceIndex(0) -12>Emitted(2, 43) Source(2, 25) + SourceIndex(0) -13>Emitted(2, 57) Source(2, 31) + SourceIndex(0) -14>Emitted(2, 64) Source(2, 31) + SourceIndex(0) -15>Emitted(2, 65) Source(2, 32) + SourceIndex(0) -16>Emitted(2, 67) Source(2, 31) + SourceIndex(0) -17>Emitted(2, 68) Source(2, 32) + SourceIndex(0) -18>Emitted(2, 69) Source(2, 33) + SourceIndex(0) +6 >Emitted(2, 13) Source(2, 13) + SourceIndex(0) +7 >Emitted(2, 14) Source(2, 14) + SourceIndex(0) +8 >Emitted(2, 15) Source(2, 15) + SourceIndex(0) +9 >Emitted(2, 29) Source(2, 21) + SourceIndex(0) +10>Emitted(2, 36) Source(2, 21) + SourceIndex(0) +11>Emitted(2, 37) Source(2, 22) + SourceIndex(0) +12>Emitted(2, 39) Source(2, 21) + SourceIndex(0) +13>Emitted(2, 40) Source(2, 22) + SourceIndex(0) +14>Emitted(2, 41) Source(2, 23) + SourceIndex(0) +15>Emitted(2, 42) Source(2, 24) + SourceIndex(0) +16>Emitted(2, 43) Source(2, 25) + SourceIndex(0) +17>Emitted(2, 57) Source(2, 31) + SourceIndex(0) +18>Emitted(2, 64) Source(2, 31) + SourceIndex(0) +19>Emitted(2, 65) Source(2, 32) + SourceIndex(0) +20>Emitted(2, 67) Source(2, 31) + SourceIndex(0) +21>Emitted(2, 68) Source(2, 32) + SourceIndex(0) +22>Emitted(2, 69) Source(2, 33) + SourceIndex(0) --- >>>//# sourceMappingURL=ternaryExpressionSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js index be1c497e3ea0d..5483f314fb9e4 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js @@ -85,6 +85,8 @@ function foo7(x) { return typeof x !== "string" && ((z = x) // number | boolean && (typeof x === "number" + // change value of x ? ((x = 10) && x.toString()) // x is number + // do not change value : ((y = x) && x.toString()))); // x is boolean } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js index a8d66dc5fa22c..c3143999d3a2c 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js @@ -87,6 +87,8 @@ function foo7(x) { return typeof x === "string" || ((z = x) // number | boolean || (typeof x === "number" + // change value of x ? ((x = 10) && x.toString()) // number | boolean | string + // do not change value : ((y = x) && x.toString()))); // number | boolean | string } diff --git a/tests/cases/fourslash/extract-method-formatting.ts b/tests/cases/fourslash/extract-method-formatting.ts new file mode 100644 index 0000000000000..1342e5632e800 --- /dev/null +++ b/tests/cases/fourslash/extract-method-formatting.ts @@ -0,0 +1,24 @@ +/// + +////function f(x: number): number { +//// /*start*/switch (x) {case 0: +////return 0;}/*end*/ +////} + +goTo.select('start', 'end') +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract function into global scope", +}); +verify.currentFileContentIs( +`function f(x: number): number { + return newFunction(x); +} +function newFunction(x: number) { + switch (x) { + case 0: + return 0; + } +} +`); From 8aaace0ac83c5755683795c9c0ae9720da31414a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 7 Sep 2017 16:23:31 -0700 Subject: [PATCH 39/60] Update version --- package.json | 2 +- src/compiler/core.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f9424a10bb237..48dfd5d811ef2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "2.5.2", + "version": "2.5.3", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 8e2ef6e25a25c..fd4b63f53a4d8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -6,7 +6,7 @@ namespace ts { // If changing the text in this section, be sure to test `configureNightly` too. export const versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - export const version = `${versionMajorMinor}.2`; + export const version = `${versionMajorMinor}.3`; } /* @internal */ From 655145ca58b4b4bc3c9b101b4959c5637a61c8e3 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 7 Sep 2017 16:48:33 -0700 Subject: [PATCH 40/60] Update LKG --- lib/tsc.js | 213 +++++++++++++++++----------- lib/tsserver.js | 244 ++++++++++++++++++++------------ lib/tsserverlibrary.d.ts | 5 +- lib/tsserverlibrary.js | 244 ++++++++++++++++++++------------ lib/typescript.d.ts | 5 +- lib/typescript.js | 269 +++++++++++++++++++++++------------- lib/typescriptServices.d.ts | 5 +- lib/typescriptServices.js | 269 +++++++++++++++++++++++------------- lib/typingsInstaller.js | 5 +- 9 files changed, 802 insertions(+), 457 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index f5d3a50661225..33eeb6de3af24 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -152,7 +152,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".2"; + ts.version = ts.versionMajorMinor + ".3"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; @@ -8934,8 +8934,7 @@ var ts; } ts.isToken = isToken; function isNodeArray(array) { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; function isLiteralKind(kind) { @@ -19943,7 +19942,7 @@ var ts; var writer = ts.createTextWriter(""); var printer = ts.createPrinter(options); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(3, typeNode, sourceFile, writer); + printer.writeNode(4, typeNode, sourceFile, writer); var result = writer.getText(); var maxLength = compilerOptions.noErrorTruncation || flags & 8 ? undefined : 100; if (maxLength && result.length >= maxLength) { @@ -25277,8 +25276,7 @@ var ts; return true; } if (source.flags & 32768 && target.flags & 32768) { - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - var related = relation.get(id); + var related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === 1; } @@ -25606,7 +25604,7 @@ var ts; if (overflow) { return 0; } - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; + var id = getRelationKey(source, target, relation); var related = relation.get(id); if (related !== undefined) { if (reportErrors && related === 2) { @@ -26079,6 +26077,42 @@ var ts; return false; } } + function isUnconstrainedTypeParameter(type) { + return type.flags & 16384 && !getConstraintFromTypeParameter(type); + } + function isTypeReferenceWithGenericArguments(type) { + return getObjectFlags(type) & 4 && ts.some(type.typeArguments, isUnconstrainedTypeParameter); + } + function getTypeReferenceId(type, typeParameters) { + var result = "" + type.target.id; + for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) { + var t = _a[_i]; + if (isUnconstrainedTypeParameter(t)) { + var index = ts.indexOf(typeParameters, t); + if (index < 0) { + index = typeParameters.length; + typeParameters.push(t); + } + result += "=" + index; + } + else { + result += "-" + t.id; + } + } + return result; + } + function getRelationKey(source, target, relation) { + if (relation === identityRelation && source.id > target.id) { + var temp = source; + source = target; + target = temp; + } + if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { + var typeParameters = []; + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + } + return source.id + "," + target.id; + } function forEachProperty(prop, callback) { if (ts.getCheckFlags(prop) & 6) { for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) { @@ -32174,7 +32208,7 @@ var ts; } function checkParenthesizedExpression(node, checkMode) { if (ts.isInJavaScriptFile(node) && node.jsDoc) { - var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281; }); }); + var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 && !!tag.typeExpression && !!tag.typeExpression.type; }); }); if (typecasts && typecasts.length) { var cast_1 = typecasts[0]; return checkAssertionWorker(cast_1, cast_1.typeExpression.type, node.expression, checkMode); @@ -37877,7 +37911,7 @@ var ts; || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } ts.updateParameter = updateParameter; @@ -38493,13 +38527,26 @@ var ts; return node; } ts.createArrowFunction = createArrowFunction; - function updateArrowFunction(node, modifiers, typeParameters, parameters, type, body) { + function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) { + var equalsGreaterThanToken; + var body; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody); + } + else { + equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) { + return n.kind === 36; + }); + body = bodyOrUndefined; + } return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } ts.updateArrowFunction = updateArrowFunction; @@ -38604,11 +38651,23 @@ var ts; return node; } ts.createConditional = createConditional; - function updateConditional(node, condition, whenTrue, whenFalse) { + function updateConditional(node, condition) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + if (args.length === 2) { + var whenTrue_1 = args[0], whenFalse_1 = args[1]; + return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1); + } + ts.Debug.assert(args.length === 4); + var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3]; return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } ts.updateConditional = updateConditional; @@ -41266,7 +41325,7 @@ var ts; case 186: return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 187: - return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); + return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context)); case 188: return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression)); case 189: @@ -41282,7 +41341,7 @@ var ts; case 194: return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken)); case 195: - return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.whenFalse, visitor, ts.isExpression)); + return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression)); case 196: return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan)); case 197: @@ -43448,7 +43507,7 @@ var ts; return updated; } function visitArrowFunction(node) { - var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, ts.visitFunctionBody(node.body, visitor, context)); + var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context)); return updated; } function visitParameter(node) { @@ -44097,7 +44156,7 @@ var ts; : ts.visitFunctionBody(node.body, visitor, context)); } function visitArrowFunction(node) { - return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, ts.getFunctionFlags(node) & 2 + return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } @@ -44592,7 +44651,7 @@ var ts; function visitArrowFunction(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); - var updated = ts.updateArrowFunction(node, node.modifiers, undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, transformFunctionBody(node)); + var updated = ts.updateArrowFunction(node, node.modifiers, undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } @@ -53255,8 +53314,13 @@ var ts; comments.reset(); setWriter(undefined); } + function emitIfPresent(node) { + if (node) { + emit(node); + } + } function emit(node) { - pipelineEmitWithNotification(3, node); + pipelineEmitWithNotification(4, node); } function emitIdentifierName(node) { pipelineEmitWithNotification(2, node); @@ -53294,7 +53358,8 @@ var ts; case 0: return pipelineEmitSourceFile(node); case 2: return pipelineEmitIdentifierName(node); case 1: return pipelineEmitExpression(node); - case 3: return pipelineEmitUnspecified(node); + case 3: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); + case 4: return pipelineEmitUnspecified(node); } } function pipelineEmitSourceFile(node) { @@ -53305,6 +53370,11 @@ var ts; ts.Debug.assertNode(node, ts.isIdentifier); emitIdentifier(node); } + function emitMappedTypeParameter(node) { + emit(node.name); + write(" in "); + emit(node.constraint); + } function pipelineEmitUnspecified(node) { var kind = node.kind; if (ts.isKeyword(kind)) { @@ -53648,9 +53718,9 @@ var ts; function emitParameter(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -53662,7 +53732,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -53670,7 +53740,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -53679,7 +53749,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -53688,9 +53758,9 @@ var ts; function emitMethodDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } function emitConstructor(node) { @@ -53760,9 +53830,8 @@ var ts; } function emitTypeLiteral(node) { write("{"); - if (node.members.length > 0) { - emitList(node, node.members, ts.getEmitFlags(node) & 1 ? 448 : 65); - } + var flags = ts.getEmitFlags(node) & 1 ? 448 : 65; + emitList(node, node.members, flags | 262144); write("}"); } function emitArrayType(node) { @@ -53809,13 +53878,14 @@ var ts; writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); + } write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); + pipelineEmitWithNotification(3, node.typeParameter); write("]"); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -53855,36 +53925,25 @@ var ts; } function emitBindingElement(node) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } function emitArrayLiteralExpression(node) { var elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - var preferNewLine = node.multiLine ? 32768 : 0; - emitExpressionList(node, elements, 4466 | preferNewLine); - } + var preferNewLine = node.multiLine ? 32768 : 0; + emitExpressionList(node, elements, 4466 | preferNewLine); } function emitObjectLiteralExpression(node) { - var properties = node.properties; - if (properties.length === 0) { - write("{}"); + var indentedFlag = ts.getEmitFlags(node) & 65536; + if (indentedFlag) { + increaseIndent(); } - else { - var indentedFlag = ts.getEmitFlags(node) & 65536; - if (indentedFlag) { - increaseIndent(); - } - var preferNewLine = node.multiLine ? 32768 : 0; - var allowTrailingComma = currentSourceFile.languageVersion >= 1 ? 32 : 0; - emitList(node, properties, 978 | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + var preferNewLine = node.multiLine ? 32768 : 0; + var allowTrailingComma = currentSourceFile.languageVersion >= 1 ? 32 : 0; + emitList(node, node.properties, 263122 | allowTrailingComma | preferNewLine); + if (indentedFlag) { + decreaseIndent(); } } function emitPropertyAccessExpression(node) { @@ -53966,7 +54025,8 @@ var ts; emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node) { write("delete "); @@ -54021,12 +54081,12 @@ var ts; var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse); emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); @@ -54036,7 +54096,8 @@ var ts; emitList(node, node.templateSpans, 131072); } function emitYieldExpression(node) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } function emitSpreadExpression(node) { @@ -54269,7 +54330,9 @@ var ts; function emitFunctionDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + emitIfPresent(node.asteriskToken); + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -54287,7 +54350,7 @@ var ts; if (ts.getEmitFlags(node) & 524288) { emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3, body, emitBlockCallback); + onEmitNode(4, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -54297,7 +54360,7 @@ var ts; pushNameGenerationScope(); emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3, body, emitBlockCallback); + onEmitNode(4, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -54599,9 +54662,7 @@ var ts; function emitJsxExpression(node) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -54632,13 +54693,12 @@ var ts; if (statements.length > 0) { emitTrailingCommentsOfPosition(statements.pos); } + var format = 81985; if (emitAsSingleStatement) { write(" "); - emit(statements[0]); - } - else { - emitList(parentNode, statements, 81985); + format &= ~(1 | 64); } + emitList(parentNode, statements, format); } function emitHeritageClause(node) { write(" "); @@ -54831,7 +54891,7 @@ var ts; } function emitParametersForArrow(parentNode, parameters) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitList(parentNode, parameters, 1360 & ~1024); } else { emitParameters(parentNode, parameters); @@ -54867,7 +54927,7 @@ var ts; if (format & 1) { writeLine(); } - else if (format & 128) { + else if (format & 128 && !(format & 262144)) { write(" "); } } @@ -54963,11 +55023,6 @@ var ts; write(text); } } - function writeIfPresent(node, text) { - if (node) { - write(text); - } - } function writeToken(token, pos, contextNode) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) @@ -54977,7 +55032,7 @@ var ts; if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(ts.tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } diff --git a/lib/tsserver.js b/lib/tsserver.js index ddbefc72ce9db..21b0b83c062df 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1099,7 +1099,8 @@ var ts; EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile"; EmitHint[EmitHint["Expression"] = 1] = "Expression"; EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName"; - EmitHint[EmitHint["Unspecified"] = 3] = "Unspecified"; + EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter"; + EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified"; })(EmitHint = ts.EmitHint || (ts.EmitHint = {})); })(ts || (ts = {})); var ts; @@ -1164,7 +1165,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".2"; + ts.version = ts.versionMajorMinor + ".3"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; @@ -9197,8 +9198,7 @@ var ts; } ts.isToken = isToken; function isNodeArray(array) { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; function isLiteralKind(kind) { @@ -21153,7 +21153,7 @@ var ts; var writer = ts.createTextWriter(""); var printer = ts.createPrinter(options); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(3, typeNode, sourceFile, writer); + printer.writeNode(4, typeNode, sourceFile, writer); var result = writer.getText(); var maxLength = compilerOptions.noErrorTruncation || flags & 8 ? undefined : 100; if (maxLength && result.length >= maxLength) { @@ -26487,8 +26487,7 @@ var ts; return true; } if (source.flags & 32768 && target.flags & 32768) { - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - var related = relation.get(id); + var related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === 1; } @@ -26816,7 +26815,7 @@ var ts; if (overflow) { return 0; } - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; + var id = getRelationKey(source, target, relation); var related = relation.get(id); if (related !== undefined) { if (reportErrors && related === 2) { @@ -27289,6 +27288,42 @@ var ts; return false; } } + function isUnconstrainedTypeParameter(type) { + return type.flags & 16384 && !getConstraintFromTypeParameter(type); + } + function isTypeReferenceWithGenericArguments(type) { + return getObjectFlags(type) & 4 && ts.some(type.typeArguments, isUnconstrainedTypeParameter); + } + function getTypeReferenceId(type, typeParameters) { + var result = "" + type.target.id; + for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) { + var t = _a[_i]; + if (isUnconstrainedTypeParameter(t)) { + var index = ts.indexOf(typeParameters, t); + if (index < 0) { + index = typeParameters.length; + typeParameters.push(t); + } + result += "=" + index; + } + else { + result += "-" + t.id; + } + } + return result; + } + function getRelationKey(source, target, relation) { + if (relation === identityRelation && source.id > target.id) { + var temp = source; + source = target; + target = temp; + } + if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { + var typeParameters = []; + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + } + return source.id + "," + target.id; + } function forEachProperty(prop, callback) { if (ts.getCheckFlags(prop) & 6) { for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) { @@ -33384,7 +33419,7 @@ var ts; } function checkParenthesizedExpression(node, checkMode) { if (ts.isInJavaScriptFile(node) && node.jsDoc) { - var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281; }); }); + var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 && !!tag.typeExpression && !!tag.typeExpression.type; }); }); if (typecasts && typecasts.length) { var cast_1 = typecasts[0]; return checkAssertionWorker(cast_1, cast_1.typeExpression.type, node.expression, checkMode); @@ -39101,7 +39136,7 @@ var ts; || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } ts.updateParameter = updateParameter; @@ -39717,13 +39752,26 @@ var ts; return node; } ts.createArrowFunction = createArrowFunction; - function updateArrowFunction(node, modifiers, typeParameters, parameters, type, body) { + function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) { + var equalsGreaterThanToken; + var body; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody); + } + else { + equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) { + return n.kind === 36; + }); + body = bodyOrUndefined; + } return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } ts.updateArrowFunction = updateArrowFunction; @@ -39828,11 +39876,23 @@ var ts; return node; } ts.createConditional = createConditional; - function updateConditional(node, condition, whenTrue, whenFalse) { + function updateConditional(node, condition) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + if (args.length === 2) { + var whenTrue_1 = args[0], whenFalse_1 = args[1]; + return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1); + } + ts.Debug.assert(args.length === 4); + var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3]; return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } ts.updateConditional = updateConditional; @@ -42497,7 +42557,7 @@ var ts; case 186: return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 187: - return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); + return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context)); case 188: return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression)); case 189: @@ -42513,7 +42573,7 @@ var ts; case 194: return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken)); case 195: - return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.whenFalse, visitor, ts.isExpression)); + return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression)); case 196: return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan)); case 197: @@ -44706,7 +44766,7 @@ var ts; return updated; } function visitArrowFunction(node) { - var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, ts.visitFunctionBody(node.body, visitor, context)); + var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context)); return updated; } function visitParameter(node) { @@ -45359,7 +45419,7 @@ var ts; : ts.visitFunctionBody(node.body, visitor, context)); } function visitArrowFunction(node) { - return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, ts.getFunctionFlags(node) & 2 + return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } @@ -45858,7 +45918,7 @@ var ts; function visitArrowFunction(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); - var updated = ts.updateArrowFunction(node, node.modifiers, undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, transformFunctionBody(node)); + var updated = ts.updateArrowFunction(node, node.modifiers, undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } @@ -54647,8 +54707,13 @@ var ts; comments.reset(); setWriter(undefined); } + function emitIfPresent(node) { + if (node) { + emit(node); + } + } function emit(node) { - pipelineEmitWithNotification(3, node); + pipelineEmitWithNotification(4, node); } function emitIdentifierName(node) { pipelineEmitWithNotification(2, node); @@ -54686,7 +54751,8 @@ var ts; case 0: return pipelineEmitSourceFile(node); case 2: return pipelineEmitIdentifierName(node); case 1: return pipelineEmitExpression(node); - case 3: return pipelineEmitUnspecified(node); + case 3: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); + case 4: return pipelineEmitUnspecified(node); } } function pipelineEmitSourceFile(node) { @@ -54697,6 +54763,11 @@ var ts; ts.Debug.assertNode(node, ts.isIdentifier); emitIdentifier(node); } + function emitMappedTypeParameter(node) { + emit(node.name); + write(" in "); + emit(node.constraint); + } function pipelineEmitUnspecified(node) { var kind = node.kind; if (ts.isKeyword(kind)) { @@ -55040,9 +55111,9 @@ var ts; function emitParameter(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -55054,7 +55125,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -55062,7 +55133,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -55071,7 +55142,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -55080,9 +55151,9 @@ var ts; function emitMethodDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } function emitConstructor(node) { @@ -55152,9 +55223,8 @@ var ts; } function emitTypeLiteral(node) { write("{"); - if (node.members.length > 0) { - emitList(node, node.members, ts.getEmitFlags(node) & 1 ? 448 : 65); - } + var flags = ts.getEmitFlags(node) & 1 ? 448 : 65; + emitList(node, node.members, flags | 262144); write("}"); } function emitArrayType(node) { @@ -55201,13 +55271,14 @@ var ts; writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); + } write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); + pipelineEmitWithNotification(3, node.typeParameter); write("]"); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -55247,36 +55318,25 @@ var ts; } function emitBindingElement(node) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } function emitArrayLiteralExpression(node) { var elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - var preferNewLine = node.multiLine ? 32768 : 0; - emitExpressionList(node, elements, 4466 | preferNewLine); - } + var preferNewLine = node.multiLine ? 32768 : 0; + emitExpressionList(node, elements, 4466 | preferNewLine); } function emitObjectLiteralExpression(node) { - var properties = node.properties; - if (properties.length === 0) { - write("{}"); + var indentedFlag = ts.getEmitFlags(node) & 65536; + if (indentedFlag) { + increaseIndent(); } - else { - var indentedFlag = ts.getEmitFlags(node) & 65536; - if (indentedFlag) { - increaseIndent(); - } - var preferNewLine = node.multiLine ? 32768 : 0; - var allowTrailingComma = currentSourceFile.languageVersion >= 1 ? 32 : 0; - emitList(node, properties, 978 | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + var preferNewLine = node.multiLine ? 32768 : 0; + var allowTrailingComma = currentSourceFile.languageVersion >= 1 ? 32 : 0; + emitList(node, node.properties, 263122 | allowTrailingComma | preferNewLine); + if (indentedFlag) { + decreaseIndent(); } } function emitPropertyAccessExpression(node) { @@ -55358,7 +55418,8 @@ var ts; emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node) { write("delete "); @@ -55413,12 +55474,12 @@ var ts; var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse); emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); @@ -55428,7 +55489,8 @@ var ts; emitList(node, node.templateSpans, 131072); } function emitYieldExpression(node) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } function emitSpreadExpression(node) { @@ -55661,7 +55723,9 @@ var ts; function emitFunctionDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + emitIfPresent(node.asteriskToken); + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -55679,7 +55743,7 @@ var ts; if (ts.getEmitFlags(node) & 524288) { emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3, body, emitBlockCallback); + onEmitNode(4, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -55689,7 +55753,7 @@ var ts; pushNameGenerationScope(); emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3, body, emitBlockCallback); + onEmitNode(4, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -55991,9 +56055,7 @@ var ts; function emitJsxExpression(node) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -56024,13 +56086,12 @@ var ts; if (statements.length > 0) { emitTrailingCommentsOfPosition(statements.pos); } + var format = 81985; if (emitAsSingleStatement) { write(" "); - emit(statements[0]); - } - else { - emitList(parentNode, statements, 81985); + format &= ~(1 | 64); } + emitList(parentNode, statements, format); } function emitHeritageClause(node) { write(" "); @@ -56223,7 +56284,7 @@ var ts; } function emitParametersForArrow(parentNode, parameters) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitList(parentNode, parameters, 1360 & ~1024); } else { emitParameters(parentNode, parameters); @@ -56259,7 +56320,7 @@ var ts; if (format & 1) { writeLine(); } - else if (format & 128) { + else if (format & 128 && !(format & 262144)) { write(" "); } } @@ -56355,11 +56416,6 @@ var ts; write(text); } } - function writeIfPresent(node, text) { - if (node) { - write(text); - } - } function writeToken(token, pos, contextNode) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) @@ -56369,7 +56425,7 @@ var ts; if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(ts.tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } @@ -56765,6 +56821,8 @@ var ts; ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine"; ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine"; ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments"; + ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty"; + ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement"; ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers"; ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses"; ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 448] = "SingleLineTypeLiteralMembers"; @@ -56774,7 +56832,7 @@ var ts; ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents"; ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements"; ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements"; - ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 978] = "ObjectLiteralExpressionProperties"; + ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties"; ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements"; ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements"; ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments"; @@ -71471,6 +71529,7 @@ var ts; return inheritedIndentation; } function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) { + ts.Debug.assert(ts.isNodeArray(nodes)); var listStartToken = getOpenTokenForList(parent, nodes); var listEndToken = getCloseTokenForOpenToken(listStartToken); var listDynamicIndentation = parentDynamicIndentation; @@ -72267,15 +72326,21 @@ var ts; var textChanges; (function (textChanges) { function getPos(n) { - return n["__pos"]; + var result = n["__pos"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setPos(n, pos) { + ts.Debug.assert(typeof pos === "number"); n["__pos"] = pos; } function getEnd(n) { - return n["__end"]; + var result = n["__end"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setEnd(n, end) { + ts.Debug.assert(typeof end === "number"); n["__end"] = end; } var Position; @@ -72664,10 +72729,9 @@ var ts; var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion }; var writer = new Writer(ts.getNewLineCharacter(options)); var printer = ts.createPrinter(options, writer); - printer.writeNode(3, node, sourceFile, writer); + printer.writeNode(4, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } - textChanges.getNonformattedText = getNonformattedText; function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, rulesProvider) { var lineMap = ts.computeLineStarts(nonFormattedText.text); var file = { @@ -72678,7 +72742,6 @@ var ts; var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider); return applyChanges(nonFormattedText.text, changes); } - textChanges.applyFormatting = applyFormatting; function applyChanges(text, changes) { for (var i = changes.length - 1; i >= 0; i--) { var change = changes[i]; @@ -72692,13 +72755,10 @@ var ts; } function assignPositionsToNode(node) { var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); - var newNode = ts.nodeIsSynthesized(visited) - ? visited - : (Proxy.prototype = visited, new Proxy()); + var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited); newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; - function Proxy() { } } function assignPositionsToNodeArray(nodes, visitor, test, start, count) { var visited = ts.visitNodes(nodes, visitor, test, start, count); @@ -74968,10 +75028,10 @@ var ts; if (range.facts & RangeFacts.IsAsyncFunction) { modifiers.push(ts.createToken(120)); } - newFunction = ts.createMethod(undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, [], parameters, returnType, body); + newFunction = ts.createMethod(undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, undefined, parameters, returnType, body); } else { - newFunction = ts.createFunctionDeclaration(undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, [], parameters, returnType, body); + newFunction = ts.createFunctionDeclaration(undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, parameters, returnType, body); } var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 4c27618e03201..457015306006b 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2283,7 +2283,8 @@ declare namespace ts { SourceFile = 0, Expression = 1, IdentifierName = 2, - Unspecified = 3, + MappedTypeParameter = 3, + Unspecified = 4, } interface TransformationContext { getCompilerOptions(): CompilerOptions; @@ -2835,6 +2836,7 @@ declare namespace ts { function updateFunctionExpression(node: FunctionExpression, modifiers: ReadonlyArray | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: Block): FunctionExpression; function createArrowFunction(modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, equalsGreaterThanToken: Token, body: ConciseBody): ArrowFunction; function createDelete(expression: Expression): DeleteExpression; function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression; function createTypeOf(expression: Expression): TypeOfExpression; @@ -2852,6 +2854,7 @@ declare namespace ts { function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function createYield(expression?: Expression): YieldExpression; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 60d8bc0001239..bd74f810fb579 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -1099,7 +1099,8 @@ var ts; EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile"; EmitHint[EmitHint["Expression"] = 1] = "Expression"; EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName"; - EmitHint[EmitHint["Unspecified"] = 3] = "Unspecified"; + EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter"; + EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified"; })(EmitHint = ts.EmitHint || (ts.EmitHint = {})); })(ts || (ts = {})); var ts; @@ -1164,7 +1165,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".2"; + ts.version = ts.versionMajorMinor + ".3"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; @@ -8394,8 +8395,7 @@ var ts; } ts.isToken = isToken; function isNodeArray(array) { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; function isLiteralKind(kind) { @@ -22859,7 +22859,7 @@ var ts; var writer = ts.createTextWriter(""); var printer = ts.createPrinter(options); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(3, typeNode, sourceFile, writer); + printer.writeNode(4, typeNode, sourceFile, writer); var result = writer.getText(); var maxLength = compilerOptions.noErrorTruncation || flags & 8 ? undefined : 100; if (maxLength && result.length >= maxLength) { @@ -28193,8 +28193,7 @@ var ts; return true; } if (source.flags & 32768 && target.flags & 32768) { - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - var related = relation.get(id); + var related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === 1; } @@ -28522,7 +28521,7 @@ var ts; if (overflow) { return 0; } - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; + var id = getRelationKey(source, target, relation); var related = relation.get(id); if (related !== undefined) { if (reportErrors && related === 2) { @@ -28995,6 +28994,42 @@ var ts; return false; } } + function isUnconstrainedTypeParameter(type) { + return type.flags & 16384 && !getConstraintFromTypeParameter(type); + } + function isTypeReferenceWithGenericArguments(type) { + return getObjectFlags(type) & 4 && ts.some(type.typeArguments, isUnconstrainedTypeParameter); + } + function getTypeReferenceId(type, typeParameters) { + var result = "" + type.target.id; + for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) { + var t = _a[_i]; + if (isUnconstrainedTypeParameter(t)) { + var index = ts.indexOf(typeParameters, t); + if (index < 0) { + index = typeParameters.length; + typeParameters.push(t); + } + result += "=" + index; + } + else { + result += "-" + t.id; + } + } + return result; + } + function getRelationKey(source, target, relation) { + if (relation === identityRelation && source.id > target.id) { + var temp = source; + source = target; + target = temp; + } + if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { + var typeParameters = []; + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + } + return source.id + "," + target.id; + } function forEachProperty(prop, callback) { if (ts.getCheckFlags(prop) & 6) { for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) { @@ -35090,7 +35125,7 @@ var ts; } function checkParenthesizedExpression(node, checkMode) { if (ts.isInJavaScriptFile(node) && node.jsDoc) { - var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281; }); }); + var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 && !!tag.typeExpression && !!tag.typeExpression.type; }); }); if (typecasts && typecasts.length) { var cast_1 = typecasts[0]; return checkAssertionWorker(cast_1, cast_1.typeExpression.type, node.expression, checkMode); @@ -40807,7 +40842,7 @@ var ts; || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } ts.updateParameter = updateParameter; @@ -41423,13 +41458,26 @@ var ts; return node; } ts.createArrowFunction = createArrowFunction; - function updateArrowFunction(node, modifiers, typeParameters, parameters, type, body) { + function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) { + var equalsGreaterThanToken; + var body; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody); + } + else { + equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) { + return n.kind === 36; + }); + body = bodyOrUndefined; + } return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } ts.updateArrowFunction = updateArrowFunction; @@ -41534,11 +41582,23 @@ var ts; return node; } ts.createConditional = createConditional; - function updateConditional(node, condition, whenTrue, whenFalse) { + function updateConditional(node, condition) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + if (args.length === 2) { + var whenTrue_1 = args[0], whenFalse_1 = args[1]; + return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1); + } + ts.Debug.assert(args.length === 4); + var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3]; return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } ts.updateConditional = updateConditional; @@ -44203,7 +44263,7 @@ var ts; case 186: return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 187: - return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); + return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context)); case 188: return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression)); case 189: @@ -44219,7 +44279,7 @@ var ts; case 194: return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken)); case 195: - return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.whenFalse, visitor, ts.isExpression)); + return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression)); case 196: return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan)); case 197: @@ -46412,7 +46472,7 @@ var ts; return updated; } function visitArrowFunction(node) { - var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, ts.visitFunctionBody(node.body, visitor, context)); + var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context)); return updated; } function visitParameter(node) { @@ -47065,7 +47125,7 @@ var ts; : ts.visitFunctionBody(node.body, visitor, context)); } function visitArrowFunction(node) { - return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, ts.getFunctionFlags(node) & 2 + return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } @@ -47564,7 +47624,7 @@ var ts; function visitArrowFunction(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); - var updated = ts.updateArrowFunction(node, node.modifiers, undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, transformFunctionBody(node)); + var updated = ts.updateArrowFunction(node, node.modifiers, undefined, ts.visitParameterList(node.parameters, visitor, context), undefined, node.equalsGreaterThanToken, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } @@ -56353,8 +56413,13 @@ var ts; comments.reset(); setWriter(undefined); } + function emitIfPresent(node) { + if (node) { + emit(node); + } + } function emit(node) { - pipelineEmitWithNotification(3, node); + pipelineEmitWithNotification(4, node); } function emitIdentifierName(node) { pipelineEmitWithNotification(2, node); @@ -56392,7 +56457,8 @@ var ts; case 0: return pipelineEmitSourceFile(node); case 2: return pipelineEmitIdentifierName(node); case 1: return pipelineEmitExpression(node); - case 3: return pipelineEmitUnspecified(node); + case 3: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); + case 4: return pipelineEmitUnspecified(node); } } function pipelineEmitSourceFile(node) { @@ -56403,6 +56469,11 @@ var ts; ts.Debug.assertNode(node, ts.isIdentifier); emitIdentifier(node); } + function emitMappedTypeParameter(node) { + emit(node.name); + write(" in "); + emit(node.constraint); + } function pipelineEmitUnspecified(node) { var kind = node.kind; if (ts.isKeyword(kind)) { @@ -56746,9 +56817,9 @@ var ts; function emitParameter(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -56760,7 +56831,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -56768,7 +56839,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -56777,7 +56848,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -56786,9 +56857,9 @@ var ts; function emitMethodDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } function emitConstructor(node) { @@ -56858,9 +56929,8 @@ var ts; } function emitTypeLiteral(node) { write("{"); - if (node.members.length > 0) { - emitList(node, node.members, ts.getEmitFlags(node) & 1 ? 448 : 65); - } + var flags = ts.getEmitFlags(node) & 1 ? 448 : 65; + emitList(node, node.members, flags | 262144); write("}"); } function emitArrayType(node) { @@ -56907,13 +56977,14 @@ var ts; writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); + } write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); + pipelineEmitWithNotification(3, node.typeParameter); write("]"); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -56953,36 +57024,25 @@ var ts; } function emitBindingElement(node) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } function emitArrayLiteralExpression(node) { var elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - var preferNewLine = node.multiLine ? 32768 : 0; - emitExpressionList(node, elements, 4466 | preferNewLine); - } + var preferNewLine = node.multiLine ? 32768 : 0; + emitExpressionList(node, elements, 4466 | preferNewLine); } function emitObjectLiteralExpression(node) { - var properties = node.properties; - if (properties.length === 0) { - write("{}"); + var indentedFlag = ts.getEmitFlags(node) & 65536; + if (indentedFlag) { + increaseIndent(); } - else { - var indentedFlag = ts.getEmitFlags(node) & 65536; - if (indentedFlag) { - increaseIndent(); - } - var preferNewLine = node.multiLine ? 32768 : 0; - var allowTrailingComma = currentSourceFile.languageVersion >= 1 ? 32 : 0; - emitList(node, properties, 978 | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + var preferNewLine = node.multiLine ? 32768 : 0; + var allowTrailingComma = currentSourceFile.languageVersion >= 1 ? 32 : 0; + emitList(node, node.properties, 263122 | allowTrailingComma | preferNewLine); + if (indentedFlag) { + decreaseIndent(); } } function emitPropertyAccessExpression(node) { @@ -57064,7 +57124,8 @@ var ts; emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node) { write("delete "); @@ -57119,12 +57180,12 @@ var ts; var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse); emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); @@ -57134,7 +57195,8 @@ var ts; emitList(node, node.templateSpans, 131072); } function emitYieldExpression(node) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } function emitSpreadExpression(node) { @@ -57367,7 +57429,9 @@ var ts; function emitFunctionDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + emitIfPresent(node.asteriskToken); + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -57385,7 +57449,7 @@ var ts; if (ts.getEmitFlags(node) & 524288) { emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3, body, emitBlockCallback); + onEmitNode(4, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -57395,7 +57459,7 @@ var ts; pushNameGenerationScope(); emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3, body, emitBlockCallback); + onEmitNode(4, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -57697,9 +57761,7 @@ var ts; function emitJsxExpression(node) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -57730,13 +57792,12 @@ var ts; if (statements.length > 0) { emitTrailingCommentsOfPosition(statements.pos); } + var format = 81985; if (emitAsSingleStatement) { write(" "); - emit(statements[0]); - } - else { - emitList(parentNode, statements, 81985); + format &= ~(1 | 64); } + emitList(parentNode, statements, format); } function emitHeritageClause(node) { write(" "); @@ -57929,7 +57990,7 @@ var ts; } function emitParametersForArrow(parentNode, parameters) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitList(parentNode, parameters, 1360 & ~1024); } else { emitParameters(parentNode, parameters); @@ -57965,7 +58026,7 @@ var ts; if (format & 1) { writeLine(); } - else if (format & 128) { + else if (format & 128 && !(format & 262144)) { write(" "); } } @@ -58061,11 +58122,6 @@ var ts; write(text); } } - function writeIfPresent(node, text) { - if (node) { - write(text); - } - } function writeToken(token, pos, contextNode) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) @@ -58075,7 +58131,7 @@ var ts; if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(ts.tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } @@ -58471,6 +58527,8 @@ var ts; ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine"; ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine"; ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments"; + ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty"; + ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement"; ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers"; ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses"; ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 448] = "SingleLineTypeLiteralMembers"; @@ -58480,7 +58538,7 @@ var ts; ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents"; ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements"; ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements"; - ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 978] = "ObjectLiteralExpressionProperties"; + ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties"; ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements"; ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements"; ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments"; @@ -71471,6 +71529,7 @@ var ts; return inheritedIndentation; } function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) { + ts.Debug.assert(ts.isNodeArray(nodes)); var listStartToken = getOpenTokenForList(parent, nodes); var listEndToken = getCloseTokenForOpenToken(listStartToken); var listDynamicIndentation = parentDynamicIndentation; @@ -72267,15 +72326,21 @@ var ts; var textChanges; (function (textChanges) { function getPos(n) { - return n["__pos"]; + var result = n["__pos"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setPos(n, pos) { + ts.Debug.assert(typeof pos === "number"); n["__pos"] = pos; } function getEnd(n) { - return n["__end"]; + var result = n["__end"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setEnd(n, end) { + ts.Debug.assert(typeof end === "number"); n["__end"] = end; } var Position; @@ -72664,10 +72729,9 @@ var ts; var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion }; var writer = new Writer(ts.getNewLineCharacter(options)); var printer = ts.createPrinter(options, writer); - printer.writeNode(3, node, sourceFile, writer); + printer.writeNode(4, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } - textChanges.getNonformattedText = getNonformattedText; function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, rulesProvider) { var lineMap = ts.computeLineStarts(nonFormattedText.text); var file = { @@ -72678,7 +72742,6 @@ var ts; var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider); return applyChanges(nonFormattedText.text, changes); } - textChanges.applyFormatting = applyFormatting; function applyChanges(text, changes) { for (var i = changes.length - 1; i >= 0; i--) { var change = changes[i]; @@ -72692,13 +72755,10 @@ var ts; } function assignPositionsToNode(node) { var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); - var newNode = ts.nodeIsSynthesized(visited) - ? visited - : (Proxy.prototype = visited, new Proxy()); + var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited); newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; - function Proxy() { } } function assignPositionsToNodeArray(nodes, visitor, test, start, count) { var visited = ts.visitNodes(nodes, visitor, test, start, count); @@ -74968,10 +75028,10 @@ var ts; if (range.facts & RangeFacts.IsAsyncFunction) { modifiers.push(ts.createToken(120)); } - newFunction = ts.createMethod(undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, [], parameters, returnType, body); + newFunction = ts.createMethod(undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, undefined, parameters, returnType, body); } else { - newFunction = ts.createFunctionDeclaration(undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, [], parameters, returnType, body); + newFunction = ts.createFunctionDeclaration(undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39) : undefined, functionName, undefined, parameters, returnType, body); } var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 2ebd420e7c8c1..eaf4400c8ee05 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -2456,7 +2456,8 @@ declare namespace ts { SourceFile = 0, Expression = 1, IdentifierName = 2, - Unspecified = 3, + MappedTypeParameter = 3, + Unspecified = 4, } interface TransformationContext { /** Gets the compiler options supplied to the transformer. */ @@ -3210,6 +3211,7 @@ declare namespace ts { function updateFunctionExpression(node: FunctionExpression, modifiers: ReadonlyArray | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: Block): FunctionExpression; function createArrowFunction(modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, equalsGreaterThanToken: Token, body: ConciseBody): ArrowFunction; function createDelete(expression: Expression): DeleteExpression; function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression; function createTypeOf(expression: Expression): TypeOfExpression; @@ -3227,6 +3229,7 @@ declare namespace ts { function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function createYield(expression?: Expression): YieldExpression; diff --git a/lib/typescript.js b/lib/typescript.js index d8b76261f704e..7e2e649341e77 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -1244,7 +1244,8 @@ var ts; EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile"; EmitHint[EmitHint["Expression"] = 1] = "Expression"; EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName"; - EmitHint[EmitHint["Unspecified"] = 3] = "Unspecified"; + EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter"; + EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified"; })(EmitHint = ts.EmitHint || (ts.EmitHint = {})); })(ts || (ts = {})); /*@internal*/ @@ -1349,7 +1350,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".2"; + ts.version = ts.versionMajorMinor + ".3"; })(ts || (ts = {})); /* @internal */ (function (ts) { @@ -11210,8 +11211,7 @@ var ts; // Node Arrays /* @internal */ function isNodeArray(array) { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; // Literals @@ -20462,7 +20462,9 @@ var ts; // 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. var flags = node.kind === 243 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) + // An export default clause with an EntityNameExpression exports all meanings of that identifier ? 2097152 /* Alias */ + // An export default clause with any other expression exports a value : 4 /* Property */; declareSymbol(container.symbol.exports, container.symbol, node, flags, 4 /* Property */ | 2097152 /* AliasExcludes */ | 32 /* Class */ | 16 /* Function */); } @@ -23404,9 +23406,11 @@ var ts; // at a higher level than type parameters would normally be if (meaning & result.flags & 793064 /* Type */ && lastLocation.kind !== 275 /* JSDocComment */) { useResult = result.flags & 262144 /* TypeParameter */ + // type parameters are visible in parameter list, return type and type parameter list ? lastLocation === location.type || lastLocation.kind === 146 /* Parameter */ || lastLocation.kind === 145 /* TypeParameter */ + // local types not visible outside the function body : false; } if (meaning & 107455 /* Value */ && result.flags & 1 /* FunctionScopedVariable */) { @@ -24692,7 +24696,7 @@ var ts; var writer = ts.createTextWriter(""); var printer = ts.createPrinter(options); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(3 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); + printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); var maxLength = compilerOptions.noErrorTruncation || flags & 8 /* NoTruncation */ ? undefined : 100; if (maxLength && result.length >= maxLength) { @@ -30628,8 +30632,7 @@ var ts; return true; } if (source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */) { - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - var related = relation.get(id); + var related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === 1 /* Succeeded */; } @@ -31007,7 +31010,7 @@ var ts; if (overflow) { return 0 /* False */; } - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; + var id = getRelationKey(source, target, relation); var related = relation.get(id); if (related !== undefined) { if (reportErrors && related === 2 /* Failed */) { @@ -31547,6 +31550,50 @@ var ts; return false; } } + function isUnconstrainedTypeParameter(type) { + return type.flags & 16384 /* TypeParameter */ && !getConstraintFromTypeParameter(type); + } + function isTypeReferenceWithGenericArguments(type) { + return getObjectFlags(type) & 4 /* Reference */ && ts.some(type.typeArguments, isUnconstrainedTypeParameter); + } + /** + * getTypeReferenceId(A) returns "111=0-12=1" + * where A.id=111 and number.id=12 + */ + function getTypeReferenceId(type, typeParameters) { + var result = "" + type.target.id; + for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) { + var t = _a[_i]; + if (isUnconstrainedTypeParameter(t)) { + var index = ts.indexOf(typeParameters, t); + if (index < 0) { + index = typeParameters.length; + typeParameters.push(t); + } + result += "=" + index; + } + else { + result += "-" + t.id; + } + } + return result; + } + /** + * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. + * For other cases, the types ids are used. + */ + function getRelationKey(source, target, relation) { + if (relation === identityRelation && source.id > target.id) { + var temp = source; + source = target; + target = temp; + } + if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { + var typeParameters = []; + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + } + return source.id + "," + target.id; + } // Invoke the callback for each underlying property symbol of the given symbol and return the first // value that isn't undefined. function forEachProperty(prop, callback) { @@ -38125,7 +38172,7 @@ var ts; var returnTypeNode = ts.getEffectiveReturnTypeNode(node); var returnOrPromisedType = returnTypeNode && ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ ? - checkAsyncFunctionReturnType(node) : + checkAsyncFunctionReturnType(node) : // Async function getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function if ((functionFlags & 1 /* Generator */) === 0) { // return is not necessary in the body of generators @@ -39059,7 +39106,7 @@ var ts; } function checkParenthesizedExpression(node, checkMode) { if (ts.isInJavaScriptFile(node) && node.jsDoc) { - var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 /* JSDocTypeTag */; }); }); + var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 /* JSDocTypeTag */ && !!tag.typeExpression && !!tag.typeExpression.type; }); }); if (typecasts && typecasts.length) { // We should have already issued an error if there were multiple type jsdocs var cast_1 = typecasts[0]; @@ -45708,7 +45755,7 @@ var ts; || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } ts.updateParameter = updateParameter; @@ -46331,13 +46378,26 @@ var ts; return node; } ts.createArrowFunction = createArrowFunction; - function updateArrowFunction(node, modifiers, typeParameters, parameters, type, body) { + function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) { + var equalsGreaterThanToken; + var body; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody); + } + else { + equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) { + return n.kind === 36 /* EqualsGreaterThanToken */; + }); + body = bodyOrUndefined; + } return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } ts.updateArrowFunction = updateArrowFunction; @@ -46442,11 +46502,23 @@ var ts; return node; } ts.createConditional = createConditional; - function updateConditional(node, condition, whenTrue, whenFalse) { + function updateConditional(node, condition) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + if (args.length === 2) { + var whenTrue_1 = args[0], whenFalse_1 = args[1]; + return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1); + } + ts.Debug.assert(args.length === 4); + var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3]; return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } ts.updateConditional = updateConditional; @@ -49626,7 +49698,7 @@ var ts; case 186 /* FunctionExpression */: return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 187 /* ArrowFunction */: - return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); + return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context)); case 188 /* DeleteExpression */: return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression)); case 189 /* TypeOfExpression */: @@ -49642,7 +49714,7 @@ var ts; case 194 /* BinaryExpression */: return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken)); case 195 /* ConditionalExpression */: - return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.whenFalse, visitor, ts.isExpression)); + return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression)); case 196 /* TemplateExpression */: return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan)); case 197 /* YieldExpression */: @@ -52221,7 +52293,11 @@ var ts; var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true); var descriptor = languageVersion > 0 /* ES3 */ ? member.kind === 149 /* PropertyDeclaration */ + // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it + // should not invoke `Object.getOwnPropertyDescriptor`. ? ts.createVoidZero() + // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly. + // We have this extra argument here so that we can inject an explicit property descriptor at a later date. : ts.createNull() : undefined; var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member)); @@ -52863,7 +52939,7 @@ var ts; function visitArrowFunction(node) { var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context)); + /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context)); return updated; } /** @@ -53939,7 +54015,7 @@ var ts; function visitArrowFunction(node) { return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */ + /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */ ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } @@ -54528,7 +54604,7 @@ var ts; enclosingFunctionFlags = ts.getFunctionFlags(node); var updated = ts.updateArrowFunction(node, node.modifiers, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, transformFunctionBody(node)); + /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } @@ -54949,7 +55025,9 @@ var ts; } } return firstNonWhitespace !== -1 + // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace. ? addLineOfJsxText(acc, text.substr(firstNonWhitespace)) + // Last line was all whitespace, so ignore it : acc; } function addLineOfJsxText(acc, trimmedLine) { @@ -66901,8 +66979,15 @@ var ts; comments.reset(); setWriter(/*output*/ undefined); } + // TODO: Should this just be `emit`? + // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034 + function emitIfPresent(node) { + if (node) { + emit(node); + } + } function emit(node) { - pipelineEmitWithNotification(3 /* Unspecified */, node); + pipelineEmitWithNotification(4 /* Unspecified */, node); } function emitIdentifierName(node) { pipelineEmitWithNotification(2 /* IdentifierName */, node); @@ -66940,7 +67025,8 @@ var ts; case 0 /* SourceFile */: return pipelineEmitSourceFile(node); case 2 /* IdentifierName */: return pipelineEmitIdentifierName(node); case 1 /* Expression */: return pipelineEmitExpression(node); - case 3 /* Unspecified */: return pipelineEmitUnspecified(node); + case 3 /* MappedTypeParameter */: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); + case 4 /* Unspecified */: return pipelineEmitUnspecified(node); } } function pipelineEmitSourceFile(node) { @@ -66951,6 +67037,11 @@ var ts; ts.Debug.assertNode(node, ts.isIdentifier); emitIdentifier(node); } + function emitMappedTypeParameter(node) { + emit(node.name); + write(" in "); + emit(node.constraint); + } function pipelineEmitUnspecified(node) { var kind = node.kind; // Reserved words @@ -67340,9 +67431,9 @@ var ts; function emitParameter(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -67357,7 +67448,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -67365,7 +67456,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -67374,7 +67465,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -67383,9 +67474,9 @@ var ts; function emitMethodDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } function emitConstructor(node) { @@ -67458,10 +67549,8 @@ var ts; } function emitTypeLiteral(node) { write("{"); - // If the literal is empty, do not add spaces between braces. - if (node.members.length > 0) { - emitList(node, node.members, ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */); - } + var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */; + emitList(node, node.members, flags | 262144 /* NoSpaceIfEmpty */); write("}"); } function emitArrayType(node) { @@ -67508,13 +67597,14 @@ var ts; writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); + } write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); + pipelineEmitWithNotification(3 /* MappedTypeParameter */, node.typeParameter); write("]"); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -67557,7 +67647,7 @@ var ts; } function emitBindingElement(node) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } @@ -67566,30 +67656,19 @@ var ts; // function emitArrayLiteralExpression(node) { var elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; - emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine); - } + var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; + emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine); } function emitObjectLiteralExpression(node) { - var properties = node.properties; - if (properties.length === 0) { - write("{}"); + var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; + if (indentedFlag) { + increaseIndent(); } - else { - var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; - if (indentedFlag) { - increaseIndent(); - } - var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; - var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */; - emitList(node, properties, 978 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; + var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */; + emitList(node, node.properties, 263122 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine); + if (indentedFlag) { + decreaseIndent(); } } function emitPropertyAccessExpression(node) { @@ -67676,7 +67755,8 @@ var ts; emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node) { write("delete "); @@ -67743,12 +67823,12 @@ var ts; var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse); emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); @@ -67758,7 +67838,8 @@ var ts; emitList(node, node.templateSpans, 131072 /* TemplateExpressionSpans */); } function emitYieldExpression(node) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } function emitSpreadExpression(node) { @@ -68001,7 +68082,9 @@ var ts; function emitFunctionDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + emitIfPresent(node.asteriskToken); + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -68019,7 +68102,7 @@ var ts; if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) { emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3 /* Unspecified */, body, emitBlockCallback); + onEmitNode(4 /* Unspecified */, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -68029,7 +68112,7 @@ var ts; pushNameGenerationScope(); emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3 /* Unspecified */, body, emitBlockCallback); + onEmitNode(4 /* Unspecified */, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -68346,9 +68429,7 @@ var ts; function emitJsxExpression(node) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -68396,13 +68477,12 @@ var ts; // Note: we can't use parentNode.end as such position includes statements. emitTrailingCommentsOfPosition(statements.pos); } + var format = 81985 /* CaseOrDefaultClauseStatements */; if (emitAsSingleStatement) { write(" "); - emit(statements[0]); - } - else { - emitList(parentNode, statements, 81985 /* CaseOrDefaultClauseStatements */); + format &= ~(1 /* MultiLine */ | 64 /* Indented */); } + emitList(parentNode, statements, format); } function emitHeritageClause(node) { write(" "); @@ -68623,7 +68703,7 @@ var ts; } function emitParametersForArrow(parentNode, parameters) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitList(parentNode, parameters, 1360 /* Parameters */ & ~1024 /* Parenthesis */); } else { emitParameters(parentNode, parameters); @@ -68660,7 +68740,7 @@ var ts; if (format & 1 /* MultiLine */) { writeLine(); } - else if (format & 128 /* SpaceBetweenBraces */) { + else if (format & 128 /* SpaceBetweenBraces */ && !(format & 262144 /* NoSpaceIfEmpty */)) { write(" "); } } @@ -68779,11 +68859,6 @@ var ts; write(text); } } - function writeIfPresent(node, text) { - if (node) { - write(text); - } - } function writeToken(token, pos, contextNode) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) @@ -68793,7 +68868,7 @@ var ts; if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(ts.tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } @@ -69259,6 +69334,8 @@ var ts; ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine"; ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine"; ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments"; + ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty"; + ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement"; // Precomputed Formats ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers"; ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses"; @@ -69269,7 +69346,7 @@ var ts; ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents"; ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements"; ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements"; - ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 978] = "ObjectLiteralExpressionProperties"; + ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties"; ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements"; ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements"; ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments"; @@ -76093,8 +76170,10 @@ var ts; } if (request) { var entries_2 = request.kind === "JsDocTagName" + // If the current position is a jsDoc tag name, only tag names should be provided for completion ? ts.JsDoc.getJSDocTagNameCompletions() : request.kind === "JsDocTag" + // If the current position is a jsDoc tag, only tags should be provided for completion ? ts.JsDoc.getJSDocTagCompletions() : ts.JsDoc.getJSDocParameterNameCompletions(request.tag); return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries_2 }; @@ -85997,6 +86076,7 @@ var ts; return inheritedIndentation; } function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) { + ts.Debug.assert(ts.isNodeArray(nodes)); var listStartToken = getOpenTokenForList(parent, nodes); var listEndToken = getCloseTokenForOpenToken(listStartToken); var listDynamicIndentation = parentDynamicIndentation; @@ -86910,15 +86990,21 @@ var ts; * It can be changed to side-table later if we decide that current design is too invasive. */ function getPos(n) { - return n["__pos"]; + var result = n["__pos"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setPos(n, pos) { + ts.Debug.assert(typeof pos === "number"); n["__pos"] = pos; } function getEnd(n) { - return n["__end"]; + var result = n["__end"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setEnd(n, end) { + ts.Debug.assert(typeof end === "number"); n["__end"] = end; } var Position; @@ -87382,10 +87468,9 @@ var ts; var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion }; var writer = new Writer(ts.getNewLineCharacter(options)); var printer = ts.createPrinter(options, writer); - printer.writeNode(3 /* Unspecified */, node, sourceFile, writer); + printer.writeNode(4 /* Unspecified */, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } - textChanges.getNonformattedText = getNonformattedText; function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, rulesProvider) { var lineMap = ts.computeLineStarts(nonFormattedText.text); var file = { @@ -87396,7 +87481,6 @@ var ts; var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider); return applyChanges(nonFormattedText.text, changes); } - textChanges.applyFormatting = applyFormatting; function applyChanges(text, changes) { for (var i = changes.length - 1; i >= 0; i--) { var change = changes[i]; @@ -87411,13 +87495,10 @@ var ts; function assignPositionsToNode(node) { var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes - var newNode = ts.nodeIsSynthesized(visited) - ? visited - : (Proxy.prototype = visited, new Proxy()); + var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited); newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; - function Proxy() { } } function assignPositionsToNodeArray(nodes, visitor, test, start, count) { var visited = ts.visitNodes(nodes, visitor, test, start, count); @@ -90026,12 +90107,12 @@ var ts; newFunction = ts.createMethod( /*decorators*/ undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, /*questionToken*/ undefined, - /*typeParameters*/ [], parameters, returnType, body); + /*typeParameters*/ undefined, parameters, returnType, body); } else { newFunction = ts.createFunctionDeclaration( /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, - /*typeParameters*/ [], parameters, returnType, body); + /*typeParameters*/ undefined, parameters, returnType, body); } var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); // insert function at the end of the scope diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 7051b32c4ac0b..825ed9b5c0dee 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2456,7 +2456,8 @@ declare namespace ts { SourceFile = 0, Expression = 1, IdentifierName = 2, - Unspecified = 3, + MappedTypeParameter = 3, + Unspecified = 4, } interface TransformationContext { /** Gets the compiler options supplied to the transformer. */ @@ -3210,6 +3211,7 @@ declare namespace ts { function updateFunctionExpression(node: FunctionExpression, modifiers: ReadonlyArray | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: Block): FunctionExpression; function createArrowFunction(modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, equalsGreaterThanToken: Token, body: ConciseBody): ArrowFunction; function createDelete(expression: Expression): DeleteExpression; function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression; function createTypeOf(expression: Expression): TypeOfExpression; @@ -3227,6 +3229,7 @@ declare namespace ts { function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function createYield(expression?: Expression): YieldExpression; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index d8b76261f704e..7e2e649341e77 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -1244,7 +1244,8 @@ var ts; EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile"; EmitHint[EmitHint["Expression"] = 1] = "Expression"; EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName"; - EmitHint[EmitHint["Unspecified"] = 3] = "Unspecified"; + EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter"; + EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified"; })(EmitHint = ts.EmitHint || (ts.EmitHint = {})); })(ts || (ts = {})); /*@internal*/ @@ -1349,7 +1350,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.5"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".2"; + ts.version = ts.versionMajorMinor + ".3"; })(ts || (ts = {})); /* @internal */ (function (ts) { @@ -11210,8 +11211,7 @@ var ts; // Node Arrays /* @internal */ function isNodeArray(array) { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; // Literals @@ -20462,7 +20462,9 @@ var ts; // 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. var flags = node.kind === 243 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) + // An export default clause with an EntityNameExpression exports all meanings of that identifier ? 2097152 /* Alias */ + // An export default clause with any other expression exports a value : 4 /* Property */; declareSymbol(container.symbol.exports, container.symbol, node, flags, 4 /* Property */ | 2097152 /* AliasExcludes */ | 32 /* Class */ | 16 /* Function */); } @@ -23404,9 +23406,11 @@ var ts; // at a higher level than type parameters would normally be if (meaning & result.flags & 793064 /* Type */ && lastLocation.kind !== 275 /* JSDocComment */) { useResult = result.flags & 262144 /* TypeParameter */ + // type parameters are visible in parameter list, return type and type parameter list ? lastLocation === location.type || lastLocation.kind === 146 /* Parameter */ || lastLocation.kind === 145 /* TypeParameter */ + // local types not visible outside the function body : false; } if (meaning & 107455 /* Value */ && result.flags & 1 /* FunctionScopedVariable */) { @@ -24692,7 +24696,7 @@ var ts; var writer = ts.createTextWriter(""); var printer = ts.createPrinter(options); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(3 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); + printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); var maxLength = compilerOptions.noErrorTruncation || flags & 8 /* NoTruncation */ ? undefined : 100; if (maxLength && result.length >= maxLength) { @@ -30628,8 +30632,7 @@ var ts; return true; } if (source.flags & 32768 /* Object */ && target.flags & 32768 /* Object */) { - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - var related = relation.get(id); + var related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === 1 /* Succeeded */; } @@ -31007,7 +31010,7 @@ var ts; if (overflow) { return 0 /* False */; } - var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; + var id = getRelationKey(source, target, relation); var related = relation.get(id); if (related !== undefined) { if (reportErrors && related === 2 /* Failed */) { @@ -31547,6 +31550,50 @@ var ts; return false; } } + function isUnconstrainedTypeParameter(type) { + return type.flags & 16384 /* TypeParameter */ && !getConstraintFromTypeParameter(type); + } + function isTypeReferenceWithGenericArguments(type) { + return getObjectFlags(type) & 4 /* Reference */ && ts.some(type.typeArguments, isUnconstrainedTypeParameter); + } + /** + * getTypeReferenceId(A) returns "111=0-12=1" + * where A.id=111 and number.id=12 + */ + function getTypeReferenceId(type, typeParameters) { + var result = "" + type.target.id; + for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) { + var t = _a[_i]; + if (isUnconstrainedTypeParameter(t)) { + var index = ts.indexOf(typeParameters, t); + if (index < 0) { + index = typeParameters.length; + typeParameters.push(t); + } + result += "=" + index; + } + else { + result += "-" + t.id; + } + } + return result; + } + /** + * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. + * For other cases, the types ids are used. + */ + function getRelationKey(source, target, relation) { + if (relation === identityRelation && source.id > target.id) { + var temp = source; + source = target; + target = temp; + } + if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { + var typeParameters = []; + return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); + } + return source.id + "," + target.id; + } // Invoke the callback for each underlying property symbol of the given symbol and return the first // value that isn't undefined. function forEachProperty(prop, callback) { @@ -38125,7 +38172,7 @@ var ts; var returnTypeNode = ts.getEffectiveReturnTypeNode(node); var returnOrPromisedType = returnTypeNode && ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ ? - checkAsyncFunctionReturnType(node) : + checkAsyncFunctionReturnType(node) : // Async function getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function if ((functionFlags & 1 /* Generator */) === 0) { // return is not necessary in the body of generators @@ -39059,7 +39106,7 @@ var ts; } function checkParenthesizedExpression(node, checkMode) { if (ts.isInJavaScriptFile(node) && node.jsDoc) { - var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 /* JSDocTypeTag */; }); }); + var typecasts = ts.flatMap(node.jsDoc, function (doc) { return ts.filter(doc.tags, function (tag) { return tag.kind === 281 /* JSDocTypeTag */ && !!tag.typeExpression && !!tag.typeExpression.type; }); }); if (typecasts && typecasts.length) { // We should have already issued an error if there were multiple type jsdocs var cast_1 = typecasts[0]; @@ -45708,7 +45755,7 @@ var ts; || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } ts.updateParameter = updateParameter; @@ -46331,13 +46378,26 @@ var ts; return node; } ts.createArrowFunction = createArrowFunction; - function updateArrowFunction(node, modifiers, typeParameters, parameters, type, body) { + function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) { + var equalsGreaterThanToken; + var body; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody); + } + else { + equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) { + return n.kind === 36 /* EqualsGreaterThanToken */; + }); + body = bodyOrUndefined; + } return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } ts.updateArrowFunction = updateArrowFunction; @@ -46442,11 +46502,23 @@ var ts; return node; } ts.createConditional = createConditional; - function updateConditional(node, condition, whenTrue, whenFalse) { + function updateConditional(node, condition) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + if (args.length === 2) { + var whenTrue_1 = args[0], whenFalse_1 = args[1]; + return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1); + } + ts.Debug.assert(args.length === 4); + var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3]; return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } ts.updateConditional = updateConditional; @@ -49626,7 +49698,7 @@ var ts; case 186 /* FunctionExpression */: return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 187 /* ArrowFunction */: - return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); + return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context)); case 188 /* DeleteExpression */: return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression)); case 189 /* TypeOfExpression */: @@ -49642,7 +49714,7 @@ var ts; case 194 /* BinaryExpression */: return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken)); case 195 /* ConditionalExpression */: - return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.whenFalse, visitor, ts.isExpression)); + return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression)); case 196 /* TemplateExpression */: return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan)); case 197 /* YieldExpression */: @@ -52221,7 +52293,11 @@ var ts; var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true); var descriptor = languageVersion > 0 /* ES3 */ ? member.kind === 149 /* PropertyDeclaration */ + // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it + // should not invoke `Object.getOwnPropertyDescriptor`. ? ts.createVoidZero() + // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly. + // We have this extra argument here so that we can inject an explicit property descriptor at a later date. : ts.createNull() : undefined; var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member)); @@ -52863,7 +52939,7 @@ var ts; function visitArrowFunction(node) { var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context)); + /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context)); return updated; } /** @@ -53939,7 +54015,7 @@ var ts; function visitArrowFunction(node) { return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */ + /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */ ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } @@ -54528,7 +54604,7 @@ var ts; enclosingFunctionFlags = ts.getFunctionFlags(node); var updated = ts.updateArrowFunction(node, node.modifiers, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, transformFunctionBody(node)); + /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } @@ -54949,7 +55025,9 @@ var ts; } } return firstNonWhitespace !== -1 + // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace. ? addLineOfJsxText(acc, text.substr(firstNonWhitespace)) + // Last line was all whitespace, so ignore it : acc; } function addLineOfJsxText(acc, trimmedLine) { @@ -66901,8 +66979,15 @@ var ts; comments.reset(); setWriter(/*output*/ undefined); } + // TODO: Should this just be `emit`? + // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034 + function emitIfPresent(node) { + if (node) { + emit(node); + } + } function emit(node) { - pipelineEmitWithNotification(3 /* Unspecified */, node); + pipelineEmitWithNotification(4 /* Unspecified */, node); } function emitIdentifierName(node) { pipelineEmitWithNotification(2 /* IdentifierName */, node); @@ -66940,7 +67025,8 @@ var ts; case 0 /* SourceFile */: return pipelineEmitSourceFile(node); case 2 /* IdentifierName */: return pipelineEmitIdentifierName(node); case 1 /* Expression */: return pipelineEmitExpression(node); - case 3 /* Unspecified */: return pipelineEmitUnspecified(node); + case 3 /* MappedTypeParameter */: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); + case 4 /* Unspecified */: return pipelineEmitUnspecified(node); } } function pipelineEmitSourceFile(node) { @@ -66951,6 +67037,11 @@ var ts; ts.Debug.assertNode(node, ts.isIdentifier); emitIdentifier(node); } + function emitMappedTypeParameter(node) { + emit(node.name); + write(" in "); + emit(node.constraint); + } function pipelineEmitUnspecified(node) { var kind = node.kind; // Reserved words @@ -67340,9 +67431,9 @@ var ts; function emitParameter(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -67357,7 +67448,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -67365,7 +67456,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -67374,7 +67465,7 @@ var ts; emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -67383,9 +67474,9 @@ var ts; function emitMethodDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } function emitConstructor(node) { @@ -67458,10 +67549,8 @@ var ts; } function emitTypeLiteral(node) { write("{"); - // If the literal is empty, do not add spaces between braces. - if (node.members.length > 0) { - emitList(node, node.members, ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */); - } + var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */; + emitList(node, node.members, flags | 262144 /* NoSpaceIfEmpty */); write("}"); } function emitArrayType(node) { @@ -67508,13 +67597,14 @@ var ts; writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); + } write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); + pipelineEmitWithNotification(3 /* MappedTypeParameter */, node.typeParameter); write("]"); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -67557,7 +67647,7 @@ var ts; } function emitBindingElement(node) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } @@ -67566,30 +67656,19 @@ var ts; // function emitArrayLiteralExpression(node) { var elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; - emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine); - } + var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; + emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine); } function emitObjectLiteralExpression(node) { - var properties = node.properties; - if (properties.length === 0) { - write("{}"); + var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; + if (indentedFlag) { + increaseIndent(); } - else { - var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; - if (indentedFlag) { - increaseIndent(); - } - var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; - var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */; - emitList(node, properties, 978 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; + var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */; + emitList(node, node.properties, 263122 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine); + if (indentedFlag) { + decreaseIndent(); } } function emitPropertyAccessExpression(node) { @@ -67676,7 +67755,8 @@ var ts; emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node) { write("delete "); @@ -67743,12 +67823,12 @@ var ts; var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse); emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); @@ -67758,7 +67838,8 @@ var ts; emitList(node, node.templateSpans, 131072 /* TemplateExpressionSpans */); } function emitYieldExpression(node) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } function emitSpreadExpression(node) { @@ -68001,7 +68082,9 @@ var ts; function emitFunctionDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + emitIfPresent(node.asteriskToken); + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -68019,7 +68102,7 @@ var ts; if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) { emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3 /* Unspecified */, body, emitBlockCallback); + onEmitNode(4 /* Unspecified */, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -68029,7 +68112,7 @@ var ts; pushNameGenerationScope(); emitSignatureHead(node); if (onEmitNode) { - onEmitNode(3 /* Unspecified */, body, emitBlockCallback); + onEmitNode(4 /* Unspecified */, body, emitBlockCallback); } else { emitBlockFunctionBody(body); @@ -68346,9 +68429,7 @@ var ts; function emitJsxExpression(node) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -68396,13 +68477,12 @@ var ts; // Note: we can't use parentNode.end as such position includes statements. emitTrailingCommentsOfPosition(statements.pos); } + var format = 81985 /* CaseOrDefaultClauseStatements */; if (emitAsSingleStatement) { write(" "); - emit(statements[0]); - } - else { - emitList(parentNode, statements, 81985 /* CaseOrDefaultClauseStatements */); + format &= ~(1 /* MultiLine */ | 64 /* Indented */); } + emitList(parentNode, statements, format); } function emitHeritageClause(node) { write(" "); @@ -68623,7 +68703,7 @@ var ts; } function emitParametersForArrow(parentNode, parameters) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitList(parentNode, parameters, 1360 /* Parameters */ & ~1024 /* Parenthesis */); } else { emitParameters(parentNode, parameters); @@ -68660,7 +68740,7 @@ var ts; if (format & 1 /* MultiLine */) { writeLine(); } - else if (format & 128 /* SpaceBetweenBraces */) { + else if (format & 128 /* SpaceBetweenBraces */ && !(format & 262144 /* NoSpaceIfEmpty */)) { write(" "); } } @@ -68779,11 +68859,6 @@ var ts; write(text); } } - function writeIfPresent(node, text) { - if (node) { - write(text); - } - } function writeToken(token, pos, contextNode) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) @@ -68793,7 +68868,7 @@ var ts; if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(ts.tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } @@ -69259,6 +69334,8 @@ var ts; ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine"; ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine"; ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments"; + ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty"; + ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement"; // Precomputed Formats ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers"; ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses"; @@ -69269,7 +69346,7 @@ var ts; ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents"; ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements"; ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements"; - ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 978] = "ObjectLiteralExpressionProperties"; + ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties"; ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements"; ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements"; ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments"; @@ -76093,8 +76170,10 @@ var ts; } if (request) { var entries_2 = request.kind === "JsDocTagName" + // If the current position is a jsDoc tag name, only tag names should be provided for completion ? ts.JsDoc.getJSDocTagNameCompletions() : request.kind === "JsDocTag" + // If the current position is a jsDoc tag, only tags should be provided for completion ? ts.JsDoc.getJSDocTagCompletions() : ts.JsDoc.getJSDocParameterNameCompletions(request.tag); return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries_2 }; @@ -85997,6 +86076,7 @@ var ts; return inheritedIndentation; } function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) { + ts.Debug.assert(ts.isNodeArray(nodes)); var listStartToken = getOpenTokenForList(parent, nodes); var listEndToken = getCloseTokenForOpenToken(listStartToken); var listDynamicIndentation = parentDynamicIndentation; @@ -86910,15 +86990,21 @@ var ts; * It can be changed to side-table later if we decide that current design is too invasive. */ function getPos(n) { - return n["__pos"]; + var result = n["__pos"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setPos(n, pos) { + ts.Debug.assert(typeof pos === "number"); n["__pos"] = pos; } function getEnd(n) { - return n["__end"]; + var result = n["__end"]; + ts.Debug.assert(typeof result === "number"); + return result; } function setEnd(n, end) { + ts.Debug.assert(typeof end === "number"); n["__end"] = end; } var Position; @@ -87382,10 +87468,9 @@ var ts; var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion }; var writer = new Writer(ts.getNewLineCharacter(options)); var printer = ts.createPrinter(options, writer); - printer.writeNode(3 /* Unspecified */, node, sourceFile, writer); + printer.writeNode(4 /* Unspecified */, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } - textChanges.getNonformattedText = getNonformattedText; function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, rulesProvider) { var lineMap = ts.computeLineStarts(nonFormattedText.text); var file = { @@ -87396,7 +87481,6 @@ var ts; var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider); return applyChanges(nonFormattedText.text, changes); } - textChanges.applyFormatting = applyFormatting; function applyChanges(text, changes) { for (var i = changes.length - 1; i >= 0; i--) { var change = changes[i]; @@ -87411,13 +87495,10 @@ var ts; function assignPositionsToNode(node) { var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes - var newNode = ts.nodeIsSynthesized(visited) - ? visited - : (Proxy.prototype = visited, new Proxy()); + var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited); newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; - function Proxy() { } } function assignPositionsToNodeArray(nodes, visitor, test, start, count) { var visited = ts.visitNodes(nodes, visitor, test, start, count); @@ -90026,12 +90107,12 @@ var ts; newFunction = ts.createMethod( /*decorators*/ undefined, modifiers, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, /*questionToken*/ undefined, - /*typeParameters*/ [], parameters, returnType, body); + /*typeParameters*/ undefined, parameters, returnType, body); } else { newFunction = ts.createFunctionDeclaration( /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, - /*typeParameters*/ [], parameters, returnType, body); + /*typeParameters*/ undefined, parameters, returnType, body); } var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); // insert function at the end of the scope diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index f92f5afca5199..2da644fe8b8e4 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -162,7 +162,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.5"; - ts.version = ts.versionMajorMinor + ".2"; + ts.version = ts.versionMajorMinor + ".3"; })(ts || (ts = {})); (function (ts) { ts.collator = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(undefined, { usage: "sort", sensitivity: "accent" }) : undefined; @@ -7348,8 +7348,7 @@ var ts; } ts.isToken = isToken; function isNodeArray(array) { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; function isLiteralKind(kind) { From d3ce606fc4a8cf7b826e186b4b8b557cbf92cab8 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 6 Sep 2017 13:11:35 -0700 Subject: [PATCH 41/60] Disable lookahead in isStartOfParameter/isStartOfType --- src/compiler/core.ts | 2 +- src/compiler/parser.ts | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index fd4b63f53a4d8..309da10b18e49 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1257,7 +1257,7 @@ namespace ts { args[i] = arguments[i]; } - return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t); + return t => reduceLeft(args, (u, f) => f(u), t); } else if (d) { return t => d(c(b(a(t)))); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a2fe752ad18e9..71426f392983e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2237,7 +2237,14 @@ namespace ts { return token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifierKind(token()) || - token() === SyntaxKind.AtToken || isStartOfType(); + token() === SyntaxKind.AtToken || + // a jsdoc parameter can start directly with a type, but shouldn't look ahead + // in order to avoid confusion between parenthesized types and arrow functions + // eg + // declare function f(cb: function(number): void): void; + // vs + // f((n) => console.log(n)); + isStartOfType(/*disableLookahead*/ true); } function parseParameter(): ParameterDeclaration { @@ -2696,7 +2703,7 @@ namespace ts { } } - function isStartOfType(): boolean { + function isStartOfType(disableLookahead?: boolean): boolean { switch (token()) { case SyntaxKind.AnyKeyword: case SyntaxKind.StringKeyword: @@ -2723,11 +2730,11 @@ namespace ts { case SyntaxKind.AsteriskToken: return true; case SyntaxKind.MinusToken: - return lookAhead(nextTokenIsNumericLiteral); + return !disableLookahead && lookAhead(nextTokenIsNumericLiteral); case SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !disableLookahead && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } From 7f639cc34b4c6a3c5af56afe2790586b0bcdd5ba Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 6 Sep 2017 15:54:14 -0700 Subject: [PATCH 42/60] Test:disable lookahead in isStartOfParameter --- src/compiler/parser.ts | 6 ------ ...arrowfunctionsOptionalArgsErrors2.errors.txt | 17 +++++++++++++---- .../fatarrowfunctionsOptionalArgsErrors2.js | 6 ++---- .../baselines/reference/parser512325.errors.txt | 17 +++++++++++++---- tests/baselines/reference/parser512325.js | 6 ++---- .../parserArrowFunctionExpression5.errors.txt | 15 +++++++++++++++ .../reference/parserArrowFunctionExpression5.js | 10 ++++++++++ .../parserArrowFunctionExpression5.ts | 5 +++++ 8 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/parserArrowFunctionExpression5.errors.txt create mode 100644 tests/baselines/reference/parserArrowFunctionExpression5.js create mode 100644 tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 71426f392983e..ec43dc0f0462e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2238,12 +2238,6 @@ namespace ts { isIdentifierOrPattern() || isModifierKind(token()) || token() === SyntaxKind.AtToken || - // a jsdoc parameter can start directly with a type, but shouldn't look ahead - // in order to avoid confusion between parenthesized types and arrow functions - // eg - // declare function f(cb: function(number): void): void; - // vs - // f((n) => console.log(n)); isStartOfType(/*disableLookahead*/ true); } diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt index 51db9c7391e40..b435e7773f5b0 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt @@ -1,7 +1,10 @@ -tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,15): error TS1003: Identifier expected. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,12): error TS2304: Cannot find name 'a'. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,12): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,16): error TS2304: Cannot find name 'b'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,16): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,19): error TS2304: Cannot find name 'c'. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,23): error TS1005: ';' expected. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,26): error TS2304: Cannot find name 'a'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,28): error TS2304: Cannot find name 'b'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,30): error TS2304: Cannot find name 'c'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(2,12): error TS2695: Left side of comma operator is unused and has no side effects. @@ -18,16 +21,22 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(4,17): error TS1005 tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(4,20): error TS2304: Cannot find name 'a'. -==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts (18 errors) ==== +==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts (21 errors) ==== var tt1 = (a, (b, c)) => a+b+c; - ~ -!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'b'. ~ !!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'c'. + ~~ +!!! error TS1005: ';' expected. + ~ +!!! error TS2304: Cannot find name 'a'. ~ !!! error TS2304: Cannot find name 'b'. ~ diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js index a1c68ea44760c..b51003b62dfaf 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js @@ -5,10 +5,8 @@ var tt2 = ((a), b, c) => a+b+c; var tt3 = ((a)) => a; //// [fatarrowfunctionsOptionalArgsErrors2.js] -var tt1 = function (a, ) { - if ( === void 0) { = (b, c); } - return a + b + c; -}; +var tt1 = (a, (b, c)); +a + b + c; var tt2 = ((a), b, c); a + b + c; var tt3 = ((a)); diff --git a/tests/baselines/reference/parser512325.errors.txt b/tests/baselines/reference/parser512325.errors.txt index f54d9f2110a9a..e6a47fbf226e3 100644 --- a/tests/baselines/reference/parser512325.errors.txt +++ b/tests/baselines/reference/parser512325.errors.txt @@ -1,21 +1,30 @@ -tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,14): error TS1003: Identifier expected. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,11): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,11): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,15): error TS2304: Cannot find name 'b'. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,15): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,18): error TS2304: Cannot find name 'c'. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,22): error TS1005: ';' expected. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,25): error TS2304: Cannot find name 'a'. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,27): error TS2304: Cannot find name 'b'. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,29): error TS2304: Cannot find name 'c'. -==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts (6 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts (9 errors) ==== var tt = (a, (b, c)) => a+b+c; - ~ -!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'b'. ~ !!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'c'. + ~~ +!!! error TS1005: ';' expected. + ~ +!!! error TS2304: Cannot find name 'a'. ~ !!! error TS2304: Cannot find name 'b'. ~ diff --git a/tests/baselines/reference/parser512325.js b/tests/baselines/reference/parser512325.js index 75af6b9f39a1d..14cbcddd86bfc 100644 --- a/tests/baselines/reference/parser512325.js +++ b/tests/baselines/reference/parser512325.js @@ -2,7 +2,5 @@ var tt = (a, (b, c)) => a+b+c; //// [parser512325.js] -var tt = function (a, ) { - if ( === void 0) { = (b, c); } - return a + b + c; -}; +var tt = (a, (b, c)); +a + b + c; diff --git a/tests/baselines/reference/parserArrowFunctionExpression5.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression5.errors.txt new file mode 100644 index 0000000000000..220c4d42279a9 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression5.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts(1,2): error TS2304: Cannot find name 'bar'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts(1,6): error TS2304: Cannot find name 'x'. + + +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts (2 errors) ==== + (bar(x, + ~~~ +!!! error TS2304: Cannot find name 'bar'. + ~ +!!! error TS2304: Cannot find name 'x'. + () => {}, + () => {} + ) + ) + \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression5.js b/tests/baselines/reference/parserArrowFunctionExpression5.js new file mode 100644 index 0000000000000..b25d77a4b028d --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression5.js @@ -0,0 +1,10 @@ +//// [parserArrowFunctionExpression5.ts] +(bar(x, + () => {}, + () => {} + ) +) + + +//// [parserArrowFunctionExpression5.js] +(bar(x, function () { }, function () { })); diff --git a/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts new file mode 100644 index 0000000000000..d4ab2adefba2c --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts @@ -0,0 +1,5 @@ +(bar(x, + () => {}, + () => {} + ) +) From 236eb1e0f84e97b7dbb398ff4edce9f00f6ecc35 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 7 Sep 2017 09:07:59 -0700 Subject: [PATCH 43/60] Rename isStartOfType parameter used by isStartOfParameter --- src/compiler/parser.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ec43dc0f0462e..c47f8cd2ba451 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2238,7 +2238,7 @@ namespace ts { isIdentifierOrPattern() || isModifierKind(token()) || token() === SyntaxKind.AtToken || - isStartOfType(/*disableLookahead*/ true); + isStartOfType(/*inStartOfParameter*/ true); } function parseParameter(): ParameterDeclaration { @@ -2697,7 +2697,7 @@ namespace ts { } } - function isStartOfType(disableLookahead?: boolean): boolean { + function isStartOfType(inStartOfParameter?: boolean): boolean { switch (token()) { case SyntaxKind.AnyKeyword: case SyntaxKind.StringKeyword: @@ -2724,11 +2724,11 @@ namespace ts { case SyntaxKind.AsteriskToken: return true; case SyntaxKind.MinusToken: - return !disableLookahead && lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return !disableLookahead && lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } From 9434a81b71f2ef9b1fea00fb4cec8103f44c9160 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 8 Sep 2017 17:09:17 -0700 Subject: [PATCH 44/60] extractMethod: Support renameLocation (#18351) --- Gulpfile.ts | 2 +- src/harness/fourslash.ts | 38 ++- src/harness/unittests/extractMethods.ts | 11 +- src/server/client.ts | 4 +- .../refactors/convertFunctionToEs6Class.ts | 4 +- src/services/refactors/extractMethod.ts | 245 ++++++++++-------- src/services/types.ts | 5 +- .../reference/extractMethod/extractMethod1.js | 8 +- .../extractMethod/extractMethod10.js | 6 +- .../extractMethod/extractMethod11.js | 6 +- .../extractMethod/extractMethod12.js | 2 +- .../reference/extractMethod/extractMethod2.js | 8 +- .../reference/extractMethod/extractMethod3.js | 8 +- .../reference/extractMethod/extractMethod4.js | 8 +- .../reference/extractMethod/extractMethod5.js | 8 +- .../reference/extractMethod/extractMethod6.js | 8 +- .../reference/extractMethod/extractMethod7.js | 8 +- .../reference/extractMethod/extractMethod8.js | 8 +- .../reference/extractMethod/extractMethod9.js | 8 +- .../fourslash/extract-method-formatting.ts | 9 +- .../fourslash/extract-method-uniqueName.ts | 20 ++ tests/cases/fourslash/extract-method1.ts | 8 +- tests/cases/fourslash/extract-method10.ts | 7 + tests/cases/fourslash/extract-method13.ts | 20 +- tests/cases/fourslash/extract-method14.ts | 9 +- tests/cases/fourslash/extract-method15.ts | 10 +- tests/cases/fourslash/extract-method18.ts | 9 +- tests/cases/fourslash/extract-method19.ts | 9 +- tests/cases/fourslash/extract-method2.ts | 8 +- tests/cases/fourslash/extract-method21.ts | 10 +- tests/cases/fourslash/extract-method24.ts | 9 +- tests/cases/fourslash/extract-method25.ts | 9 +- tests/cases/fourslash/extract-method5.ts | 8 +- tests/cases/fourslash/extract-method7.ts | 7 +- tests/cases/fourslash/fourslash.ts | 2 +- 35 files changed, 319 insertions(+), 230 deletions(-) create mode 100644 tests/cases/fourslash/extract-method-uniqueName.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index 757cd4fed0888..63bdb52e43514 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -776,7 +776,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo const file = new Vinyl({ contents, path: bundlePath }); console.log(`Fixing sourcemaps for ${file.path}`); // assumes contents is a Buffer, since that's what browserify yields - const maps = convertMap.fromSource(stringContent, /*largeSource*/ true).toObject(); + const maps = convertMap.fromSource(stringContent).toObject(); delete maps.sourceRoot; maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s)); // Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 77639dcc0787b..8421e33ba3452 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2736,11 +2736,11 @@ namespace FourSlash { } } - private getSelection() { - return ({ + private getSelection(): ts.TextRange { + return { pos: this.currentCaretPosition, end: this.selectionEnd === -1 ? this.currentCaretPosition : this.selectionEnd - }); + }; } public verifyRefactorAvailable(negative: boolean, name: string, actionName?: string) { @@ -2781,7 +2781,7 @@ namespace FourSlash { } } - public applyRefactor({ refactorName, actionName, actionDescription }: FourSlashInterface.ApplyRefactorOptions) { + public applyRefactor({ refactorName, actionName, actionDescription, newContent: newContentWithRenameMarker }: FourSlashInterface.ApplyRefactorOptions) { const range = this.getSelection(); const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range); const refactor = refactors.find(r => r.name === refactorName); @@ -2801,6 +2801,35 @@ namespace FourSlash { for (const edit of editInfo.edits) { this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false); } + + const { renamePosition, newContent } = parseNewContent(); + + this.verifyCurrentFileContent(newContent); + + if (renamePosition === undefined) { + if (editInfo.renameLocation !== undefined) { + this.raiseError(`Did not expect a rename location, got ${editInfo.renameLocation}`); + } + } + else { + // TODO: test editInfo.renameFilename value + assert.isDefined(editInfo.renameFilename); + if (renamePosition !== editInfo.renameLocation) { + this.raiseError(`Expected rename position of ${renamePosition}, but got ${editInfo.renameLocation}`); + } + } + + function parseNewContent(): { renamePosition: number | undefined, newContent: string } { + const renamePosition = newContentWithRenameMarker.indexOf("/*RENAME*/"); + if (renamePosition === -1) { + return { renamePosition: undefined, newContent: newContentWithRenameMarker }; + } + else { + const newContent = newContentWithRenameMarker.slice(0, renamePosition) + newContentWithRenameMarker.slice(renamePosition + "/*RENAME*/".length); + return { renamePosition, newContent }; + } + } + } public verifyFileAfterApplyingRefactorAtMarker( @@ -4291,5 +4320,6 @@ namespace FourSlashInterface { refactorName: string; actionName: string; actionDescription: string; + newContent: string; } } diff --git a/src/harness/unittests/extractMethods.ts b/src/harness/unittests/extractMethods.ts index d096cd3d375d9..c9f3fe358bb0b 100644 --- a/src/harness/unittests/extractMethods.ts +++ b/src/harness/unittests/extractMethods.ts @@ -224,7 +224,7 @@ namespace ts { testExtractRange(` function f() { while (true) { - [#| + [#| if (x) { return; } |] @@ -234,7 +234,7 @@ namespace ts { testExtractRange(` function f() { while (true) { - [#| + [#| [$|if (x) { } return;|] @@ -580,9 +580,12 @@ namespace A { data.push(`==ORIGINAL==`); data.push(sourceFile.text); for (const r of results) { - const changes = refactor.extractMethod.getPossibleExtractions(result.targetRange, context, results.indexOf(r))[0].changes; + const { renameLocation, edits } = refactor.extractMethod.getExtractionAtIndex(result.targetRange, context, results.indexOf(r)); + assert.lengthOf(edits, 1); data.push(`==SCOPE::${r.scopeDescription}==`); - data.push(textChanges.applyChanges(sourceFile.text, changes[0].textChanges)); + const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges); + const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation); + data.push(newTextWithRename); } return data.join(newLineCharacter); }); diff --git a/src/server/client.ts b/src/server/client.ts index a7e0615dce866..f6ec155e008c2 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -582,9 +582,7 @@ namespace ts.server { const response = this.processResponse(request); if (!response.body) { - return { - edits: [] - }; + return { edits: [], renameFilename: undefined, renameLocation: undefined }; } const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index bf0e4e22658b7..f929f265dc572 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -97,7 +97,9 @@ namespace ts.refactor.convertFunctionToES6Class { } return { - edits: changeTracker.getChanges() + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined, }; function deleteNode(node: Node, inList = false) { diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts index 4cec56474b953..542770ab9295c 100644 --- a/src/services/refactors/extractMethod.ts +++ b/src/services/refactors/extractMethod.ts @@ -31,16 +31,16 @@ namespace ts.refactor.extractMethod { const usedNames: Map = createMap(); let i = 0; - for (const extr of extractions) { + for (const { scopeDescription, errors } of extractions) { // Skip these since we don't have a way to report errors yet - if (extr.errors && extr.errors.length) { + if (errors.length) { continue; } // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes - const description = formatStringFromArgs(Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + const description = formatStringFromArgs(Diagnostics.Extract_function_into_0.message, [scopeDescription]); if (!usedNames.has(description)) { usedNames.set(description, true); actions.push({ @@ -75,10 +75,7 @@ namespace ts.refactor.extractMethod { const index = +parsedIndexMatch[1]; Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); - const extractions = getPossibleExtractions(targetRange, context, index); - // Scope is no longer valid from when the user issued the refactor (??) - Debug.assert(extractions !== undefined, "The extraction went missing? How?"); - return ({ edits: extractions[0].changes }); + return getExtractionAtIndex(targetRange, context, index); } // Move these into diagnostic messages if they become user-facing @@ -102,7 +99,7 @@ namespace ts.refactor.extractMethod { export const CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); } - export enum RangeFacts { + enum RangeFacts { None = 0, HasReturn = 1 << 0, IsGenerator = 1 << 1, @@ -117,7 +114,7 @@ namespace ts.refactor.extractMethod { /** * Represents an expression or a list of statements that should be extracted with some extra information */ - export interface TargetRange { + interface TargetRange { readonly range: Expression | Statement[]; readonly facts: RangeFacts; /** @@ -130,7 +127,7 @@ namespace ts.refactor.extractMethod { /** * Result of 'getRangeToExtract' operation: contains either a range or a list of errors */ - export type RangeToExtract = { + type RangeToExtract = { readonly targetRange?: never; readonly errors: ReadonlyArray; } | { @@ -141,18 +138,7 @@ namespace ts.refactor.extractMethod { /* * Scopes that can store newly extracted method */ - export type Scope = FunctionLikeDeclaration | SourceFile | ModuleBlock | ClassLikeDeclaration; - - /** - * Result of 'extractRange' operation for a specific scope. - * Stores either a list of changes that should be applied to extract a range or a list of errors - */ - export interface ExtractResultForScope { - readonly scope: Scope; - readonly scopeDescription: string; - readonly changes?: FileTextChanges[]; - readonly errors?: Diagnostic[]; - } + type Scope = FunctionLikeDeclaration | SourceFile | ModuleBlock | ClassLikeDeclaration; /** * getRangeToExtract takes a span inside a text file and returns either an expression or an array @@ -160,6 +146,7 @@ namespace ts.refactor.extractMethod { * process may fail, in which case a set of errors is returned instead (these are currently * not shown to the user, but can be used by us diagnostically) */ + // exported only for tests export function getRangeToExtract(sourceFile: SourceFile, span: TextSpan): RangeToExtract { const length = span.length || 0; // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. @@ -473,7 +460,7 @@ namespace ts.refactor.extractMethod { * you may be able to extract into a class method *or* local closure *or* namespace function, * depending on what's in the extracted body. */ - export function collectEnclosingScopes(range: TargetRange): Scope[] | undefined { + function collectEnclosingScopes(range: TargetRange): Scope[] | undefined { let current: Node = isReadonlyArray(range.range) ? firstOrUndefined(range.range) : range.range; if (range.facts & RangeFacts.UsesThis) { // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class @@ -509,12 +496,32 @@ namespace ts.refactor.extractMethod { return scopes; } + // exported only for tests + export function getExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo { + const { scopes, readsAndWrites: { target, usagesPerScope, errorsPerScope } } = getPossibleExtractionsWorker(targetRange, context); + Debug.assert(!errorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + context.cancellationToken.throwIfCancellationRequested(); + return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context); + } + + interface PossibleExtraction { + readonly scopeDescription: string; + readonly errors: ReadonlyArray; + } /** * Given a piece of text to extract ('targetRange'), computes a list of possible extractions. * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes * or an error explaining why we can't extract into that scope. */ - export function getPossibleExtractions(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number = undefined): ReadonlyArray | undefined { + // exported only for tests + export function getPossibleExtractions(targetRange: TargetRange, context: RefactorContext): ReadonlyArray | undefined { + const extractions = getPossibleExtractionsWorker(targetRange, context); + // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 + return extractions && extractions.scopes.map((scope, i): PossibleExtraction => + ({ scopeDescription: getDescriptionForScope(scope), errors: extractions.readsAndWrites.errorsPerScope[i] })); + } + + function getPossibleExtractionsWorker(targetRange: TargetRange, context: RefactorContext): { readonly scopes: Scope[], readonly readsAndWrites: ReadsAndWrites } { const { file: sourceFile } = context; if (targetRange === undefined) { @@ -527,34 +534,13 @@ namespace ts.refactor.extractMethod { } const enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); - const { target, usagesPerScope, errorsPerScope } = collectReadsAndWrites( + const readsAndWrites = collectReadsAndWrites( targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()); - - context.cancellationToken.throwIfCancellationRequested(); - - if (requestedChangesIndex !== undefined) { - if (errorsPerScope[requestedChangesIndex].length) { - return undefined; - } - return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; - } - else { - return scopes.map((scope, i) => { - const errors = errorsPerScope[i]; - if (errors.length) { - return { - scope, - scopeDescription: getDescriptionForScope(scope), - errors - }; - } - return { scope, scopeDescription: getDescriptionForScope(scope) }; - }); - } + return { scopes, readsAndWrites }; } function getDescriptionForScope(scope: Scope) { @@ -596,34 +582,33 @@ namespace ts.refactor.extractMethod { } } - function getUniqueName(isNameOkay: (name: string) => boolean) { + function getUniqueName(fileText: string): string { let functionNameText = "newFunction"; - if (isNameOkay(functionNameText)) { - return functionNameText; - } - let i = 1; - while (!isNameOkay(functionNameText = `newFunction_${i}`)) { - i++; + for (let i = 1; fileText.indexOf(functionNameText) !== -1; i++) { + functionNameText = `newFunction_${i}`; } return functionNameText; } - export function extractFunctionInScope( + /** + * Result of 'extractRange' operation for a specific scope. + * Stores either a list of changes that should be applied to extract a range or a list of errors + */ + function extractFunctionInScope( node: Statement | Expression | Block, scope: Scope, { usages: usagesInScope, substitutions }: ScopeUsages, range: TargetRange, - context: RefactorContext): ExtractResultForScope { + context: RefactorContext): RefactorEditInfo { const checker = context.program.getTypeChecker(); // Make a unique name for the extracted function const file = scope.getSourceFile(); - const functionNameText: string = getUniqueName(n => !file.identifiers.has(n)); + const functionNameText = getUniqueName(file.text); const isJS = isInJavaScriptFile(scope); - const functionName = createIdentifier(functionNameText as string); - const functionReference = createIdentifier(functionNameText as string); + const functionName = createIdentifier(functionNameText); let returnType: TypeNode = undefined; const parameters: ParameterDeclaration[] = []; @@ -660,7 +645,7 @@ namespace ts.refactor.extractMethod { returnType = checker.typeToTypeNode(contextualType); } - const { body, returnValueProperty } = transformFunctionBody(node); + const { body, returnValueProperty } = transformFunctionBody(node, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)); let newFunction: MethodDeclaration | FunctionDeclaration; if (isClassLike(scope)) { @@ -703,8 +688,10 @@ namespace ts.refactor.extractMethod { const newNodes: Node[] = []; // replace range with function call + const called = getCalledExpression(scope, range, functionNameText); + let call: Expression = createCall( - isClassLike(scope) ? createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? createIdentifier(scope.name.getText()) : createThis(), functionReference) : functionReference, + called, /*typeArguments*/ undefined, callArguments); if (range.facts & RangeFacts.IsGenerator) { @@ -769,73 +756,96 @@ namespace ts.refactor.extractMethod { changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); } - return { - scope, - scopeDescription: getDescriptionForScope(scope), - changes: changeTracker.getChanges() - }; + const edits = changeTracker.getChanges(); + const renameRange = isReadonlyArray(range.range) ? range.range[0] : range.range; + + const renameFilename = renameRange.getSourceFile().fileName; + const renameLocation = getRenameLocation(edits, renameFilename, functionNameText); + return { renameFilename, renameLocation, edits }; + } - function getPropertyAssignmentsForWrites(writes: UsageEntry[]) { - return writes.map(w => createShorthandPropertyAssignment(w.symbol.name)); + function getRenameLocation(edits: ReadonlyArray, renameFilename: string, functionNameText: string): number { + let delta = 0; + for (const { fileName, textChanges } of edits) { + Debug.assert(fileName === renameFilename); + for (const change of textChanges) { + const { span, newText } = change; + // TODO(acasey): We are assuming that the call expression comes before the function declaration, + // because we want the new cursor to be on the call expression, + // which is closer to where the user was before extracting the function. + const index = newText.indexOf(functionNameText); + if (index !== -1) { + return span.start + delta + index; + } + delta += newText.length - span.length; + } } + throw new Error(); // Didn't find the text we inserted? + } - function generateReturnValueProperty() { - return "__return"; + function getCalledExpression(scope: Node, range: TargetRange, functionNameText: string): Expression { + const functionReference = createIdentifier(functionNameText); + if (isClassLike(scope)) { + const lhs = range.facts & RangeFacts.InStaticRegion ? createIdentifier(scope.name.text) : createThis(); + return createPropertyAccess(lhs, functionReference); } + else { + return functionReference; + } + } - function transformFunctionBody(body: Node) { - if (isBlock(body) && !writes && substitutions.size === 0) { - // already block, no writes to propagate back, no substitutions - can use node as is - return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; - } - let returnValueProperty: string; - const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(body)]); - // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions - if (writes || substitutions.size) { - const rewrittenStatements = visitNodes(statements, visitor).slice(); - if (writes && !(range.facts & RangeFacts.HasReturn) && isStatement(body)) { - // add return at the end to propagate writes back in case if control flow falls out of the function body - // it is ok to know that range has at least one return since it we only allow unconditional returns - const assignments = getPropertyAssignmentsForWrites(writes); - if (assignments.length === 1) { - rewrittenStatements.push(createReturn(assignments[0].name)); - } - else { - rewrittenStatements.push(createReturn(createObjectLiteral(assignments))); - } + function transformFunctionBody(body: Node, writes: ReadonlyArray, substitutions: ReadonlyMap, hasReturn: boolean): { body: Block, returnValueProperty: string } { + if (isBlock(body) && !writes && substitutions.size === 0) { + // already block, no writes to propagate back, no substitutions - can use node as is + return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + } + let returnValueProperty: string; + const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(body)]); + // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions + if (writes || substitutions.size) { + const rewrittenStatements = visitNodes(statements, visitor).slice(); + if (writes && !hasReturn && isStatement(body)) { + // add return at the end to propagate writes back in case if control flow falls out of the function body + // it is ok to know that range has at least one return since it we only allow unconditional returns + const assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(createReturn(createObjectLiteral(assignments))); } - return { body: createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty }; - } - else { - return { body: createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; } + return { body: createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty }; + } + else { + return { body: createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + } - function visitor(node: Node): VisitResult { - if (node.kind === SyntaxKind.ReturnStatement && writes) { - const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWrites(writes); - if ((node).expression) { - if (!returnValueProperty) { - returnValueProperty = generateReturnValueProperty(); - } - assignments.unshift(createPropertyAssignment(returnValueProperty, visitNode((node).expression, visitor))); - } - if (assignments.length === 1) { - return createReturn(assignments[0].name as Expression); - } - else { - return createReturn(createObjectLiteral(assignments)); + function visitor(node: Node): VisitResult { + if (node.kind === SyntaxKind.ReturnStatement && writes) { + const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWrites(writes); + if ((node).expression) { + if (!returnValueProperty) { + returnValueProperty = "__return"; } + assignments.unshift(createPropertyAssignment(returnValueProperty, visitNode((node).expression, visitor))); + } + if (assignments.length === 1) { + return createReturn(assignments[0].name as Expression); } else { - const substitution = substitutions.get(getNodeId(node).toString()); - return substitution || visitEachChild(node, visitor, nullTransformationContext); + return createReturn(createObjectLiteral(assignments)); } } + else { + const substitution = substitutions.get(getNodeId(node).toString()); + return substitution || visitEachChild(node, visitor, nullTransformationContext); + } } } - function isModuleBlock(n: Node): n is ModuleBlock { - return n.kind === SyntaxKind.ModuleBlock; + function getPropertyAssignmentsForWrites(writes: ReadonlyArray): ShorthandPropertyAssignment[] { + return writes.map(w => createShorthandPropertyAssignment(w.symbol.name)); } function isReadonlyArray(v: any): v is ReadonlyArray { @@ -871,16 +881,21 @@ namespace ts.refactor.extractMethod { } interface ScopeUsages { - usages: Map; - substitutions: Map; + readonly usages: Map; + readonly substitutions: Map; } + interface ReadsAndWrites { + readonly target: Expression | Block; + readonly usagesPerScope: ReadonlyArray; + readonly errorsPerScope: ReadonlyArray>; + } function collectReadsAndWrites( targetRange: TargetRange, scopes: Scope[], enclosingTextRange: TextRange, sourceFile: SourceFile, - checker: TypeChecker) { + checker: TypeChecker): ReadsAndWrites { const usagesPerScope: ScopeUsages[] = []; const substitutionsPerScope: Map[] = []; diff --git a/src/services/types.ts b/src/services/types.ts index b034e2813c6e1..caf2c5562d38b 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -412,11 +412,10 @@ namespace ts { */ export type RefactorEditInfo = { edits: FileTextChanges[]; - renameFilename?: string; - renameLocation?: number; + renameFilename: string | undefined; + renameLocation: number | undefined; }; - export interface TextInsertion { newText: string; /** The position in newText the caret should point to after the insertion. */ diff --git a/tests/baselines/reference/extractMethod/extractMethod1.js b/tests/baselines/reference/extractMethod/extractMethod1.js index 10bf2648383bf..29936f95612c1 100644 --- a/tests/baselines/reference/extractMethod/extractMethod1.js +++ b/tests/baselines/reference/extractMethod/extractMethod1.js @@ -23,7 +23,7 @@ namespace A { function a() { let a = 1; - newFunction(); + /*RENAME*/newFunction(); function newFunction() { let y = 5; @@ -43,7 +43,7 @@ namespace A { function a() { let a = 1; - a = newFunction(a); + a = /*RENAME*/newFunction(a); } function newFunction(a: number) { @@ -64,7 +64,7 @@ namespace A { function a() { let a = 1; - a = newFunction(a); + a = /*RENAME*/newFunction(a); } } @@ -85,7 +85,7 @@ namespace A { function a() { let a = 1; - a = newFunction(x, a, foo); + a = /*RENAME*/newFunction(x, a, foo); } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod10.js b/tests/baselines/reference/extractMethod/extractMethod10.js index b2397744680b2..346c44871eb30 100644 --- a/tests/baselines/reference/extractMethod/extractMethod10.js +++ b/tests/baselines/reference/extractMethod/extractMethod10.js @@ -15,7 +15,7 @@ namespace A { class C { a() { let z = 1; - return this.newFunction(); + return this./*RENAME*/newFunction(); } private newFunction() { @@ -30,7 +30,7 @@ namespace A { class C { a() { let z = 1; - return newFunction(); + return /*RENAME*/newFunction(); } } @@ -45,7 +45,7 @@ namespace A { class C { a() { let z = 1; - return newFunction(); + return /*RENAME*/newFunction(); } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod11.js b/tests/baselines/reference/extractMethod/extractMethod11.js index 21392a07a7a4b..fe826586527e5 100644 --- a/tests/baselines/reference/extractMethod/extractMethod11.js +++ b/tests/baselines/reference/extractMethod/extractMethod11.js @@ -18,7 +18,7 @@ namespace A { a() { let z = 1; var __return: any; - ({ __return, z } = this.newFunction(z)); + ({ __return, z } = this./*RENAME*/newFunction(z)); return __return; } @@ -37,7 +37,7 @@ namespace A { a() { let z = 1; var __return: any; - ({ __return, z } = newFunction(z)); + ({ __return, z } = /*RENAME*/newFunction(z)); return __return; } } @@ -56,7 +56,7 @@ namespace A { a() { let z = 1; var __return: any; - ({ __return, y, z } = newFunction(y, z)); + ({ __return, y, z } = /*RENAME*/newFunction(y, z)); return __return; } } diff --git a/tests/baselines/reference/extractMethod/extractMethod12.js b/tests/baselines/reference/extractMethod/extractMethod12.js index 7cebab5d3c582..659b93d445701 100644 --- a/tests/baselines/reference/extractMethod/extractMethod12.js +++ b/tests/baselines/reference/extractMethod/extractMethod12.js @@ -21,7 +21,7 @@ namespace A { a() { let z = 1; var __return: any; - ({ __return, z } = this.newFunction(z)); + ({ __return, z } = this./*RENAME*/newFunction(z)); return __return; } diff --git a/tests/baselines/reference/extractMethod/extractMethod2.js b/tests/baselines/reference/extractMethod/extractMethod2.js index 3c0d2e7c7b01c..93f2834839245 100644 --- a/tests/baselines/reference/extractMethod/extractMethod2.js +++ b/tests/baselines/reference/extractMethod/extractMethod2.js @@ -20,7 +20,7 @@ namespace A { namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); function newFunction() { let y = 5; @@ -38,7 +38,7 @@ namespace A { namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); } function newFunction() { @@ -56,7 +56,7 @@ namespace A { namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); } } @@ -74,7 +74,7 @@ namespace A { namespace B { function a() { - return newFunction(x, foo); + return /*RENAME*/newFunction(x, foo); } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod3.js b/tests/baselines/reference/extractMethod/extractMethod3.js index cb28e2755e708..54d31d2458c0d 100644 --- a/tests/baselines/reference/extractMethod/extractMethod3.js +++ b/tests/baselines/reference/extractMethod/extractMethod3.js @@ -18,7 +18,7 @@ namespace A { namespace B { function* a(z: number) { - return yield* newFunction(); + return yield* /*RENAME*/newFunction(); function* newFunction() { let y = 5; @@ -35,7 +35,7 @@ namespace A { namespace B { function* a(z: number) { - return yield* newFunction(z); + return yield* /*RENAME*/newFunction(z); } function* newFunction(z: number) { @@ -52,7 +52,7 @@ namespace A { namespace B { function* a(z: number) { - return yield* newFunction(z); + return yield* /*RENAME*/newFunction(z); } } @@ -69,7 +69,7 @@ namespace A { namespace B { function* a(z: number) { - return yield* newFunction(z, foo); + return yield* /*RENAME*/newFunction(z, foo); } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod4.js b/tests/baselines/reference/extractMethod/extractMethod4.js index 8d4feb3ea2364..dbb5b7f3a8814 100644 --- a/tests/baselines/reference/extractMethod/extractMethod4.js +++ b/tests/baselines/reference/extractMethod/extractMethod4.js @@ -20,7 +20,7 @@ namespace A { namespace B { async function a(z: number, z1: any) { - return await newFunction(); + return await /*RENAME*/newFunction(); async function newFunction() { let y = 5; @@ -39,7 +39,7 @@ namespace A { namespace B { async function a(z: number, z1: any) { - return await newFunction(z, z1); + return await /*RENAME*/newFunction(z, z1); } async function newFunction(z: number, z1: any) { @@ -58,7 +58,7 @@ namespace A { namespace B { async function a(z: number, z1: any) { - return await newFunction(z, z1); + return await /*RENAME*/newFunction(z, z1); } } @@ -77,7 +77,7 @@ namespace A { namespace B { async function a(z: number, z1: any) { - return await newFunction(z, z1, foo); + return await /*RENAME*/newFunction(z, z1, foo); } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod5.js b/tests/baselines/reference/extractMethod/extractMethod5.js index 96a76e426b14f..c14c88608ff04 100644 --- a/tests/baselines/reference/extractMethod/extractMethod5.js +++ b/tests/baselines/reference/extractMethod/extractMethod5.js @@ -23,7 +23,7 @@ namespace A { function a() { let a = 1; - newFunction(); + /*RENAME*/newFunction(); function newFunction() { let y = 5; @@ -43,7 +43,7 @@ namespace A { function a() { let a = 1; - a = newFunction(a); + a = /*RENAME*/newFunction(a); } function newFunction(a: number) { @@ -64,7 +64,7 @@ namespace A { function a() { let a = 1; - a = newFunction(a); + a = /*RENAME*/newFunction(a); } } @@ -85,7 +85,7 @@ namespace A { function a() { let a = 1; - a = newFunction(x, a); + a = /*RENAME*/newFunction(x, a); } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod6.js b/tests/baselines/reference/extractMethod/extractMethod6.js index d1244ac959649..e1d976818f603 100644 --- a/tests/baselines/reference/extractMethod/extractMethod6.js +++ b/tests/baselines/reference/extractMethod/extractMethod6.js @@ -23,7 +23,7 @@ namespace A { function a() { let a = 1; - return newFunction(); + return /*RENAME*/newFunction(); function newFunction() { let y = 5; @@ -44,7 +44,7 @@ namespace A { let a = 1; var __return: any; - ({ __return, a } = newFunction(a)); + ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } @@ -66,7 +66,7 @@ namespace A { let a = 1; var __return: any; - ({ __return, a } = newFunction(a)); + ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } } @@ -88,7 +88,7 @@ namespace A { let a = 1; var __return: any; - ({ __return, a } = newFunction(x, a)); + ({ __return, a } = /*RENAME*/newFunction(x, a)); return __return; } } diff --git a/tests/baselines/reference/extractMethod/extractMethod7.js b/tests/baselines/reference/extractMethod/extractMethod7.js index da400d8b05128..8bcb79414c0b4 100644 --- a/tests/baselines/reference/extractMethod/extractMethod7.js +++ b/tests/baselines/reference/extractMethod/extractMethod7.js @@ -27,7 +27,7 @@ namespace A { function a() { let a = 1; - return newFunction(); + return /*RENAME*/newFunction(); function newFunction() { let y = 5; @@ -50,7 +50,7 @@ namespace A { let a = 1; var __return: any; - ({ __return, a } = newFunction(a)); + ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } @@ -74,7 +74,7 @@ namespace A { let a = 1; var __return: any; - ({ __return, a } = newFunction(a)); + ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } } @@ -98,7 +98,7 @@ namespace A { let a = 1; var __return: any; - ({ __return, a } = newFunction(x, a)); + ({ __return, a } = /*RENAME*/newFunction(x, a)); return __return; } } diff --git a/tests/baselines/reference/extractMethod/extractMethod8.js b/tests/baselines/reference/extractMethod/extractMethod8.js index d298387b9026e..98853e3484e75 100644 --- a/tests/baselines/reference/extractMethod/extractMethod8.js +++ b/tests/baselines/reference/extractMethod/extractMethod8.js @@ -14,7 +14,7 @@ namespace A { namespace B { function a() { let a1 = 1; - return newFunction() + 100; + return /*RENAME*/newFunction() + 100; function newFunction() { return 1 + a1 + x; @@ -28,7 +28,7 @@ namespace A { namespace B { function a() { let a1 = 1; - return newFunction(a1) + 100; + return /*RENAME*/newFunction(a1) + 100; } function newFunction(a1: number) { @@ -42,7 +42,7 @@ namespace A { namespace B { function a() { let a1 = 1; - return newFunction(a1) + 100; + return /*RENAME*/newFunction(a1) + 100; } } @@ -56,7 +56,7 @@ namespace A { namespace B { function a() { let a1 = 1; - return newFunction(a1, x) + 100; + return /*RENAME*/newFunction(a1, x) + 100; } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod9.js b/tests/baselines/reference/extractMethod/extractMethod9.js index 609e3535d5762..700caf708f0f1 100644 --- a/tests/baselines/reference/extractMethod/extractMethod9.js +++ b/tests/baselines/reference/extractMethod/extractMethod9.js @@ -13,7 +13,7 @@ namespace A { export interface I { x: number }; namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); function newFunction() { let a1: I = { x: 1 }; @@ -27,7 +27,7 @@ namespace A { export interface I { x: number }; namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); } function newFunction() { @@ -41,7 +41,7 @@ namespace A { export interface I { x: number }; namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); } } @@ -55,7 +55,7 @@ namespace A { export interface I { x: number }; namespace B { function a() { - return newFunction(); + return /*RENAME*/newFunction(); } } } diff --git a/tests/cases/fourslash/extract-method-formatting.ts b/tests/cases/fourslash/extract-method-formatting.ts index 1342e5632e800..ac75ad85072dd 100644 --- a/tests/cases/fourslash/extract-method-formatting.ts +++ b/tests/cases/fourslash/extract-method-formatting.ts @@ -10,10 +10,8 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_1", actionDescription: "Extract function into global scope", -}); -verify.currentFileContentIs( -`function f(x: number): number { - return newFunction(x); + newContent: `function f(x: number): number { + return /*RENAME*/newFunction(x); } function newFunction(x: number) { switch (x) { @@ -21,4 +19,5 @@ function newFunction(x: number) { return 0; } } -`); +` +}); diff --git a/tests/cases/fourslash/extract-method-uniqueName.ts b/tests/cases/fourslash/extract-method-uniqueName.ts new file mode 100644 index 0000000000000..d0da7f70c548b --- /dev/null +++ b/tests/cases/fourslash/extract-method-uniqueName.ts @@ -0,0 +1,20 @@ +/// + +////// newFunction +/////*start*/1 + 1/*end*/; + +goTo.select('start', 'end') +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_0", + actionDescription: "Extract function into global scope", + newContent: +`// newFunction +/*RENAME*/newFunction_1(); + +function newFunction_1() { + // newFunction + 1 + 1; +} +` +}); diff --git a/tests/cases/fourslash/extract-method1.ts b/tests/cases/fourslash/extract-method1.ts index ff061295c8c6b..faf98c9c0ea30 100644 --- a/tests/cases/fourslash/extract-method1.ts +++ b/tests/cases/fourslash/extract-method1.ts @@ -17,11 +17,10 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into class 'Foo'", -}); -verify.currentFileContentIs( + newContent: `class Foo { someMethod(m: number) { - this.newFunction(m); + this./*RENAME*/newFunction(m); var q = 10; return q; } @@ -33,4 +32,5 @@ verify.currentFileContentIs( var z = y + x; console.log(z); } -}`); +}` +}); diff --git a/tests/cases/fourslash/extract-method10.ts b/tests/cases/fourslash/extract-method10.ts index ffbee7350e259..3094b86ac6e7e 100644 --- a/tests/cases/fourslash/extract-method10.ts +++ b/tests/cases/fourslash/extract-method10.ts @@ -8,4 +8,11 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: 'scope_0', actionDescription: "Extract function into module scope", + newContent: +`export {}; // Make this a module +(x => x)(/*RENAME*/newFunction())(1); +function newFunction(): (x: any) => any { + return x => x; +} +` }); diff --git a/tests/cases/fourslash/extract-method13.ts b/tests/cases/fourslash/extract-method13.ts index 14a146a80c509..26759d012df39 100644 --- a/tests/cases/fourslash/extract-method13.ts +++ b/tests/cases/fourslash/extract-method13.ts @@ -14,6 +14,16 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into class 'C'", + newContent: +`class C { + static j = 100; + constructor(q: string = C./*RENAME*/newFunction()) { + } + + private static newFunction(): string { + return "hello"; + } +}` }); goTo.select('c', 'd'); @@ -21,10 +31,9 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into class 'C'", -}); - -verify.currentFileContentIs(`class C { - static j = C.newFunction_1(); + newContent: +`class C { + static j = C./*RENAME*/newFunction_1(); constructor(q: string = C.newFunction()) { } @@ -35,4 +44,5 @@ verify.currentFileContentIs(`class C { private static newFunction_1() { return 100; } -}`); \ No newline at end of file +}` +}); diff --git a/tests/cases/fourslash/extract-method14.ts b/tests/cases/fourslash/extract-method14.ts index 696bb664bd358..f1d30aac43b38 100644 --- a/tests/cases/fourslash/extract-method14.ts +++ b/tests/cases/fourslash/extract-method14.ts @@ -15,14 +15,15 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_1", actionDescription: "Extract function into global scope", -}); -verify.currentFileContentIs(`function foo() { + newContent: +`function foo() { var i = 10; var __return: any; - ({ __return, i } = newFunction(i)); + ({ __return, i } = n/*RENAME*/ewFunction(i)); return __return; } function newFunction(i) { return { __return: i++, i }; } -`); \ No newline at end of file +` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/extract-method15.ts b/tests/cases/fourslash/extract-method15.ts index 93aa357cfee2e..eb63c65e0966d 100644 --- a/tests/cases/fourslash/extract-method15.ts +++ b/tests/cases/fourslash/extract-method15.ts @@ -13,14 +13,14 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_1", actionDescription: "Extract function into global scope", -}); - -verify.currentFileContentIs(`function foo() { + newContent: +`function foo() { var i = 10; - i = newFunction(i); + i = /*RENAME*/newFunction(i); } function newFunction(i: number) { i++; return i; } -`); +` +}); diff --git a/tests/cases/fourslash/extract-method18.ts b/tests/cases/fourslash/extract-method18.ts index d99d14bac73f6..4a76f3247a9b4 100644 --- a/tests/cases/fourslash/extract-method18.ts +++ b/tests/cases/fourslash/extract-method18.ts @@ -13,12 +13,13 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_1", actionDescription: "Extract function into global scope", -}); -verify.currentFileContentIs(`function fn() { + newContent: +`function fn() { const x = { m: 1 }; - newFunction(x); + /*RENAME*/newFunction(x); } function newFunction(x: { m: number; }) { x.m = 3; } -`); +` +}); diff --git a/tests/cases/fourslash/extract-method19.ts b/tests/cases/fourslash/extract-method19.ts index e4fb3e6e1110e..1904332f05939 100644 --- a/tests/cases/fourslash/extract-method19.ts +++ b/tests/cases/fourslash/extract-method19.ts @@ -13,13 +13,14 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into function 'fn'", -}); -verify.currentFileContentIs(`function fn() { - newFunction_1(); + newContent: +`function fn() { + /*RENAME*/newFunction_1(); function newFunction_1() { console.log("hi"); } } -function newFunction() { }`); +function newFunction() { }` +}); diff --git a/tests/cases/fourslash/extract-method2.ts b/tests/cases/fourslash/extract-method2.ts index 508836c419922..0839f6ad426ba 100644 --- a/tests/cases/fourslash/extract-method2.ts +++ b/tests/cases/fourslash/extract-method2.ts @@ -14,18 +14,18 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_2", actionDescription: "Extract function into global scope", -}); -verify.currentFileContentIs( + newContent: `namespace NS { class Q { foo() { console.log('100'); const m = 10, j = "hello", k = {x: "what"}; - const q = newFunction(m, j, k); + const q = /*RENAME*/newFunction(m, j, k); } } } function newFunction(m: number, j: string, k: { x: string; }) { return m + j + k; } -`); +` +}); diff --git a/tests/cases/fourslash/extract-method21.ts b/tests/cases/fourslash/extract-method21.ts index c32df5b59798e..f392e6876d16f 100644 --- a/tests/cases/fourslash/extract-method21.ts +++ b/tests/cases/fourslash/extract-method21.ts @@ -16,14 +16,14 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into class 'Foo'", -}); - -verify.currentFileContentIs(`class Foo { + newContent: +`class Foo { static method() { - return Foo.newFunction(); + return Foo./*RENAME*/newFunction(); } private static newFunction() { return 1; } -}`); \ No newline at end of file +}` +}); diff --git a/tests/cases/fourslash/extract-method24.ts b/tests/cases/fourslash/extract-method24.ts index 615cb2ac4d2f8..3d14126b4d1e4 100644 --- a/tests/cases/fourslash/extract-method24.ts +++ b/tests/cases/fourslash/extract-method24.ts @@ -11,13 +11,14 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_1", actionDescription: "Extract function into global scope", -}); -verify.currentFileContentIs(`function M() { + newContent: +`function M() { let a = [1,2,3]; let x = 0; - console.log(newFunction(a, x)); + console.log(/*RENAME*/newFunction(a, x)); } function newFunction(a: number[], x: number): any { return a[x]; } -`); \ No newline at end of file +` +}); diff --git a/tests/cases/fourslash/extract-method25.ts b/tests/cases/fourslash/extract-method25.ts index 8585dd06fd4ea..c88b05a778706 100644 --- a/tests/cases/fourslash/extract-method25.ts +++ b/tests/cases/fourslash/extract-method25.ts @@ -12,12 +12,13 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into function 'fn'", -}); -verify.currentFileContentIs(`function fn() { - var q = newFunction() + newContent: +`function fn() { + var q = /*RENAME*/newFunction() q[0]++ function newFunction() { return [0]; } -}`); +}` +}); diff --git a/tests/cases/fourslash/extract-method5.ts b/tests/cases/fourslash/extract-method5.ts index 10294298b085b..99c85410702e7 100644 --- a/tests/cases/fourslash/extract-method5.ts +++ b/tests/cases/fourslash/extract-method5.ts @@ -13,12 +13,12 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into function 'f'", -}); -verify.currentFileContentIs( + newContent: `function f() { - var x: 1 | 2 | 3 = newFunction(); + var x: 1 | 2 | 3 = /*RENAME*/newFunction(); function newFunction(): 1 | 2 | 3 { return 2; } -}`); \ No newline at end of file +}` +}); diff --git a/tests/cases/fourslash/extract-method7.ts b/tests/cases/fourslash/extract-method7.ts index 95c9cbe9897ec..8ef8eb38d3fb8 100644 --- a/tests/cases/fourslash/extract-method7.ts +++ b/tests/cases/fourslash/extract-method7.ts @@ -11,10 +11,11 @@ edit.applyRefactor({ refactorName: "Extract Method", actionName: "scope_0", actionDescription: "Extract function into global scope", -}); -verify.currentFileContentIs(`function fn(x = newFunction()) { + newContent: +`function fn(x = /*RENAME*/newFunction()) { } function newFunction() { return 3; } -`); +` +}); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index be842680e17ff..5e7452375f7e7 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -309,7 +309,7 @@ declare namespace FourSlashInterface { enableFormatting(): void; disableFormatting(): void; - applyRefactor(options: { refactorName: string, actionName: string, actionDescription: string }): void; + applyRefactor(options: { refactorName: string, actionName: string, actionDescription: string, newContent: string }): void; } class debug { printCurrentParameterHelp(): void; From c476a08188be95273037838d9d7cdb750e39924d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 8 Sep 2017 17:34:24 -0700 Subject: [PATCH 45/60] Update LKG --- lib/tsc.js | 9 +- lib/tsserver.js | 219 +++++++++++++++++----------------- lib/tsserverlibrary.d.ts | 4 +- lib/tsserverlibrary.js | 219 +++++++++++++++++----------------- lib/typescript.d.ts | 4 +- lib/typescript.js | 229 +++++++++++++++++++----------------- lib/typescriptServices.d.ts | 4 +- lib/typescriptServices.js | 229 +++++++++++++++++++----------------- lib/typingsInstaller.js | 9 +- 9 files changed, 492 insertions(+), 434 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index 33eeb6de3af24..d0fb24e1321e0 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -11088,7 +11088,8 @@ var ts; return token() === 24 || isIdentifierOrPattern() || ts.isModifierKind(token()) || - token() === 57 || isStartOfType(); + token() === 57 || + isStartOfType(true); } function parseParameter() { var node = createNode(146); @@ -11427,7 +11428,7 @@ var ts; return parseTypeReference(); } } - function isStartOfType() { + function isStartOfType(inStartOfParameter) { switch (token()) { case 119: case 136: @@ -11454,9 +11455,9 @@ var ts; case 39: return true; case 38: - return lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19: - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } diff --git a/lib/tsserver.js b/lib/tsserver.js index 21b0b83c062df..c1075eb497150 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -12958,7 +12958,8 @@ var ts; return token() === 24 || isIdentifierOrPattern() || ts.isModifierKind(token()) || - token() === 57 || isStartOfType(); + token() === 57 || + isStartOfType(true); } function parseParameter() { var node = createNode(146); @@ -13297,7 +13298,7 @@ var ts; return parseTypeReference(); } } - function isStartOfType() { + function isStartOfType(inStartOfParameter) { switch (token()) { case 119: case 136: @@ -13324,9 +13325,9 @@ var ts; case 39: return true; case 38: - return lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19: - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } @@ -74425,7 +74426,9 @@ var ts; deleteCallback(); } return { - edits: changeTracker.getChanges() + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined, }; function deleteNode(node, inList) { if (inList === void 0) { inList = false; } @@ -74576,11 +74579,11 @@ var ts; var usedNames = ts.createMap(); var i = 0; for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { - var extr = extractions_1[_i]; - if (extr.errors && extr.errors.length) { + var _a = extractions_1[_i], scopeDescription = _a.scopeDescription, errors = _a.errors; + if (errors.length) { continue; } - var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [scopeDescription]); if (!usedNames.has(description)) { usedNames.set(description, true); actions.push({ @@ -74608,9 +74611,7 @@ var ts; ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); var index = +parsedIndexMatch[1]; ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); - var extractions = getPossibleExtractions(targetRange, context, index); - ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); - return ({ edits: extractions[0].changes }); + return getExtractionAtIndex(targetRange, context, index); } var Messages; (function (Messages) { @@ -74639,7 +74640,7 @@ var ts; RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; - })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + })(RangeFacts || (RangeFacts = {})); function getRangeToExtract(sourceFile, span) { var length = span.length || 0; var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, false), sourceFile, span); @@ -74879,7 +74880,7 @@ var ts; return undefined; } function isValidExtractionTarget(node) { - return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); + return (node.kind === 228) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node); } function collectEnclosingScopes(range) { var current = isReadonlyArray(range.range) ? ts.firstOrUndefined(range.range) : range.range; @@ -74904,9 +74905,21 @@ var ts; } return scopes; } - extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; - function getPossibleExtractions(targetRange, context, requestedChangesIndex) { - if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + function getExtractionAtIndex(targetRange, context, requestedChangesIndex) { + var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, errorsPerScope = _b.errorsPerScope; + ts.Debug.assert(!errorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + context.cancellationToken.throwIfCancellationRequested(); + return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context); + } + extractMethod_1.getExtractionAtIndex = getExtractionAtIndex; + function getPossibleExtractions(targetRange, context) { + var extractions = getPossibleExtractionsWorker(targetRange, context); + return extractions && extractions.scopes.map(function (scope, i) { + return ({ scopeDescription: getDescriptionForScope(scope), errors: extractions.readsAndWrites.errorsPerScope[i] }); + }); + } + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getPossibleExtractionsWorker(targetRange, context) { var sourceFile = context.file; if (targetRange === undefined) { return undefined; @@ -74916,29 +74929,9 @@ var ts; return undefined; } var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); - var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; - context.cancellationToken.throwIfCancellationRequested(); - if (requestedChangesIndex !== undefined) { - if (errorsPerScope[requestedChangesIndex].length) { - return undefined; - } - return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; - } - else { - return scopes.map(function (scope, i) { - var errors = errorsPerScope[i]; - if (errors.length) { - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - errors: errors - }; - } - return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; - }); - } + var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()); + return { scopes: scopes, readsAndWrites: readsAndWrites }; } - extractMethod_1.getPossibleExtractions = getPossibleExtractions; function getDescriptionForScope(scope) { if (ts.isFunctionLike(scope)) { switch (scope.kind) { @@ -74960,7 +74953,7 @@ var ts; return "'set " + scope.name.getText() + "'"; } } - else if (isModuleBlock(scope)) { + else if (ts.isModuleBlock(scope)) { return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { @@ -74977,14 +74970,10 @@ var ts; return "unknown"; } } - function getUniqueName(isNameOkay) { + function getUniqueName(fileText) { var functionNameText = "newFunction"; - if (isNameOkay(functionNameText)) { - return functionNameText; - } - var i = 1; - while (!isNameOkay(functionNameText = "newFunction_" + i)) { - i++; + for (var i = 1; fileText.indexOf(functionNameText) !== -1; i++) { + functionNameText = "newFunction_" + i; } return functionNameText; } @@ -74992,10 +74981,9 @@ var ts; var usagesInScope = _a.usages, substitutions = _a.substitutions; var checker = context.program.getTypeChecker(); var file = scope.getSourceFile(); - var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var functionNameText = getUniqueName(file.text); var isJS = ts.isInJavaScriptFile(scope); var functionName = ts.createIdentifier(functionNameText); - var functionReference = ts.createIdentifier(functionNameText); var returnType = undefined; var parameters = []; var callArguments = []; @@ -75018,7 +75006,7 @@ var ts; var contextualType = checker.getContextualType(node); returnType = checker.typeToTypeNode(contextualType); } - var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var _b = transformFunctionBody(node, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty; var newFunction; if (ts.isClassLike(scope)) { var modifiers = isJS ? [] : [ts.createToken(112)]; @@ -75036,7 +75024,8 @@ var ts; var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); var newNodes = []; - var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, undefined, callArguments); + var called = getCalledExpression(scope, range, functionNameText); + var call = ts.createCall(called, undefined, callArguments); if (range.facts & RangeFacts.IsGenerator) { call = ts.createYield(ts.createToken(39), call); } @@ -75086,65 +75075,85 @@ var ts; else { changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); } - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - changes: changeTracker.getChanges() - }; - function getPropertyAssignmentsForWrites(writes) { - return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); - } - function generateReturnValueProperty() { - return "__return"; - } - function transformFunctionBody(body) { - if (ts.isBlock(body) && !writes && substitutions.size === 0) { - return { body: ts.createBlock(body.statements, true), returnValueProperty: undefined }; - } - var returnValueProperty; - var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); - if (writes || substitutions.size) { - var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); - if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { - var assignments = getPropertyAssignmentsForWrites(writes); - if (assignments.length === 1) { - rewrittenStatements.push(ts.createReturn(assignments[0].name)); - } - else { - rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); - } + var edits = changeTracker.getChanges(); + var renameRange = isReadonlyArray(range.range) ? range.range[0] : range.range; + var renameFilename = renameRange.getSourceFile().fileName; + var renameLocation = getRenameLocation(edits, renameFilename, functionNameText); + return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits }; + } + function getRenameLocation(edits, renameFilename, functionNameText) { + var delta = 0; + for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { + var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges; + ts.Debug.assert(fileName === renameFilename); + for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) { + var change = textChanges_2[_b]; + var span_17 = change.span, newText = change.newText; + var index = newText.indexOf(functionNameText); + if (index !== -1) { + return span_17.start + delta + index; } - return { body: ts.createBlock(rewrittenStatements, true), returnValueProperty: returnValueProperty }; + delta += newText.length - span_17.length; } - else { - return { body: ts.createBlock(statements, true), returnValueProperty: undefined }; - } - function visitor(node) { - if (node.kind === 219 && writes) { - var assignments = getPropertyAssignmentsForWrites(writes); - if (node.expression) { - if (!returnValueProperty) { - returnValueProperty = generateReturnValueProperty(); - } - assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); - } - if (assignments.length === 1) { - return ts.createReturn(assignments[0].name); - } - else { - return ts.createReturn(ts.createObjectLiteral(assignments)); + } + throw new Error(); + } + function getCalledExpression(scope, range, functionNameText) { + var functionReference = ts.createIdentifier(functionNameText); + if (ts.isClassLike(scope)) { + var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); + return ts.createPropertyAccess(lhs, functionReference); + } + else { + return functionReference; + } + } + function transformFunctionBody(body, writes, substitutions, hasReturn) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + return { body: ts.createBlock(body.statements, true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !hasReturn && ts.isStatement(body)) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); + } + } + return { body: ts.createBlock(rewrittenStatements, true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = "__return"; } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); } else { - var substitution = substitutions.get(ts.getNodeId(node).toString()); - return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + return ts.createReturn(ts.createObjectLiteral(assignments)); } } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } } } - extractMethod_1.extractFunctionInScope = extractFunctionInScope; - function isModuleBlock(n) { - return n.kind === 234; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); } function isReadonlyArray(v) { return ts.isArray(v); @@ -81209,8 +81218,8 @@ var ts; { start: start, end: end, text: text, code: code, category: category, source: source }; } function allEditsBeforePos(edits, pos) { - for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { - var edit = edits_1[_i]; + for (var _i = 0, edits_2 = edits; _i < edits_2.length; _i++) { + var edit = edits_2[_i]; if (ts.textSpanEnd(edit.span) >= pos) { return false; } @@ -82372,12 +82381,12 @@ var ts; return undefined; } if (simplifiedResult) { - var span_17 = helpItems.applicableSpan; + var span_18 = helpItems.applicableSpan; return { items: helpItems.items, applicableSpan: { - start: scriptInfo.positionToLineOffset(span_17.start), - end: scriptInfo.positionToLineOffset(span_17.start + span_17.length) + start: scriptInfo.positionToLineOffset(span_18.start), + end: scriptInfo.positionToLineOffset(span_18.start + span_18.length) }, selectedItemIndex: helpItems.selectedItemIndex, argumentIndex: helpItems.argumentIndex, diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 457015306006b..4779895cbab5b 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -3283,8 +3283,8 @@ declare namespace ts { }; type RefactorEditInfo = { edits: FileTextChanges[]; - renameFilename?: string; - renameLocation?: number; + renameFilename: string | undefined; + renameLocation: number | undefined; }; interface TextInsertion { newText: string; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index bd74f810fb579..93916b40bffee 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -12155,7 +12155,8 @@ var ts; return token() === 24 || isIdentifierOrPattern() || ts.isModifierKind(token()) || - token() === 57 || isStartOfType(); + token() === 57 || + isStartOfType(true); } function parseParameter() { var node = createNode(146); @@ -12494,7 +12495,7 @@ var ts; return parseTypeReference(); } } - function isStartOfType() { + function isStartOfType(inStartOfParameter) { switch (token()) { case 119: case 136: @@ -12521,9 +12522,9 @@ var ts; case 39: return true; case 38: - return lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19: - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } @@ -74425,7 +74426,9 @@ var ts; deleteCallback(); } return { - edits: changeTracker.getChanges() + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined, }; function deleteNode(node, inList) { if (inList === void 0) { inList = false; } @@ -74576,11 +74579,11 @@ var ts; var usedNames = ts.createMap(); var i = 0; for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { - var extr = extractions_1[_i]; - if (extr.errors && extr.errors.length) { + var _a = extractions_1[_i], scopeDescription = _a.scopeDescription, errors = _a.errors; + if (errors.length) { continue; } - var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [scopeDescription]); if (!usedNames.has(description)) { usedNames.set(description, true); actions.push({ @@ -74608,9 +74611,7 @@ var ts; ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); var index = +parsedIndexMatch[1]; ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); - var extractions = getPossibleExtractions(targetRange, context, index); - ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); - return ({ edits: extractions[0].changes }); + return getExtractionAtIndex(targetRange, context, index); } var Messages; (function (Messages) { @@ -74639,7 +74640,7 @@ var ts; RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; - })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + })(RangeFacts || (RangeFacts = {})); function getRangeToExtract(sourceFile, span) { var length = span.length || 0; var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, false), sourceFile, span); @@ -74879,7 +74880,7 @@ var ts; return undefined; } function isValidExtractionTarget(node) { - return (node.kind === 228) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); + return (node.kind === 228) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node); } function collectEnclosingScopes(range) { var current = isReadonlyArray(range.range) ? ts.firstOrUndefined(range.range) : range.range; @@ -74904,9 +74905,21 @@ var ts; } return scopes; } - extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; - function getPossibleExtractions(targetRange, context, requestedChangesIndex) { - if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + function getExtractionAtIndex(targetRange, context, requestedChangesIndex) { + var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, errorsPerScope = _b.errorsPerScope; + ts.Debug.assert(!errorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + context.cancellationToken.throwIfCancellationRequested(); + return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context); + } + extractMethod_1.getExtractionAtIndex = getExtractionAtIndex; + function getPossibleExtractions(targetRange, context) { + var extractions = getPossibleExtractionsWorker(targetRange, context); + return extractions && extractions.scopes.map(function (scope, i) { + return ({ scopeDescription: getDescriptionForScope(scope), errors: extractions.readsAndWrites.errorsPerScope[i] }); + }); + } + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getPossibleExtractionsWorker(targetRange, context) { var sourceFile = context.file; if (targetRange === undefined) { return undefined; @@ -74916,29 +74929,9 @@ var ts; return undefined; } var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); - var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; - context.cancellationToken.throwIfCancellationRequested(); - if (requestedChangesIndex !== undefined) { - if (errorsPerScope[requestedChangesIndex].length) { - return undefined; - } - return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; - } - else { - return scopes.map(function (scope, i) { - var errors = errorsPerScope[i]; - if (errors.length) { - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - errors: errors - }; - } - return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; - }); - } + var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()); + return { scopes: scopes, readsAndWrites: readsAndWrites }; } - extractMethod_1.getPossibleExtractions = getPossibleExtractions; function getDescriptionForScope(scope) { if (ts.isFunctionLike(scope)) { switch (scope.kind) { @@ -74960,7 +74953,7 @@ var ts; return "'set " + scope.name.getText() + "'"; } } - else if (isModuleBlock(scope)) { + else if (ts.isModuleBlock(scope)) { return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { @@ -74977,14 +74970,10 @@ var ts; return "unknown"; } } - function getUniqueName(isNameOkay) { + function getUniqueName(fileText) { var functionNameText = "newFunction"; - if (isNameOkay(functionNameText)) { - return functionNameText; - } - var i = 1; - while (!isNameOkay(functionNameText = "newFunction_" + i)) { - i++; + for (var i = 1; fileText.indexOf(functionNameText) !== -1; i++) { + functionNameText = "newFunction_" + i; } return functionNameText; } @@ -74992,10 +74981,9 @@ var ts; var usagesInScope = _a.usages, substitutions = _a.substitutions; var checker = context.program.getTypeChecker(); var file = scope.getSourceFile(); - var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var functionNameText = getUniqueName(file.text); var isJS = ts.isInJavaScriptFile(scope); var functionName = ts.createIdentifier(functionNameText); - var functionReference = ts.createIdentifier(functionNameText); var returnType = undefined; var parameters = []; var callArguments = []; @@ -75018,7 +75006,7 @@ var ts; var contextualType = checker.getContextualType(node); returnType = checker.typeToTypeNode(contextualType); } - var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var _b = transformFunctionBody(node, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty; var newFunction; if (ts.isClassLike(scope)) { var modifiers = isJS ? [] : [ts.createToken(112)]; @@ -75036,7 +75024,8 @@ var ts; var changeTracker = ts.textChanges.ChangeTracker.fromCodeFixContext(context); changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); var newNodes = []; - var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, undefined, callArguments); + var called = getCalledExpression(scope, range, functionNameText); + var call = ts.createCall(called, undefined, callArguments); if (range.facts & RangeFacts.IsGenerator) { call = ts.createYield(ts.createToken(39), call); } @@ -75086,65 +75075,85 @@ var ts; else { changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); } - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - changes: changeTracker.getChanges() - }; - function getPropertyAssignmentsForWrites(writes) { - return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); - } - function generateReturnValueProperty() { - return "__return"; - } - function transformFunctionBody(body) { - if (ts.isBlock(body) && !writes && substitutions.size === 0) { - return { body: ts.createBlock(body.statements, true), returnValueProperty: undefined }; - } - var returnValueProperty; - var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); - if (writes || substitutions.size) { - var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); - if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { - var assignments = getPropertyAssignmentsForWrites(writes); - if (assignments.length === 1) { - rewrittenStatements.push(ts.createReturn(assignments[0].name)); - } - else { - rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); - } + var edits = changeTracker.getChanges(); + var renameRange = isReadonlyArray(range.range) ? range.range[0] : range.range; + var renameFilename = renameRange.getSourceFile().fileName; + var renameLocation = getRenameLocation(edits, renameFilename, functionNameText); + return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits }; + } + function getRenameLocation(edits, renameFilename, functionNameText) { + var delta = 0; + for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { + var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges; + ts.Debug.assert(fileName === renameFilename); + for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) { + var change = textChanges_2[_b]; + var span_17 = change.span, newText = change.newText; + var index = newText.indexOf(functionNameText); + if (index !== -1) { + return span_17.start + delta + index; } - return { body: ts.createBlock(rewrittenStatements, true), returnValueProperty: returnValueProperty }; + delta += newText.length - span_17.length; } - else { - return { body: ts.createBlock(statements, true), returnValueProperty: undefined }; - } - function visitor(node) { - if (node.kind === 219 && writes) { - var assignments = getPropertyAssignmentsForWrites(writes); - if (node.expression) { - if (!returnValueProperty) { - returnValueProperty = generateReturnValueProperty(); - } - assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); - } - if (assignments.length === 1) { - return ts.createReturn(assignments[0].name); - } - else { - return ts.createReturn(ts.createObjectLiteral(assignments)); + } + throw new Error(); + } + function getCalledExpression(scope, range, functionNameText) { + var functionReference = ts.createIdentifier(functionNameText); + if (ts.isClassLike(scope)) { + var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); + return ts.createPropertyAccess(lhs, functionReference); + } + else { + return functionReference; + } + } + function transformFunctionBody(body, writes, substitutions, hasReturn) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + return { body: ts.createBlock(body.statements, true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !hasReturn && ts.isStatement(body)) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); + } + } + return { body: ts.createBlock(rewrittenStatements, true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = "__return"; } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); } else { - var substitution = substitutions.get(ts.getNodeId(node).toString()); - return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + return ts.createReturn(ts.createObjectLiteral(assignments)); } } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } } } - extractMethod_1.extractFunctionInScope = extractFunctionInScope; - function isModuleBlock(n) { - return n.kind === 234; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); } function isReadonlyArray(v) { return ts.isArray(v); @@ -77374,8 +77383,8 @@ var ts; { start: start, end: end, text: text, code: code, category: category, source: source }; } function allEditsBeforePos(edits, pos) { - for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { - var edit = edits_1[_i]; + for (var _i = 0, edits_2 = edits; _i < edits_2.length; _i++) { + var edit = edits_2[_i]; if (ts.textSpanEnd(edit.span) >= pos) { return false; } @@ -78537,12 +78546,12 @@ var ts; return undefined; } if (simplifiedResult) { - var span_17 = helpItems.applicableSpan; + var span_18 = helpItems.applicableSpan; return { items: helpItems.items, applicableSpan: { - start: scriptInfo.positionToLineOffset(span_17.start), - end: scriptInfo.positionToLineOffset(span_17.start + span_17.length) + start: scriptInfo.positionToLineOffset(span_18.start), + end: scriptInfo.positionToLineOffset(span_18.start + span_18.length) }, selectedItemIndex: helpItems.selectedItemIndex, argumentIndex: helpItems.argumentIndex, diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index eaf4400c8ee05..4b62e695c8214 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -3935,8 +3935,8 @@ declare namespace ts { */ type RefactorEditInfo = { edits: FileTextChanges[]; - renameFilename?: string; - renameLocation?: number; + renameFilename: string | undefined; + renameLocation: number | undefined; }; interface TextInsertion { newText: string; diff --git a/lib/typescript.js b/lib/typescript.js index 7e2e649341e77..74272714529fd 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -13845,7 +13845,8 @@ var ts; return token() === 24 /* DotDotDotToken */ || isIdentifierOrPattern() || ts.isModifierKind(token()) || - token() === 57 /* AtToken */ || isStartOfType(); + token() === 57 /* AtToken */ || + isStartOfType(/*inStartOfParameter*/ true); } function parseParameter() { var node = createNode(146 /* Parameter */); @@ -14252,7 +14253,7 @@ var ts; return parseTypeReference(); } } - function isStartOfType() { + function isStartOfType(inStartOfParameter) { switch (token()) { case 119 /* AnyKeyword */: case 136 /* StringKeyword */: @@ -14279,11 +14280,11 @@ var ts; case 39 /* AsteriskToken */: return true; case 38 /* MinusToken */: - return lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19 /* OpenParenToken */: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } @@ -89385,7 +89386,9 @@ var ts; deleteCallback(); } return { - edits: changeTracker.getChanges() + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined, }; function deleteNode(node, inList) { if (inList === void 0) { inList = false; } @@ -89561,15 +89564,15 @@ var ts; var usedNames = ts.createMap(); var i = 0; for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { - var extr = extractions_1[_i]; + var _a = extractions_1[_i], scopeDescription = _a.scopeDescription, errors = _a.errors; // Skip these since we don't have a way to report errors yet - if (extr.errors && extr.errors.length) { + if (errors.length) { continue; } // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes - var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [scopeDescription]); if (!usedNames.has(description)) { usedNames.set(description, true); actions.push({ @@ -89599,10 +89602,7 @@ var ts; ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); var index = +parsedIndexMatch[1]; ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); - var extractions = getPossibleExtractions(targetRange, context, index); - // Scope is no longer valid from when the user issued the refactor (??) - ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); - return ({ edits: extractions[0].changes }); + return getExtractionAtIndex(targetRange, context, index); } // Move these into diagnostic messages if they become user-facing var Messages; @@ -89635,13 +89635,14 @@ var ts; * The range is in a function which needs the 'static' modifier in a class */ RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; - })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + })(RangeFacts || (RangeFacts = {})); /** * getRangeToExtract takes a span inside a text file and returns either an expression or an array * of statements representing the minimum set of nodes needed to extract the entire span. This * process may fail, in which case a set of errors is returned instead (these are currently * not shown to the user, but can be used by us diagnostically) */ + // exported only for tests function getRangeToExtract(sourceFile, span) { var length = span.length || 0; // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. @@ -89927,7 +89928,7 @@ var ts; } function isValidExtractionTarget(node) { // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method - return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); + return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node); } /** * Computes possible places we could extract the function into. For example, @@ -89965,14 +89966,29 @@ var ts; } return scopes; } - extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; + // exported only for tests + function getExtractionAtIndex(targetRange, context, requestedChangesIndex) { + var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, errorsPerScope = _b.errorsPerScope; + ts.Debug.assert(!errorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + context.cancellationToken.throwIfCancellationRequested(); + return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context); + } + extractMethod_1.getExtractionAtIndex = getExtractionAtIndex; /** * Given a piece of text to extract ('targetRange'), computes a list of possible extractions. * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes * or an error explaining why we can't extract into that scope. */ - function getPossibleExtractions(targetRange, context, requestedChangesIndex) { - if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + // exported only for tests + function getPossibleExtractions(targetRange, context) { + var extractions = getPossibleExtractionsWorker(targetRange, context); + // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 + return extractions && extractions.scopes.map(function (scope, i) { + return ({ scopeDescription: getDescriptionForScope(scope), errors: extractions.readsAndWrites.errorsPerScope[i] }); + }); + } + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getPossibleExtractionsWorker(targetRange, context) { var sourceFile = context.file; if (targetRange === undefined) { return undefined; @@ -89982,29 +89998,9 @@ var ts; return undefined; } var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); - var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; - context.cancellationToken.throwIfCancellationRequested(); - if (requestedChangesIndex !== undefined) { - if (errorsPerScope[requestedChangesIndex].length) { - return undefined; - } - return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; - } - else { - return scopes.map(function (scope, i) { - var errors = errorsPerScope[i]; - if (errors.length) { - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - errors: errors - }; - } - return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; - }); - } + var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()); + return { scopes: scopes, readsAndWrites: readsAndWrites }; } - extractMethod_1.getPossibleExtractions = getPossibleExtractions; function getDescriptionForScope(scope) { if (ts.isFunctionLike(scope)) { switch (scope.kind) { @@ -90026,7 +90022,7 @@ var ts; return "'set " + scope.name.getText() + "'"; } } - else if (isModuleBlock(scope)) { + else if (ts.isModuleBlock(scope)) { return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { @@ -90043,26 +90039,25 @@ var ts; return "unknown"; } } - function getUniqueName(isNameOkay) { + function getUniqueName(fileText) { var functionNameText = "newFunction"; - if (isNameOkay(functionNameText)) { - return functionNameText; - } - var i = 1; - while (!isNameOkay(functionNameText = "newFunction_" + i)) { - i++; + for (var i = 1; fileText.indexOf(functionNameText) !== -1; i++) { + functionNameText = "newFunction_" + i; } return functionNameText; } + /** + * Result of 'extractRange' operation for a specific scope. + * Stores either a list of changes that should be applied to extract a range or a list of errors + */ function extractFunctionInScope(node, scope, _a, range, context) { var usagesInScope = _a.usages, substitutions = _a.substitutions; var checker = context.program.getTypeChecker(); // Make a unique name for the extracted function var file = scope.getSourceFile(); - var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var functionNameText = getUniqueName(file.text); var isJS = ts.isInJavaScriptFile(scope); var functionName = ts.createIdentifier(functionNameText); - var functionReference = ts.createIdentifier(functionNameText); var returnType = undefined; var parameters = []; var callArguments = []; @@ -90093,7 +90088,7 @@ var ts; var contextualType = checker.getContextualType(node); returnType = checker.typeToTypeNode(contextualType); } - var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var _b = transformFunctionBody(node, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty; var newFunction; if (ts.isClassLike(scope)) { // always create private method in TypeScript files @@ -90119,7 +90114,8 @@ var ts; changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); var newNodes = []; // replace range with function call - var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, + var called = getCalledExpression(scope, range, functionNameText); + var call = ts.createCall(called, /*typeArguments*/ undefined, callArguments); if (range.facts & RangeFacts.IsGenerator) { call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call); @@ -90176,69 +90172,92 @@ var ts; else { changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); } - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - changes: changeTracker.getChanges() - }; - function getPropertyAssignmentsForWrites(writes) { - return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); - } - function generateReturnValueProperty() { - return "__return"; - } - function transformFunctionBody(body) { - if (ts.isBlock(body) && !writes && substitutions.size === 0) { - // already block, no writes to propagate back, no substitutions - can use node as is - return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; - } - var returnValueProperty; - var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); - // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions - if (writes || substitutions.size) { - var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); - if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { - // add return at the end to propagate writes back in case if control flow falls out of the function body - // it is ok to know that range has at least one return since it we only allow unconditional returns - var assignments = getPropertyAssignmentsForWrites(writes); - if (assignments.length === 1) { - rewrittenStatements.push(ts.createReturn(assignments[0].name)); - } - else { - rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); - } + var edits = changeTracker.getChanges(); + var renameRange = isReadonlyArray(range.range) ? range.range[0] : range.range; + var renameFilename = renameRange.getSourceFile().fileName; + var renameLocation = getRenameLocation(edits, renameFilename, functionNameText); + return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits }; + } + function getRenameLocation(edits, renameFilename, functionNameText) { + var delta = 0; + for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { + var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges; + ts.Debug.assert(fileName === renameFilename); + for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) { + var change = textChanges_2[_b]; + var span_17 = change.span, newText = change.newText; + // TODO(acasey): We are assuming that the call expression comes before the function declaration, + // because we want the new cursor to be on the call expression, + // which is closer to where the user was before extracting the function. + var index = newText.indexOf(functionNameText); + if (index !== -1) { + return span_17.start + delta + index; + } + delta += newText.length - span_17.length; + } + } + throw new Error(); // Didn't find the text we inserted? + } + function getCalledExpression(scope, range, functionNameText) { + var functionReference = ts.createIdentifier(functionNameText); + if (ts.isClassLike(scope)) { + var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); + return ts.createPropertyAccess(lhs, functionReference); + } + else { + return functionReference; + } + } + function transformFunctionBody(body, writes, substitutions, hasReturn) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + // already block, no writes to propagate back, no substitutions - can use node as is + return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !hasReturn && ts.isStatement(body)) { + // add return at the end to propagate writes back in case if control flow falls out of the function body + // it is ok to know that range has at least one return since it we only allow unconditional returns + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); } - return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; } - else { - return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; - } - function visitor(node) { - if (node.kind === 219 /* ReturnStatement */ && writes) { - var assignments = getPropertyAssignmentsForWrites(writes); - if (node.expression) { - if (!returnValueProperty) { - returnValueProperty = generateReturnValueProperty(); - } - assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); - } - if (assignments.length === 1) { - return ts.createReturn(assignments[0].name); - } - else { - return ts.createReturn(ts.createObjectLiteral(assignments)); + return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 /* ReturnStatement */ && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = "__return"; } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); } else { - var substitution = substitutions.get(ts.getNodeId(node).toString()); - return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + return ts.createReturn(ts.createObjectLiteral(assignments)); } } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } } } - extractMethod_1.extractFunctionInScope = extractFunctionInScope; - function isModuleBlock(n) { - return n.kind === 234 /* ModuleBlock */; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); } function isReadonlyArray(v) { return ts.isArray(v); diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 825ed9b5c0dee..d5602ea0f78d5 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -3935,8 +3935,8 @@ declare namespace ts { */ type RefactorEditInfo = { edits: FileTextChanges[]; - renameFilename?: string; - renameLocation?: number; + renameFilename: string | undefined; + renameLocation: number | undefined; }; interface TextInsertion { newText: string; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 7e2e649341e77..74272714529fd 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -13845,7 +13845,8 @@ var ts; return token() === 24 /* DotDotDotToken */ || isIdentifierOrPattern() || ts.isModifierKind(token()) || - token() === 57 /* AtToken */ || isStartOfType(); + token() === 57 /* AtToken */ || + isStartOfType(/*inStartOfParameter*/ true); } function parseParameter() { var node = createNode(146 /* Parameter */); @@ -14252,7 +14253,7 @@ var ts; return parseTypeReference(); } } - function isStartOfType() { + function isStartOfType(inStartOfParameter) { switch (token()) { case 119 /* AnyKeyword */: case 136 /* StringKeyword */: @@ -14279,11 +14280,11 @@ var ts; case 39 /* AsteriskToken */: return true; case 38 /* MinusToken */: - return lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19 /* OpenParenToken */: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } @@ -89385,7 +89386,9 @@ var ts; deleteCallback(); } return { - edits: changeTracker.getChanges() + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined, }; function deleteNode(node, inList) { if (inList === void 0) { inList = false; } @@ -89561,15 +89564,15 @@ var ts; var usedNames = ts.createMap(); var i = 0; for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { - var extr = extractions_1[_i]; + var _a = extractions_1[_i], scopeDescription = _a.scopeDescription, errors = _a.errors; // Skip these since we don't have a way to report errors yet - if (extr.errors && extr.errors.length) { + if (errors.length) { continue; } // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes - var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [extr.scopeDescription]); + var description = ts.formatStringFromArgs(ts.Diagnostics.Extract_function_into_0.message, [scopeDescription]); if (!usedNames.has(description)) { usedNames.set(description, true); actions.push({ @@ -89599,10 +89602,7 @@ var ts; ts.Debug.assert(!!parsedIndexMatch, "Scope name should have matched the regexp"); var index = +parsedIndexMatch[1]; ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the scope index"); - var extractions = getPossibleExtractions(targetRange, context, index); - // Scope is no longer valid from when the user issued the refactor (??) - ts.Debug.assert(extractions !== undefined, "The extraction went missing? How?"); - return ({ edits: extractions[0].changes }); + return getExtractionAtIndex(targetRange, context, index); } // Move these into diagnostic messages if they become user-facing var Messages; @@ -89635,13 +89635,14 @@ var ts; * The range is in a function which needs the 'static' modifier in a class */ RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; - })(RangeFacts = extractMethod_1.RangeFacts || (extractMethod_1.RangeFacts = {})); + })(RangeFacts || (RangeFacts = {})); /** * getRangeToExtract takes a span inside a text file and returns either an expression or an array * of statements representing the minimum set of nodes needed to extract the entire span. This * process may fail, in which case a set of errors is returned instead (these are currently * not shown to the user, but can be used by us diagnostically) */ + // exported only for tests function getRangeToExtract(sourceFile, span) { var length = span.length || 0; // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. @@ -89927,7 +89928,7 @@ var ts; } function isValidExtractionTarget(node) { // Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method - return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || isModuleBlock(node) || ts.isClassLike(node); + return (node.kind === 228 /* FunctionDeclaration */) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node); } /** * Computes possible places we could extract the function into. For example, @@ -89965,14 +89966,29 @@ var ts; } return scopes; } - extractMethod_1.collectEnclosingScopes = collectEnclosingScopes; + // exported only for tests + function getExtractionAtIndex(targetRange, context, requestedChangesIndex) { + var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, errorsPerScope = _b.errorsPerScope; + ts.Debug.assert(!errorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + context.cancellationToken.throwIfCancellationRequested(); + return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context); + } + extractMethod_1.getExtractionAtIndex = getExtractionAtIndex; /** * Given a piece of text to extract ('targetRange'), computes a list of possible extractions. * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes * or an error explaining why we can't extract into that scope. */ - function getPossibleExtractions(targetRange, context, requestedChangesIndex) { - if (requestedChangesIndex === void 0) { requestedChangesIndex = undefined; } + // exported only for tests + function getPossibleExtractions(targetRange, context) { + var extractions = getPossibleExtractionsWorker(targetRange, context); + // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 + return extractions && extractions.scopes.map(function (scope, i) { + return ({ scopeDescription: getDescriptionForScope(scope), errors: extractions.readsAndWrites.errorsPerScope[i] }); + }); + } + extractMethod_1.getPossibleExtractions = getPossibleExtractions; + function getPossibleExtractionsWorker(targetRange, context) { var sourceFile = context.file; if (targetRange === undefined) { return undefined; @@ -89982,29 +89998,9 @@ var ts; return undefined; } var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); - var _a = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()), target = _a.target, usagesPerScope = _a.usagesPerScope, errorsPerScope = _a.errorsPerScope; - context.cancellationToken.throwIfCancellationRequested(); - if (requestedChangesIndex !== undefined) { - if (errorsPerScope[requestedChangesIndex].length) { - return undefined; - } - return [extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context)]; - } - else { - return scopes.map(function (scope, i) { - var errors = errorsPerScope[i]; - if (errors.length) { - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - errors: errors - }; - } - return { scope: scope, scopeDescription: getDescriptionForScope(scope) }; - }); - } + var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker()); + return { scopes: scopes, readsAndWrites: readsAndWrites }; } - extractMethod_1.getPossibleExtractions = getPossibleExtractions; function getDescriptionForScope(scope) { if (ts.isFunctionLike(scope)) { switch (scope.kind) { @@ -90026,7 +90022,7 @@ var ts; return "'set " + scope.name.getText() + "'"; } } - else if (isModuleBlock(scope)) { + else if (ts.isModuleBlock(scope)) { return "namespace '" + scope.parent.name.getText() + "'"; } else if (ts.isClassLike(scope)) { @@ -90043,26 +90039,25 @@ var ts; return "unknown"; } } - function getUniqueName(isNameOkay) { + function getUniqueName(fileText) { var functionNameText = "newFunction"; - if (isNameOkay(functionNameText)) { - return functionNameText; - } - var i = 1; - while (!isNameOkay(functionNameText = "newFunction_" + i)) { - i++; + for (var i = 1; fileText.indexOf(functionNameText) !== -1; i++) { + functionNameText = "newFunction_" + i; } return functionNameText; } + /** + * Result of 'extractRange' operation for a specific scope. + * Stores either a list of changes that should be applied to extract a range or a list of errors + */ function extractFunctionInScope(node, scope, _a, range, context) { var usagesInScope = _a.usages, substitutions = _a.substitutions; var checker = context.program.getTypeChecker(); // Make a unique name for the extracted function var file = scope.getSourceFile(); - var functionNameText = getUniqueName(function (n) { return !file.identifiers.has(n); }); + var functionNameText = getUniqueName(file.text); var isJS = ts.isInJavaScriptFile(scope); var functionName = ts.createIdentifier(functionNameText); - var functionReference = ts.createIdentifier(functionNameText); var returnType = undefined; var parameters = []; var callArguments = []; @@ -90093,7 +90088,7 @@ var ts; var contextualType = checker.getContextualType(node); returnType = checker.typeToTypeNode(contextualType); } - var _b = transformFunctionBody(node), body = _b.body, returnValueProperty = _b.returnValueProperty; + var _b = transformFunctionBody(node, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty; var newFunction; if (ts.isClassLike(scope)) { // always create private method in TypeScript files @@ -90119,7 +90114,8 @@ var ts; changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); var newNodes = []; // replace range with function call - var call = ts.createCall(ts.isClassLike(scope) ? ts.createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), functionReference) : functionReference, + var called = getCalledExpression(scope, range, functionNameText); + var call = ts.createCall(called, /*typeArguments*/ undefined, callArguments); if (range.facts & RangeFacts.IsGenerator) { call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call); @@ -90176,69 +90172,92 @@ var ts; else { changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); } - return { - scope: scope, - scopeDescription: getDescriptionForScope(scope), - changes: changeTracker.getChanges() - }; - function getPropertyAssignmentsForWrites(writes) { - return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); - } - function generateReturnValueProperty() { - return "__return"; - } - function transformFunctionBody(body) { - if (ts.isBlock(body) && !writes && substitutions.size === 0) { - // already block, no writes to propagate back, no substitutions - can use node as is - return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; - } - var returnValueProperty; - var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); - // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions - if (writes || substitutions.size) { - var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); - if (writes && !(range.facts & RangeFacts.HasReturn) && ts.isStatement(body)) { - // add return at the end to propagate writes back in case if control flow falls out of the function body - // it is ok to know that range has at least one return since it we only allow unconditional returns - var assignments = getPropertyAssignmentsForWrites(writes); - if (assignments.length === 1) { - rewrittenStatements.push(ts.createReturn(assignments[0].name)); - } - else { - rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); - } + var edits = changeTracker.getChanges(); + var renameRange = isReadonlyArray(range.range) ? range.range[0] : range.range; + var renameFilename = renameRange.getSourceFile().fileName; + var renameLocation = getRenameLocation(edits, renameFilename, functionNameText); + return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits }; + } + function getRenameLocation(edits, renameFilename, functionNameText) { + var delta = 0; + for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { + var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges; + ts.Debug.assert(fileName === renameFilename); + for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) { + var change = textChanges_2[_b]; + var span_17 = change.span, newText = change.newText; + // TODO(acasey): We are assuming that the call expression comes before the function declaration, + // because we want the new cursor to be on the call expression, + // which is closer to where the user was before extracting the function. + var index = newText.indexOf(functionNameText); + if (index !== -1) { + return span_17.start + delta + index; + } + delta += newText.length - span_17.length; + } + } + throw new Error(); // Didn't find the text we inserted? + } + function getCalledExpression(scope, range, functionNameText) { + var functionReference = ts.createIdentifier(functionNameText); + if (ts.isClassLike(scope)) { + var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); + return ts.createPropertyAccess(lhs, functionReference); + } + else { + return functionReference; + } + } + function transformFunctionBody(body, writes, substitutions, hasReturn) { + if (ts.isBlock(body) && !writes && substitutions.size === 0) { + // already block, no writes to propagate back, no substitutions - can use node as is + return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + } + var returnValueProperty; + var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); + // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions + if (writes || substitutions.size) { + var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (writes && !hasReturn && ts.isStatement(body)) { + // add return at the end to propagate writes back in case if control flow falls out of the function body + // it is ok to know that range has at least one return since it we only allow unconditional returns + var assignments = getPropertyAssignmentsForWrites(writes); + if (assignments.length === 1) { + rewrittenStatements.push(ts.createReturn(assignments[0].name)); + } + else { + rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); } - return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; } - else { - return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; - } - function visitor(node) { - if (node.kind === 219 /* ReturnStatement */ && writes) { - var assignments = getPropertyAssignmentsForWrites(writes); - if (node.expression) { - if (!returnValueProperty) { - returnValueProperty = generateReturnValueProperty(); - } - assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); - } - if (assignments.length === 1) { - return ts.createReturn(assignments[0].name); - } - else { - return ts.createReturn(ts.createObjectLiteral(assignments)); + return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; + } + else { + return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + } + function visitor(node) { + if (node.kind === 219 /* ReturnStatement */ && writes) { + var assignments = getPropertyAssignmentsForWrites(writes); + if (node.expression) { + if (!returnValueProperty) { + returnValueProperty = "__return"; } + assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); + } + if (assignments.length === 1) { + return ts.createReturn(assignments[0].name); } else { - var substitution = substitutions.get(ts.getNodeId(node).toString()); - return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + return ts.createReturn(ts.createObjectLiteral(assignments)); } } + else { + var substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution || ts.visitEachChild(node, visitor, ts.nullTransformationContext); + } } } - extractMethod_1.extractFunctionInScope = extractFunctionInScope; - function isModuleBlock(n) { - return n.kind === 234 /* ModuleBlock */; + function getPropertyAssignmentsForWrites(writes) { + return writes.map(function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); } function isReadonlyArray(v) { return ts.isArray(v); diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 2da644fe8b8e4..2c2ccfdcf1f97 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -11098,7 +11098,8 @@ var ts; return token() === 24 || isIdentifierOrPattern() || ts.isModifierKind(token()) || - token() === 57 || isStartOfType(); + token() === 57 || + isStartOfType(true); } function parseParameter() { var node = createNode(146); @@ -11437,7 +11438,7 @@ var ts; return parseTypeReference(); } } - function isStartOfType() { + function isStartOfType(inStartOfParameter) { switch (token()) { case 119: case 136: @@ -11464,9 +11465,9 @@ var ts; case 39: return true; case 38: - return lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19: - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } From 319bc2b3186a1b2b79e40926d7122b49b5f7a19e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 7 Sep 2017 16:22:16 -0700 Subject: [PATCH 46/60] Test: parsing of two-line @typedef jsdoc --- tests/baselines/reference/jsdocTwoLineTypedef.js | 10 ++++++++++ tests/baselines/reference/jsdocTwoLineTypedef.symbols | 9 +++++++++ tests/baselines/reference/jsdocTwoLineTypedef.types | 9 +++++++++ tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts | 6 ++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/baselines/reference/jsdocTwoLineTypedef.js create mode 100644 tests/baselines/reference/jsdocTwoLineTypedef.symbols create mode 100644 tests/baselines/reference/jsdocTwoLineTypedef.types create mode 100644 tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts diff --git a/tests/baselines/reference/jsdocTwoLineTypedef.js b/tests/baselines/reference/jsdocTwoLineTypedef.js new file mode 100644 index 0000000000000..b48d6a89a2154 --- /dev/null +++ b/tests/baselines/reference/jsdocTwoLineTypedef.js @@ -0,0 +1,10 @@ +//// [jsdocTwoLineTypedef.ts] +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; + + +//// [jsdocTwoLineTypedef.js] diff --git a/tests/baselines/reference/jsdocTwoLineTypedef.symbols b/tests/baselines/reference/jsdocTwoLineTypedef.symbols new file mode 100644 index 0000000000000..80a69e5f52cff --- /dev/null +++ b/tests/baselines/reference/jsdocTwoLineTypedef.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts === +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; +>LoadCallback : Symbol(LoadCallback, Decl(jsdocTwoLineTypedef.ts, 0, 0)) + diff --git a/tests/baselines/reference/jsdocTwoLineTypedef.types b/tests/baselines/reference/jsdocTwoLineTypedef.types new file mode 100644 index 0000000000000..5e0d05b3feb2e --- /dev/null +++ b/tests/baselines/reference/jsdocTwoLineTypedef.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts === +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; +>LoadCallback : void + diff --git a/tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts b/tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts new file mode 100644 index 0000000000000..2a7ad0d7dbfca --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTwoLineTypedef.ts @@ -0,0 +1,6 @@ +// Regression from #18301 +/** + * @typedef LoadCallback + * @type {function} + */ +type LoadCallback = void; From 745dd6a2357b372ef1d85f86b3ab3ca3fe877706 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 7 Sep 2017 16:37:13 -0700 Subject: [PATCH 47/60] Fix forEachChild's visit of JSDocTypedefTag Also remove JSDocTypeLiteral.jsdocTypeTag, which made no sense since it was only useful when storing information for its parent `@typedef` tag. --- src/compiler/parser.ts | 16 +++++++++------- src/compiler/types.ts | 1 - 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c47f8cd2ba451..635f6b2a36ada 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -438,8 +438,10 @@ namespace ts { visitNode(cbNode, (node).typeExpression); } case SyntaxKind.JSDocTypeLiteral: - for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) { - visitNode(cbNode, tag); + if ((node as JSDocTypeLiteral).jsDocPropertyTags) { + for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) { + visitNode(cbNode, tag); + } } return; case SyntaxKind.PartiallyEmittedExpression: @@ -6667,19 +6669,18 @@ namespace ts { if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { let child: JSDocTypeTag | JSDocPropertyTag | false; let jsdocTypeLiteral: JSDocTypeLiteral; - let alreadyHasTypeTag = false; + let childTypeTag: JSDocTypeTag; const start = scanner.getStartPos(); while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Property))) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); } if (child.kind === SyntaxKind.JSDocTypeTag) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -6693,7 +6694,8 @@ namespace ts { if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + const useChildTypeTagAsType = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type); + typedefTag.typeExpression = useChildTypeTagAsType ? childTypeTag.typeExpression : finishNode(jsdocTypeLiteral); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1deef10a6138b..9243a15b4f2f0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2150,7 +2150,6 @@ namespace ts { export interface JSDocTypeLiteral extends JSDocType { kind: SyntaxKind.JSDocTypeLiteral; jsDocPropertyTags?: ReadonlyArray; - jsDocTypeTag?: JSDocTypeTag; /** If true, then this type literal represents an *array* of its type. */ isArrayType?: boolean; } From de413a485d3cac0fd55c94f9e4d2db2a36395955 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 7 Sep 2017 16:38:17 -0700 Subject: [PATCH 48/60] Update baselines --- ...sCorrectly.typedefTagWithChildrenTags.json | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index f0e42ae632553..08d270286b9fb 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -34,38 +34,6 @@ "kind": "JSDocTypeLiteral", "pos": 26, "end": 98, - "jsDocTypeTag": { - "kind": "JSDocTypeTag", - "pos": 28, - "end": 42, - "atToken": { - "kind": "AtToken", - "pos": 28, - "end": 29 - }, - "tagName": { - "kind": "Identifier", - "pos": 29, - "end": 33, - "escapedText": "type" - }, - "typeExpression": { - "kind": "JSDocTypeExpression", - "pos": 34, - "end": 42, - "type": { - "kind": "TypeReference", - "pos": 35, - "end": 41, - "typeName": { - "kind": "Identifier", - "pos": 35, - "end": 41, - "escapedText": "Object" - } - } - } - }, "jsDocPropertyTags": [ { "kind": "JSDocPropertyTag", From 8b26919a5bc29503c92c1130e8cbd3ceb64057ad Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 8 Sep 2017 08:33:17 -0700 Subject: [PATCH 49/60] Inline variable to aid control flow --- src/compiler/parser.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 635f6b2a36ada..b905c3e609f60 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6694,8 +6694,9 @@ namespace ts { if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) { jsdocTypeLiteral.isArrayType = true; } - const useChildTypeTagAsType = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type); - typedefTag.typeExpression = useChildTypeTagAsType ? childTypeTag.typeExpression : finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } From 9a5ddc03e8350f760eedf28b7c97fe4d84f9e4e9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 2 Sep 2017 10:27:48 -0700 Subject: [PATCH 50/60] Improved caching scheme for anonymous types --- src/compiler/checker.ts | 281 +++++++++++++--------------------- src/compiler/types.ts | 5 +- src/services/signatureHelp.ts | 2 +- 3 files changed, 107 insertions(+), 181 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e2668c2fa68a7..704e50ee22b1d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4788,22 +4788,39 @@ namespace ts { return typeParameters; } - // Appends the outer type parameters of a node to a set of type parameters and returns the resulting set. The function - // allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set in-place and - // returns the same array. - function appendOuterTypeParameters(typeParameters: TypeParameter[], node: Node): TypeParameter[] { + // Return the outer type parameters of a node or undefined if the node has no outer type parameters. + function getOuterTypeParameters(node: Node, includeThisTypes?: boolean): TypeParameter[] { while (true) { node = node.parent; if (!node) { - return typeParameters; + return undefined; } - if (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || - node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.ArrowFunction) { - const declarations = (node).typeParameters; - if (declarations) { - return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); - } + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.MethodSignature: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.JSDocFunctionType: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.JSDocTemplateTag: + case SyntaxKind.MappedType: + const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); + if (node.kind === SyntaxKind.MappedType) { + return append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node).typeParameter))); + } + const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(node) || emptyArray); + const thisType = includeThisTypes && + (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; + return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } @@ -4811,7 +4828,7 @@ namespace ts { // The outer type parameters are those defined by enclosing generic classes, methods, or functions. function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] { const declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration); - return appendOuterTypeParameters(/*typeParameters*/ undefined, declaration); + return getOuterTypeParameters(declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, @@ -6799,7 +6816,7 @@ namespace ts { const id = getTypeListId(typeArguments); let instantiation = links.instantiations.get(id); if (!instantiation) { - links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); + links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); } return instantiation; } @@ -8034,11 +8051,6 @@ namespace ts { return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateCached(type: T, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T { - const instantiations = mapper.instantiations || (mapper.instantiations = []); - return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); - } - function makeUnaryTypeMapper(source: Type, target: Type) { return (t: Type) => t === source ? target : t; } @@ -8060,11 +8072,9 @@ namespace ts { function createTypeMapper(sources: TypeParameter[], targets: Type[]): TypeMapper { Debug.assert(targets === undefined || sources.length === targets.length); - const mapper: TypeMapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : + return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : - makeArrayTypeMapper(sources, targets); - mapper.mappedTypes = sources; - return mapper; + makeArrayTypeMapper(sources, targets); } function createTypeEraser(sources: TypeParameter[]): TypeMapper { @@ -8075,10 +8085,8 @@ namespace ts { * Maps forward-references to later types parameters to the empty object type. * This is used during inference when instantiating type parameter defaults. */ - function createBackreferenceMapper(typeParameters: TypeParameter[], index: number) { - const mapper: TypeMapper = t => indexOf(typeParameters, t) >= index ? emptyObjectType : t; - mapper.mappedTypes = typeParameters; - return mapper; + function createBackreferenceMapper(typeParameters: TypeParameter[], index: number): TypeMapper { + return t => indexOf(typeParameters, t) >= index ? emptyObjectType : t; } function isInferenceContext(mapper: TypeMapper): mapper is InferenceContext { @@ -8096,15 +8104,11 @@ namespace ts { } function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper): TypeMapper { - const mapper: TypeMapper = t => instantiateType(mapper1(t), mapper2); - mapper.mappedTypes = concatenate(mapper1.mappedTypes, mapper2.mappedTypes); - return mapper; + return t => instantiateType(mapper1(t), mapper2); } - function createReplacementMapper(source: Type, target: Type, baseMapper: TypeMapper) { - const mapper: TypeMapper = t => t === source ? target : baseMapper(t); - mapper.mappedTypes = baseMapper.mappedTypes; - return mapper; + function createReplacementMapper(source: Type, target: Type, baseMapper: TypeMapper): TypeMapper { + return t => t === source ? target : baseMapper(t); } function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter { @@ -8181,13 +8185,39 @@ namespace ts { return result; } - function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType { - const result = createObjectType(ObjectFlags.Anonymous | ObjectFlags.Instantiated, type.symbol); - result.target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type; - result.mapper = type.objectFlags & ObjectFlags.Instantiated ? combineTypeMappers(type.mapper, mapper) : mapper; - result.aliasSymbol = type.aliasSymbol; - result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); - return result; + function getAnonymousTypeInstantiation(type: AnonymousType, mapper: TypeMapper) { + if (type.objectFlags & ObjectFlags.Instantiated) { + mapper = combineTypeMappers(type.mapper, mapper); + type = type.target; + } + const symbol = type.symbol; + const links = getSymbolLinks(symbol); + if (!links.typeParameters) { + // This first time an anonymous type is instantiated we compute and store a list of the type + // parameters that are in scope (and therefore potentially referenced). + const typeParameters = getOuterTypeParameters(symbol.declarations[0], /*includeThisTypes*/ true); + links.typeParameters = typeParameters || emptyArray; + if (typeParameters) { + links.instantiations = createMap(); + links.instantiations.set(getTypeListId(typeParameters), type); + } + } + const typeParameters = links.typeParameters; + if (typeParameters.length) { + // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the + // mapper to the type parameters to produce the effective list of type arguments, and compute the + // instantiation cache key from the type IDs of the type arguments. + const typeArguments = map(typeParameters, mapper); + const id = getTypeListId(typeArguments); + let result = links.instantiations.get(id); + if (!result) { + const newMapper = createTypeMapper(typeParameters, typeArguments); + result = type.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(type, newMapper) : instantiateAnonymousType(type, newMapper); + links.instantiations.set(id, result); + } + return result; + } + return type; } function instantiateMappedType(type: MappedType, mapper: TypeMapper): Type { @@ -8204,164 +8234,64 @@ namespace ts { if (typeVariable !== mappedTypeVariable) { return mapType(mappedTypeVariable, t => { if (isMappableType(t)) { - return instantiateMappedObjectType(type, createReplacementMapper(typeVariable, t, mapper)); + return instantiateAnonymousType(type, createReplacementMapper(typeVariable, t, mapper)); } return t; }); } } } - return instantiateMappedObjectType(type, mapper); + return instantiateAnonymousType(type, mapper); } function isMappableType(type: Type) { return type.flags & (TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.Intersection | TypeFlags.IndexedAccess); } - function instantiateMappedObjectType(type: MappedType, mapper: TypeMapper): Type { - const result = createObjectType(ObjectFlags.Mapped | ObjectFlags.Instantiated, type.symbol); - result.declaration = type.declaration; - result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType { + const result = createObjectType(type.objectFlags | ObjectFlags.Instantiated, type.symbol); + if (type.objectFlags & ObjectFlags.Mapped) { + (result).declaration = (type).declaration; + } + result.target = type; + result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } - function isSymbolInScopeOfMappedTypeParameter(symbol: Symbol, mapper: TypeMapper) { - if (!(symbol.declarations && symbol.declarations.length)) { - return false; - } - const mappedTypes = mapper.mappedTypes; - // Starting with the parent of the symbol's declaration, check if the mapper maps any of - // the type parameters introduced by enclosing declarations. We just pick the first - // declaration since multiple declarations will all have the same parent anyway. - return !!findAncestor(symbol.declarations[0], node => { - if (node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile) { - return "quit"; - } - switch (node.kind) { - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - const typeParameters = getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters); - if (typeParameters) { - for (const d of typeParameters) { - if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { - return true; - } - } - } - if (isClassLike(node) || node.kind === SyntaxKind.InterfaceDeclaration) { - const thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; - if (thisType && contains(mappedTypes, thisType)) { - return true; - } - } - break; - case SyntaxKind.MappedType: - if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node).typeParameter)))) { - return true; - } - break; - case SyntaxKind.JSDocFunctionType: - const func = node as JSDocFunctionType; - for (const p of func.parameters) { - if (contains(mappedTypes, getTypeOfNode(p))) { - return true; - } - } - break; - } - }); - } - - function isTopLevelTypeAlias(symbol: Symbol) { - if (symbol.declarations && symbol.declarations.length) { - const parentKind = symbol.declarations[0].parent.kind; - return parentKind === SyntaxKind.SourceFile || parentKind === SyntaxKind.ModuleBlock; - } - return false; - } - function instantiateType(type: Type, mapper: TypeMapper): Type { if (type && mapper !== identityMapper) { - // If we are instantiating a type that has a top-level type alias, obtain the instantiation through - // the type alias instead in order to share instantiations for the same type arguments. This can - // dramatically reduce the number of structurally identical types we generate. Note that we can only - // perform this optimization for top-level type aliases. Consider: - // - // function f1(x: T) { - // type Foo = { x: X, t: T }; - // let obj: Foo = { x: x }; - // return obj; - // } - // function f2(x: U) { return f1(x); } - // let z = f2(42); - // - // Above, the declaration of f2 has an inferred return type that is an instantiation of f1's Foo - // equivalent to { x: U, t: U }. When instantiating this return type, we can't go back to Foo's - // cache because all cached instantiations are of the form { x: ???, t: T }, i.e. they have not been - // instantiated for T. Instead, we need to further instantiate the { x: U, t: U } form. - if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) { - if (type.aliasTypeArguments) { - return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); + if (type.flags & TypeFlags.TypeParameter) { + return mapper(type); + } + if (type.flags & TypeFlags.Object) { + if ((type).objectFlags & ObjectFlags.Anonymous) { + // If the anonymous type originates in a declaration of a function, method, class, or + // interface, in an object type literal, or in an object literal expression, we may need + // to instantiate the type because it might reference a type parameter. + return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ? + getAnonymousTypeInstantiation(type, mapper) : type; + } + if ((type).objectFlags & ObjectFlags.Mapped) { + return getAnonymousTypeInstantiation(type, mapper); + } + if ((type).objectFlags & ObjectFlags.Reference) { + return createTypeReference((type).target, instantiateTypes((type).typeArguments, mapper)); } - return type; } - return instantiateTypeNoAlias(type, mapper); - } - return type; - } - - function instantiateTypeNoAlias(type: Type, mapper: TypeMapper): Type { - if (type.flags & TypeFlags.TypeParameter) { - return mapper(type); - } - if (type.flags & TypeFlags.Object) { - if ((type).objectFlags & ObjectFlags.Anonymous) { - // If the anonymous type originates in a declaration of a function, method, class, or - // interface, in an object type literal, or in an object literal expression, we may need - // to instantiate the type because it might reference a type parameter. We skip instantiation - // if none of the type parameters that are in scope in the type's declaration are mapped by - // the given mapper, however we can only do that analysis if the type isn't itself an - // instantiation. - return type.symbol && - type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && - ((type).objectFlags & ObjectFlags.Instantiated || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateCached(type, mapper, instantiateAnonymousType) : type; + if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) { + return getUnionType(instantiateTypes((type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if ((type).objectFlags & ObjectFlags.Mapped) { - return instantiateCached(type, mapper, instantiateMappedType); + if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(instantiateTypes((type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if ((type).objectFlags & ObjectFlags.Reference) { - return createTypeReference((type).target, instantiateTypes((type).typeArguments, mapper)); + if (type.flags & TypeFlags.Index) { + return getIndexType(instantiateType((type).type, mapper)); + } + if (type.flags & TypeFlags.IndexedAccess) { + return getIndexedAccessType(instantiateType((type).objectType, mapper), instantiateType((type).indexType, mapper)); } - } - if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) { - return getUnionType(instantiateTypes((type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(instantiateTypes((type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & TypeFlags.Index) { - return getIndexType(instantiateType((type).type, mapper)); - } - if (type.flags & TypeFlags.IndexedAccess) { - return getIndexedAccessType(instantiateType((type).objectType, mapper), instantiateType((type).indexType, mapper)); } return type; } @@ -10356,7 +10286,6 @@ namespace ts { function createInferenceContext(signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext { const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo); const context = mapper as InferenceContext; - context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9243a15b4f2f0..440417db11240 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3295,13 +3295,12 @@ namespace ts { } /* @internal */ - export interface MappedType extends ObjectType { + export interface MappedType extends AnonymousType { declaration: MappedTypeNode; typeParameter?: TypeParameter; constraintType?: Type; templateType?: Type; modifiersType?: Type; - mapper?: TypeMapper; // Instantiation mapper } export interface EvolvingArrayType extends ObjectType { @@ -3432,8 +3431,6 @@ namespace ts { /* @internal */ export interface TypeMapper { (t: TypeParameter): Type; - mappedTypes?: TypeParameter[]; // Types mapped by this mapper - instantiations?: Type[]; // Cache of instantiations created using this type mapper. } export const enum InferencePriority { diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 2976b0d28ee97..10d5dda7966fb 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -373,7 +373,7 @@ namespace ts.SignatureHelp { isVariadic = false; // type parameter lists are not variadic prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken)); // Use `.mapper` to ensure we get the generic type arguments even if this is an instantiated version of the signature. - const typeParameters = candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; + const typeParameters = candidateSignature.typeParameters; // !!! candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); const parameterParts = mapToDisplayParts(writer => From 51695422c20c019e5503bfd328a19357fe4e7922 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 2 Sep 2017 15:39:14 -0700 Subject: [PATCH 51/60] Fix signature help --- src/services/signatureHelp.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 10d5dda7966fb..7e8e748bb172d 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -372,8 +372,7 @@ namespace ts.SignatureHelp { if (isTypeParameterList) { isVariadic = false; // type parameter lists are not variadic prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken)); - // Use `.mapper` to ensure we get the generic type arguments even if this is an instantiated version of the signature. - const typeParameters = candidateSignature.typeParameters; // !!! candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; + const typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); const parameterParts = mapToDisplayParts(writer => From 9711d66668da47d679b7aeb75b89e8fdd6aaccb3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Sep 2017 08:53:04 -0700 Subject: [PATCH 52/60] Optimize caching of type literals --- src/compiler/checker.ts | 46 +++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 704e50ee22b1d..f4d19330ac41d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8186,33 +8186,37 @@ namespace ts { } function getAnonymousTypeInstantiation(type: AnonymousType, mapper: TypeMapper) { - if (type.objectFlags & ObjectFlags.Instantiated) { - mapper = combineTypeMappers(type.mapper, mapper); - type = type.target; - } - const symbol = type.symbol; + const target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type; + const symbol = target.symbol; const links = getSymbolLinks(symbol); - if (!links.typeParameters) { - // This first time an anonymous type is instantiated we compute and store a list of the type - // parameters that are in scope (and therefore potentially referenced). - const typeParameters = getOuterTypeParameters(symbol.declarations[0], /*includeThisTypes*/ true); - links.typeParameters = typeParameters || emptyArray; - if (typeParameters) { + let typeParameters = links.typeParameters; + if (!typeParameters) { + // The first time an anonymous type is instantiated we compute and store a list of the type + // parameters that are in scope (and therefore potentially referenced). For type literals that + // aren't the right hand side of a generic type alias declaration we optimize by reducing the + // set of type parameters to those that are actually referenced somewhere in the literal. + const declaration = symbol.declarations[0]; + const outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true) || emptyArray; + typeParameters = symbol.flags & SymbolFlags.TypeLiteral && !target.aliasTypeArguments ? + filter(outerTypeParameters, tp => isTypeParameterReferencedWithin(tp, declaration)) : + outerTypeParameters; + links.typeParameters = typeParameters; + if (typeParameters.length) { links.instantiations = createMap(); - links.instantiations.set(getTypeListId(typeParameters), type); + links.instantiations.set(getTypeListId(typeParameters), target); } } - const typeParameters = links.typeParameters; if (typeParameters.length) { // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the // mapper to the type parameters to produce the effective list of type arguments, and compute the // instantiation cache key from the type IDs of the type arguments. - const typeArguments = map(typeParameters, mapper); + const combinedMapper = type.objectFlags & ObjectFlags.Instantiated ? combineTypeMappers(type.mapper, mapper) : mapper; + const typeArguments = map(typeParameters, combinedMapper); const id = getTypeListId(typeArguments); let result = links.instantiations.get(id); if (!result) { const newMapper = createTypeMapper(typeParameters, typeArguments); - result = type.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(type, newMapper) : instantiateAnonymousType(type, newMapper); + result = target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); links.instantiations.set(id, result); } return result; @@ -8220,6 +8224,16 @@ namespace ts { return type; } + function isTypeParameterReferencedWithin(tp: TypeParameter, node: Node) { + return tp.isThisType ? forEachChild(node, checkThis) : forEachChild(node, checkIdentifier); + function checkThis(node: Node): boolean { + return node.kind === SyntaxKind.ThisType || forEachChild(node, checkThis); + } + function checkIdentifier(node: Node): boolean { + return node.kind === SyntaxKind.Identifier && isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || forEachChild(node, checkIdentifier); + } + } + function instantiateMappedType(type: MappedType, mapper: TypeMapper): Type { // Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some // type variable T. If so, the mapped type is distributive over a union type and when T is instantiated @@ -10408,6 +10422,7 @@ namespace ts { function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; + //sys.write(typeToString(originalSource) + " ==> " + typeToString(originalTarget) + "\n"); inferFromTypes(originalSource, originalTarget); function inferFromTypes(source: Type, target: Type) { @@ -10475,6 +10490,7 @@ namespace ts { const inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { + //sys.write(" " + typeToString(source) + "\n"); if (!inference.candidates || priority < inference.priority) { inference.candidates = [source]; inference.priority = priority; From ee7e77ad222e74505569a6847160250e99e9731a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Sep 2017 08:53:19 -0700 Subject: [PATCH 53/60] Accept new baselines --- .../reference/functionConstraintSatisfaction2.errors.txt | 4 ---- tests/baselines/reference/limitDeepInstantiations.errors.txt | 4 ++-- tests/baselines/reference/promisePermutations.errors.txt | 2 -- tests/baselines/reference/promisePermutations2.errors.txt | 2 -- tests/baselines/reference/promisePermutations3.errors.txt | 2 -- 5 files changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt b/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt index f87312634f82f..7558a97511fc6 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt +++ b/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt @@ -22,8 +22,6 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstrain Type 'void' is not assignable to type 'string'. tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts(38,10): error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'. Type 'T' is not assignable to type '(x: string) => string'. - Type '() => void' is not assignable to type '(x: string) => string'. - Type 'void' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstraintSatisfaction2.ts (13 errors) ==== @@ -102,7 +100,5 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/functionConstrain ~ !!! error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'. !!! error TS2345: Type 'T' is not assignable to type '(x: string) => string'. -!!! error TS2345: Type '() => void' is not assignable to type '(x: string) => string'. -!!! error TS2345: Type 'void' is not assignable to type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/limitDeepInstantiations.errors.txt b/tests/baselines/reference/limitDeepInstantiations.errors.txt index 330e5fbc8e43e..70718199d2bdf 100644 --- a/tests/baselines/reference/limitDeepInstantiations.errors.txt +++ b/tests/baselines/reference/limitDeepInstantiations.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/limitDeepInstantiations.ts(3,35): error TS2550: Generic type instantiation is excessively deep and possibly infinite. +tests/cases/compiler/limitDeepInstantiations.ts(3,35): error TS2502: '"true"' is referenced directly or indirectly in its own type annotation. tests/cases/compiler/limitDeepInstantiations.ts(5,13): error TS2344: Type '"false"' does not satisfy the constraint '"true"'. @@ -7,7 +7,7 @@ tests/cases/compiler/limitDeepInstantiations.ts(5,13): error TS2344: Type '"fals type Foo = { "true": Foo> }[T]; ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2550: Generic type instantiation is excessively deep and possibly infinite. +!!! error TS2502: '"true"' is referenced directly or indirectly in its own type annotation. let f1: Foo<"true", {}>; let f2: Foo<"false", {}>; ~~~~~~~ diff --git a/tests/baselines/reference/promisePermutations.errors.txt b/tests/baselines/reference/promisePermutations.errors.txt index a876345ffa100..c5527d5aa6745 100644 --- a/tests/baselines/reference/promisePermutations.errors.txt +++ b/tests/baselines/reference/promisePermutations.errors.txt @@ -45,7 +45,6 @@ tests/cases/compiler/promisePermutations.ts(134,19): error TS2345: Argument of t tests/cases/compiler/promisePermutations.ts(137,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. tests/cases/compiler/promisePermutations.ts(144,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. - Type 'IPromise' is not assignable to type 'IPromise'. tests/cases/compiler/promisePermutations.ts(152,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. Type 'IPromise' is not assignable to type 'Promise'. Types of property 'then' are incompatible. @@ -290,7 +289,6 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2345: Argument of t var r10d = r10.then(testFunction, sIPromise, nIPromise); // ok ~~~~~~~~~ !!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. -!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok diff --git a/tests/baselines/reference/promisePermutations2.errors.txt b/tests/baselines/reference/promisePermutations2.errors.txt index 871ee2ae2c347..955063797c0e7 100644 --- a/tests/baselines/reference/promisePermutations2.errors.txt +++ b/tests/baselines/reference/promisePermutations2.errors.txt @@ -45,7 +45,6 @@ tests/cases/compiler/promisePermutations2.ts(133,19): error TS2345: Argument of tests/cases/compiler/promisePermutations2.ts(136,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. tests/cases/compiler/promisePermutations2.ts(143,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. - Type 'IPromise' is not assignable to type 'IPromise'. tests/cases/compiler/promisePermutations2.ts(151,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. Type 'IPromise' is not assignable to type 'Promise'. Types of property 'then' are incompatible. @@ -289,7 +288,6 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of var r10d = r10.then(testFunction, sIPromise, nIPromise); // error ~~~~~~~~~ !!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. -!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok diff --git a/tests/baselines/reference/promisePermutations3.errors.txt b/tests/baselines/reference/promisePermutations3.errors.txt index 9d09559c5d32e..89a4cffe68813 100644 --- a/tests/baselines/reference/promisePermutations3.errors.txt +++ b/tests/baselines/reference/promisePermutations3.errors.txt @@ -48,7 +48,6 @@ tests/cases/compiler/promisePermutations3.ts(133,19): error TS2345: Argument of tests/cases/compiler/promisePermutations3.ts(136,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. tests/cases/compiler/promisePermutations3.ts(143,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. - Type 'IPromise' is not assignable to type 'IPromise'. tests/cases/compiler/promisePermutations3.ts(151,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. Type 'IPromise' is not assignable to type 'Promise'. Types of property 'then' are incompatible. @@ -301,7 +300,6 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of var r10d = r10.then(testFunction, sIPromise, nIPromise); // error ~~~~~~~~~ !!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. -!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok From 00cede1098f94cbbd4339d1ef4dbee3620d41c71 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Sep 2017 11:00:03 -0700 Subject: [PATCH 54/60] Fix linting errors --- src/compiler/checker.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f4d19330ac41d..d52fa56aead40 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10422,7 +10422,6 @@ namespace ts { function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; - //sys.write(typeToString(originalSource) + " ==> " + typeToString(originalTarget) + "\n"); inferFromTypes(originalSource, originalTarget); function inferFromTypes(source: Type, target: Type) { @@ -10490,7 +10489,6 @@ namespace ts { const inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { - //sys.write(" " + typeToString(source) + "\n"); if (!inference.candidates || priority < inference.priority) { inference.candidates = [source]; inference.priority = priority; From 3f370440374e6299b866da077bc90bd494652362 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 5 Sep 2017 17:17:04 -0700 Subject: [PATCH 55/60] Use canonicalized forms when comparing signatures --- src/compiler/checker.ts | 31 ++++++++++++++++++++++++++----- src/compiler/types.ts | 2 ++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d52fa56aead40..92afa856df4fd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6631,11 +6631,31 @@ namespace ts { } function getErasedSignature(signature: Signature): Signature { - if (!signature.typeParameters) return signature; - if (!signature.erasedSignatureCache) { - signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); - } - return signature.erasedSignatureCache; + return signature.typeParameters ? + signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : + signature; + } + + function createErasedSignature(signature: Signature) { + // Create an instantiation of the signature where all type arguments are the any type. + return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); + } + + function getCanonicalSignature(signature: Signature): Signature { + return signature.typeParameters ? + signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : + signature; + } + + function createCanonicalSignature(signature: Signature) { + // Create an instantiation of the signature where each unconstrained type parameter is replaced with + // its original. When a generic class or interface is instantiated, each generic method in the class or + // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios + // where different generations of the same type parameter are in scope). This leads to a lot of new type + // identities, and potentially a lot of work comparing those identities, so here we create an instantiation + // that reverts back to the original type identities for all unconstrained type parameters. + const canonicalTypeArguments = map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp); + return instantiateSignature(signature, createTypeMapper(signature.typeParameters, canonicalTypeArguments), /*eraseTypeParameters*/ true); } function getOrCreateTypeFromSignature(signature: Signature): ObjectType { @@ -8482,6 +8502,7 @@ namespace ts { return Ternary.False; } + target = getCanonicalSignature(target); if (source.typeParameters) { source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 440417db11240..c50197e2268f3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3410,6 +3410,8 @@ namespace ts { /* @internal */ erasedSignatureCache?: Signature; // Erased version of signature (deferred) /* @internal */ + canonicalSignatureCache?: Signature; // Canonical version of signature (deferred) + /* @internal */ isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison /* @internal */ typePredicate?: TypePredicate; From 8ef188e1bee50c4e685b4024e85eacad5bff6f43 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 6 Sep 2017 09:48:00 -0700 Subject: [PATCH 56/60] Minor changes --- src/compiler/checker.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 92afa856df4fd..8c9d369b4e5c0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6653,9 +6653,8 @@ namespace ts { // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios // where different generations of the same type parameter are in scope). This leads to a lot of new type // identities, and potentially a lot of work comparing those identities, so here we create an instantiation - // that reverts back to the original type identities for all unconstrained type parameters. - const canonicalTypeArguments = map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp); - return instantiateSignature(signature, createTypeMapper(signature.typeParameters, canonicalTypeArguments), /*eraseTypeParameters*/ true); + // that uses the original type identities for all unconstrained type parameters. + return getSignatureInstantiation(signature, map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp)); } function getOrCreateTypeFromSignature(signature: Signature): ObjectType { @@ -8502,8 +8501,8 @@ namespace ts { return Ternary.False; } - target = getCanonicalSignature(target); - if (source.typeParameters) { + if (source.typeParameters && source.typeParameters !== target.typeParameters) { + target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } From 1ea199576474a1db8ed25cf86ed908e8897a067b Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 5 Sep 2017 15:47:54 -0700 Subject: [PATCH 57/60] Document ThrottledOperations.schedule --- src/server/utilities.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/server/utilities.ts b/src/server/utilities.ts index e2e2a67eaf12d..353c5bcec2158 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -179,6 +179,12 @@ namespace ts.server { constructor(private readonly host: ServerHost) { } + /** + * Wait `number` milliseconds and then invoke `cb`. If, while waiting, schedule + * is called again with the same `operationId`, cancel this operation in favor + * of the new one. (Note that the amount of time the canceled operation had been + * waiting does not affect the amount of time that the new operation waits.) + */ public schedule(operationId: string, delay: number, cb: () => void) { const pendingTimeout = this.pendingTimeouts.get(operationId); if (pendingTimeout) { From dd9f4a1d945ebe6432501cda4fb21b22f6aa04fb Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 5 Sep 2017 16:00:19 -0700 Subject: [PATCH 58/60] Limit the number of unanswered typings installer requests If we send them all at once, we (apparently) hit a buffer limit in the node IPC channel and both TS Server and the typings installer become unresponsive. --- src/server/server.ts | 62 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index 0fe37dd8ba0d5..f4a8d1064e389 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -235,24 +235,34 @@ namespace ts.server { return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`; } + interface QueuedOperation { + operationId: string; + operation: () => void; + } + class NodeTypingsInstaller implements ITypingsInstaller { private installer: NodeChildProcess; private installerPidReported = false; private socket: NodeSocket; private projectService: ProjectService; - private throttledOperations: ThrottledOperations; private eventSender: EventSender; + private activeRequestCount = 0; + private requestQueue: QueuedOperation[] = []; + private requestMap = createMap(); // Maps operation ID to newest requestQueue entry with that ID + + private static readonly maxActiveRequestCount = 10; + private static readonly requestDelayMillis = 100; + constructor( private readonly telemetryEnabled: boolean, private readonly logger: server.Logger, - host: ServerHost, + private readonly host: ServerHost, eventPort: number, readonly globalTypingsCacheLocation: string, readonly typingSafeListLocation: string, private readonly npmLocation: string | undefined, private newLine: string) { - this.throttledOperations = new ThrottledOperations(host); if (eventPort) { const s = net.connect({ port: eventPort }, () => { this.socket = s; @@ -333,12 +343,26 @@ namespace ts.server { this.logger.info(`Scheduling throttled operation: ${JSON.stringify(request)}`); } } - this.throttledOperations.schedule(project.getProjectName(), /*ms*/ 250, () => { + + const operationId = project.getProjectName(); + const operation = () => { if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`Sending request: ${JSON.stringify(request)}`); } this.installer.send(request); - }); + }; + const queuedRequest: QueuedOperation = { operationId, operation }; + + if (this.activeRequestCount < NodeTypingsInstaller.maxActiveRequestCount) { + this.scheduleRequest(queuedRequest); + } + else { + if (this.logger.hasLevel(LogLevel.verbose)) { + this.logger.info(`Deferring request for: ${operationId}`); + } + this.requestQueue.push(queuedRequest); + this.requestMap.set(operationId, queuedRequest); + } } private handleMessage(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) { @@ -399,11 +423,39 @@ namespace ts.server { return; } + if (this.activeRequestCount > 0) { + this.activeRequestCount--; + } + else { + Debug.fail("Received too many responses"); + } + + while (this.requestQueue.length > 0) { + const queuedRequest = this.requestQueue.shift(); + if (this.requestMap.get(queuedRequest.operationId) == queuedRequest) { + this.requestMap.delete(queuedRequest.operationId); + this.scheduleRequest(queuedRequest); + break; + } + + if (this.logger.hasLevel(LogLevel.verbose)) { + this.logger.info(`Skipping defunct request for: ${queuedRequest.operationId}`); + } + } + this.projectService.updateTypingsForProject(response); if (response.kind === ActionSet && this.socket) { this.sendEvent(0, "setTypings", response); } } + + private scheduleRequest(request: QueuedOperation) { + if(this.logger.hasLevel(LogLevel.verbose)) { + this.logger.info(`Scheduling request for: ${request.operationId}`); + } + this.activeRequestCount++; + this.host.setTimeout(request.operation, NodeTypingsInstaller.requestDelayMillis); + } } class IOSession extends Session { From 40c34d122a2d37ecd2101c2e23defb0988b4ec7d Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 6 Sep 2017 15:44:00 -0700 Subject: [PATCH 59/60] Fix lint issues --- src/server/server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index f4a8d1064e389..26f6171086b92 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -432,7 +432,7 @@ namespace ts.server { while (this.requestQueue.length > 0) { const queuedRequest = this.requestQueue.shift(); - if (this.requestMap.get(queuedRequest.operationId) == queuedRequest) { + if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) { this.requestMap.delete(queuedRequest.operationId); this.scheduleRequest(queuedRequest); break; @@ -450,7 +450,7 @@ namespace ts.server { } private scheduleRequest(request: QueuedOperation) { - if(this.logger.hasLevel(LogLevel.verbose)) { + if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`Scheduling request for: ${request.operationId}`); } this.activeRequestCount++; From c505bc420655451cc0a2e3e316a02e7f947ba94d Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 6 Sep 2017 15:46:59 -0700 Subject: [PATCH 60/60] Add explanatory comment --- src/server/server.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/server/server.ts b/src/server/server.ts index 26f6171086b92..0552d86e7a04b 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -250,6 +250,11 @@ namespace ts.server { private requestQueue: QueuedOperation[] = []; private requestMap = createMap(); // Maps operation ID to newest requestQueue entry with that ID + // This number is essentially arbitrary. Processing more than one typings request + // at a time makes sense, but having too many in the pipe results in a hang + // (see https://github.com/nodejs/node/issues/7657). + // It would be preferable to base our limit on the amount of space left in the + // buffer, but we have yet to find a way to retrieve that value. private static readonly maxActiveRequestCount = 10; private static readonly requestDelayMillis = 100;