diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 363b21d64b1..26164a528f3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -466,9 +466,7 @@ namespace ts { // other kinds of value declarations take precedence over modules target.valueDeclaration = source.valueDeclaration; } - forEach(source.declarations, node => { - target.declarations.push(node); - }); + addRange(target.declarations, source.declarations); if (source.members) { if (!target.members) target.members = createMap(); mergeSymbolTable(target.members, source.members); @@ -1100,7 +1098,7 @@ namespace ts { } function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration | undefined { - return forEach(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined); + return find(symbol.declarations, isAliasSymbolDeclaration); } function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index ad016972d0d..3c7f3539e76 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1024,8 +1024,11 @@ namespace ts { } } - // Return the result if we have an immediate super() call on the last statement. - if (superCallExpression && statementOffset === ctorStatements.length - 1) { + // Return the result if we have an immediate super() call on the last statement, + // but only if the constructor itself doesn't use 'this' elsewhere. + if (superCallExpression + && statementOffset === ctorStatements.length - 1 + && !(ctor.transformFlags & (TransformFlags.ContainsLexicalThis | TransformFlags.ContainsCapturedLexicalThis))) { const returnStatement = createReturn(superCallExpression); if (superCallExpression.kind !== SyntaxKind.BinaryExpression diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 817dca3fd16..621d1414360 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -23,6 +23,7 @@ namespace ts.JsDoc { "lends", "link", "memberOf", + "method", "name", "namespace", "param", diff --git a/src/services/services.ts b/src/services/services.ts index b1d03c5a970..37b2c4f11aa 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -616,9 +616,8 @@ namespace ts { else { declarations.push(functionDeclaration); } - - forEachChild(node, visit); } + forEachChild(node, visit); break; case SyntaxKind.ClassDeclaration: diff --git a/tests/baselines/reference/arrowFunctionContexts.js b/tests/baselines/reference/arrowFunctionContexts.js index 64727398f72..1af0797b41f 100644 --- a/tests/baselines/reference/arrowFunctionContexts.js +++ b/tests/baselines/reference/arrowFunctionContexts.js @@ -116,7 +116,8 @@ var Base = (function () { var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, function () { return _this; }) || this; + var _this = _super.call(this, function () { return _this; }) || this; + return _this; } return Derived; }(Base)); @@ -157,7 +158,8 @@ var M2; var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, function () { return _this; }) || this; + var _this = _super.call(this, function () { return _this; }) || this; + return _this; } return Derived; }(Base)); diff --git a/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.errors.txt b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.errors.txt new file mode 100644 index 00000000000..6e2b7ef5787 --- /dev/null +++ b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts(9,24): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + + +==== tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts (1 errors) ==== + class A { + constructor(f: () => string) { + } + public blah(): string { return ""; } + } + + class B extends A { + constructor() { + super(() => { return super.blah(); }) + ~~~~~ +!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.js b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.js new file mode 100644 index 00000000000..7fde44106c6 --- /dev/null +++ b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.js @@ -0,0 +1,33 @@ +//// [captureSuperPropertyAccessInSuperCall01.ts] +class A { + constructor(f: () => string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(() => { return super.blah(); }) + } +} + +//// [captureSuperPropertyAccessInSuperCall01.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var A = (function () { + function A(f) { + } + A.prototype.blah = function () { return ""; }; + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + var _this = _super.call(this, function () { return _super.blah.call(_this); }) || this; + return _this; + } + return B; +}(A)); diff --git a/tests/baselines/reference/captureThisInSuperCall.js b/tests/baselines/reference/captureThisInSuperCall.js index 2c4df5db961..069871f598e 100644 --- a/tests/baselines/reference/captureThisInSuperCall.js +++ b/tests/baselines/reference/captureThisInSuperCall.js @@ -22,7 +22,8 @@ var A = (function () { var B = (function (_super) { __extends(B, _super); function B() { - return _super.call(this, { test: function () { return _this.someMethod(); } }) || this; + var _this = _super.call(this, { test: function () { return _this.someMethod(); } }) || this; + return _this; } B.prototype.someMethod = function () { }; return B; diff --git a/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js b/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js index 4cce975d6d9..ded73f57baf 100644 --- a/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js +++ b/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js @@ -25,7 +25,8 @@ var Based = (function () { var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, this.x) || this; + var _this = _super.call(this, _this.x) || this; + return _this; } return Derived; }(Based)); diff --git a/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js b/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js index ca12c16e047..364aed4d4b0 100644 --- a/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js +++ b/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js @@ -23,7 +23,8 @@ var Base = (function () { var Super = (function (_super) { __extends(Super, _super); function Super() { - return _super.call(this, (function () { return _this; })) || this; + var _this = _super.call(this, (function () { return _this; })) || this; + return _this; } return Super; }(Base)); diff --git a/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js b/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js index 504d414a608..039e25919f8 100644 --- a/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js +++ b/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js @@ -42,7 +42,8 @@ var Base = (function () { var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return Derived; }(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing2.js b/tests/baselines/reference/superCallBeforeThisAccessing2.js index 7331718a9ed..91cc3d28dd6 100644 --- a/tests/baselines/reference/superCallBeforeThisAccessing2.js +++ b/tests/baselines/reference/superCallBeforeThisAccessing2.js @@ -24,7 +24,8 @@ var Base = (function () { var D = (function (_super) { __extends(D, _super); function D() { - return _super.call(this, function () { _this._t; }) || this; + var _this = _super.call(this, function () { _this._t; }) || this; + return _this; } return D; }(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing6.js b/tests/baselines/reference/superCallBeforeThisAccessing6.js index e4dfb3f714a..4eb8e5266c2 100644 --- a/tests/baselines/reference/superCallBeforeThisAccessing6.js +++ b/tests/baselines/reference/superCallBeforeThisAccessing6.js @@ -24,7 +24,8 @@ var Base = (function () { var D = (function (_super) { __extends(D, _super); function D() { - return _super.call(this, this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return D; }(Base)); diff --git a/tests/baselines/reference/superPropertyAccessInSuperCall01.errors.txt b/tests/baselines/reference/superPropertyAccessInSuperCall01.errors.txt new file mode 100644 index 00000000000..f7449a26d5a --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInSuperCall01.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/superPropertyAccessInSuperCall01.ts(9,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + + +==== tests/cases/compiler/superPropertyAccessInSuperCall01.ts (1 errors) ==== + class A { + constructor(f: string) { + } + public blah(): string { return ""; } + } + + class B extends A { + constructor() { + super(super.blah()) + ~~~~~ +!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superPropertyAccessInSuperCall01.js b/tests/baselines/reference/superPropertyAccessInSuperCall01.js new file mode 100644 index 00000000000..f0dc925682c --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInSuperCall01.js @@ -0,0 +1,33 @@ +//// [superPropertyAccessInSuperCall01.ts] +class A { + constructor(f: string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(super.blah()) + } +} + +//// [superPropertyAccessInSuperCall01.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var A = (function () { + function A(f) { + } + A.prototype.blah = function () { return ""; }; + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + var _this = _super.call(this, _super.blah.call(_this)) || this; + return _this; + } + return B; +}(A)); diff --git a/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js b/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js index 15bc0c40f37..3fcf7167ee5 100644 --- a/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js +++ b/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js @@ -40,7 +40,8 @@ var C1 = (function (_super) { var C2 = (function (_super) { __extends(C2, _super); function C2() { - return _super.call(this, _super.x.call(_this)) || this; + var _this = _super.call(this, _super.x.call(_this)) || this; + return _this; } return C2; }(B)); diff --git a/tests/baselines/reference/thisInInvalidContexts.js b/tests/baselines/reference/thisInInvalidContexts.js index 1fc1c734639..7f299fd7e10 100644 --- a/tests/baselines/reference/thisInInvalidContexts.js +++ b/tests/baselines/reference/thisInInvalidContexts.js @@ -70,7 +70,8 @@ var ClassWithNoInitializer = (function (_super) { __extends(ClassWithNoInitializer, _super); //'this' in optional super call function ClassWithNoInitializer() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return ClassWithNoInitializer; }(BaseErrClass)); diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index f8cb6d695dc..65a1ef1eee9 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -71,7 +71,8 @@ var ClassWithNoInitializer = (function (_super) { __extends(ClassWithNoInitializer, _super); //'this' in optional super call function ClassWithNoInitializer() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return ClassWithNoInitializer; }(BaseErrClass)); diff --git a/tests/baselines/reference/thisInSuperCall.js b/tests/baselines/reference/thisInSuperCall.js index 2a4d15973ab..1c1f11ffbc8 100644 --- a/tests/baselines/reference/thisInSuperCall.js +++ b/tests/baselines/reference/thisInSuperCall.js @@ -36,7 +36,8 @@ var Base = (function () { var Foo = (function (_super) { __extends(Foo, _super); function Foo() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return Foo; }(Base)); diff --git a/tests/baselines/reference/thisInSuperCall2.js b/tests/baselines/reference/thisInSuperCall2.js index eabfa9d562c..6288082ed64 100644 --- a/tests/baselines/reference/thisInSuperCall2.js +++ b/tests/baselines/reference/thisInSuperCall2.js @@ -33,7 +33,8 @@ var Base = (function () { var Foo = (function (_super) { __extends(Foo, _super); function Foo() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return Foo; }(Base)); diff --git a/tests/baselines/reference/validUseOfThisInSuper.js b/tests/baselines/reference/validUseOfThisInSuper.js index 483e905b48a..bbd564db366 100644 --- a/tests/baselines/reference/validUseOfThisInSuper.js +++ b/tests/baselines/reference/validUseOfThisInSuper.js @@ -24,7 +24,8 @@ var Base = (function () { var Super = (function (_super) { __extends(Super, _super); function Super() { - return _super.call(this, (function () { return _this; })()) || this; + var _this = _super.call(this, (function () { return _this; })()) || this; + return _this; } return Super; }(Base)); diff --git a/tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts b/tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts new file mode 100644 index 00000000000..e60b9801c02 --- /dev/null +++ b/tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts @@ -0,0 +1,11 @@ +class A { + constructor(f: () => string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(() => { return super.blah(); }) + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superPropertyAccessInSuperCall01.ts b/tests/cases/compiler/superPropertyAccessInSuperCall01.ts new file mode 100644 index 00000000000..38373e9eef6 --- /dev/null +++ b/tests/cases/compiler/superPropertyAccessInSuperCall01.ts @@ -0,0 +1,11 @@ +class A { + constructor(f: string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(super.blah()) + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index e5cc7a3d2b6..8ab9dbd0131 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -30,6 +30,7 @@ goTo.marker('1'); verify.completionListContains("constructor"); verify.completionListContains("param"); verify.completionListContains("type"); +verify.completionListContains("method"); goTo.marker('2'); verify.completionListContains("constructor"); diff --git a/tests/cases/fourslash/navigateToIIFE.ts b/tests/cases/fourslash/navigateToIIFE.ts new file mode 100644 index 00000000000..69632e5f1ec --- /dev/null +++ b/tests/cases/fourslash/navigateToIIFE.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: file1.ts +/////*1*/(function () { +//// "use strict"; +//// function onResume() { +//// }; +////} )(); +// @Filename: file2.ts +/////*2*/class EventManager { +//// public onResume(name: string) { } +////} +////class MyOtherEventManager { +//// public onResume(name: string) { } +////} +verify.navigationItemsListCount(3, "onResume"); +verify.navigationItemsListCount(1, "onResume", undefined, test.marker("1").fileName); +verify.navigationItemsListContains("onResume", "function", "onResume", "exact", test.marker("1").fileName); +verify.navigationItemsListCount(2, "onResume", undefined, test.marker("2").fileName);