From 90c08c22015979848bef009298bebd7532737200 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 2 Feb 2016 16:32:10 -0800 Subject: [PATCH 01/22] Port PR#6860 lexically check calling super before this Update baselines add baselines Update baseline Port PR #6860 lexically check calling super before this Check using "super" before "this" lexically instead of using the NodeCheckFlags Remove "type-checking" way of checking if super is used before this. Instead check using whether super occurs before this syntactically Refactor the code Dive down to get super call Address PR Address PR about tests Add a flag so we don't repeatedly finding super call rename function Move tests into correct location Address PR: report error on super call instead of entire constructor node remove marge mark --- src/compiler/checker.ts | 93 +++++++++++++++---- src/compiler/types.ts | 10 +- .../reference/classExtendsNull.errors.txt | 11 +-- .../superCallBeforeThisAccessing1.js | 40 ++++++++ .../superCallBeforeThisAccessing1.symbols | 38 ++++++++ .../superCallBeforeThisAccessing1.types | 43 +++++++++ .../superCallBeforeThisAccessing2.js | 31 +++++++ .../superCallBeforeThisAccessing2.symbols | 23 +++++ .../superCallBeforeThisAccessing2.types | 25 +++++ .../superCallBeforeThisAccessing3.errors.txt | 19 ++++ .../superCallBeforeThisAccessing3.js | 37 ++++++++ .../superCallBeforeThisAccessing4.errors.txt | 24 +++++ .../superCallBeforeThisAccessing4.js | 39 ++++++++ .../superCallBeforeThisAccessing5.js | 22 +++++ .../superCallBeforeThisAccessing5.symbols | 15 +++ .../superCallBeforeThisAccessing5.types | 16 ++++ .../superCallBeforeThisAccessing6.errors.txt | 16 ++++ .../superCallBeforeThisAccessing6.js | 30 ++++++ .../superCallBeforeThisAccessing7.errors.txt | 19 ++++ .../superCallBeforeThisAccessing7.js | 36 +++++++ .../superCallBeforeThisAccessing8.js | 36 +++++++ .../superCallBeforeThisAccessing8.symbols | 32 +++++++ .../superCallBeforeThisAccessing8.types | 34 +++++++ .../superCallBeforeThisAccessing1.ts | 15 +++ .../superCallBeforeThisAccessing2.ts | 9 ++ .../superCallBeforeThisAccessing3.ts | 12 +++ .../superCallBeforeThisAccessing4.ts | 15 +++ .../superCallBeforeThisAccessing5.ts | 6 ++ .../superCallBeforeThisAccessing6.ts | 9 ++ .../superCallBeforeThisAccessing7.ts | 12 +++ .../superCallBeforeThisAccessing8.ts | 12 +++ 31 files changed, 748 insertions(+), 31 deletions(-) create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing1.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing1.symbols create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing1.types create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing2.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing2.symbols create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing2.types create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing3.errors.txt create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing3.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing4.errors.txt create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing4.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing5.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing5.symbols create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing5.types create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing6.errors.txt create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing6.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing7.errors.txt create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing7.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing8.js create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing8.symbols create mode 100644 tests/baselines/reference/superCallBeforeThisAccessing8.types create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76323f83e08..6508ce755d0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7328,6 +7328,50 @@ namespace ts { } } + function isSuperCallExpression(n: Node): boolean { + return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.SuperKeyword; + } + + function findFirstSuperCall(n: Node): Node { + if (isSuperCallExpression(n)) { + return n; + } + else if (isFunctionLike(n)) { + return undefined; + } + return forEachChild(n, findFirstSuperCall); + } + + /** + * Return a cached result if super-statement is already found. + * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor + * + * @param constructor constructor-function to look for super statement + */ + function getSuperCallInConstructor(constructor: ConstructorDeclaration): ExpressionStatement { + const links = getNodeLinks(constructor); + + // Only trying to find super-call if we haven't yet tried to find one. Once we try, we will record the result + if (links.hasSuperCall === undefined) { + links.superCall = findFirstSuperCall(constructor.body); + links.hasSuperCall = links.superCall ? true : false; + } + return links.superCall; + } + + /** + * Check if the given class-declaration extends null then return true. + * Otherwise, return false + * @param classDecl a class declaration to check if it extends null + */ + function classDeclarationExtendsNull(classDecl: ClassDeclaration): boolean { + const classSymbol = getSymbolOfNode(classDecl); + const classInstanceType = getDeclaredTypeOfSymbol(classSymbol); + const baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType); + + return baseConstructorType === nullType; + } + function checkThisExpression(node: Node): Type { // Stop at the first arrow function so that we can // tell whether 'this' needs to be captured. @@ -7335,10 +7379,25 @@ namespace ts { let needToCaptureLexicalThis = false; if (container.kind === SyntaxKind.Constructor) { - const baseTypeNode = getClassExtendsHeritageClauseElement(container.parent); - if (baseTypeNode && !(getNodeCheckFlags(container) & NodeCheckFlags.HasSeenSuperCall)) { - // In ES6, super inside constructor of class-declaration has to precede "this" accessing - error(node, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class); + const containingClassDecl = container.parent; + const baseTypeNode = getClassExtendsHeritageClauseElement(containingClassDecl); + + // If a containing class does not have extends clause or the class extends null + // skip checking whether super statement is called before "this" accessing. + if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) { + const superCall = getSuperCallInConstructor(container); + + // We should give an error in the following cases: + // - No super-call + // - "this" is accessing before super-call. + // i.e super(this) + // this.x; super(); + // We want to make sure that super-call is done before accessing "this" so that + // "this" is not accessed as a parameter of the super-call. + if (!superCall || superCall.end > node.pos) { + // In ES6, super inside constructor of class-declaration has to precede "this" accessing + error(node, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class); + } } } @@ -10287,14 +10346,11 @@ namespace ts { checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments); const signature = getResolvedSignature(node); - if (node.expression.kind === SyntaxKind.SuperKeyword) { - const containingFunction = getContainingFunction(node.expression); - if (containingFunction && containingFunction.kind === SyntaxKind.Constructor) { - getNodeLinks(containingFunction).flags |= NodeCheckFlags.HasSeenSuperCall; - } + if (node.expression.kind === SyntaxKind.SuperKeyword) { return voidType; } + if (node.kind === SyntaxKind.NewExpression) { const declaration = signature.declaration; @@ -11875,17 +11931,15 @@ namespace ts { } // TS 1.0 spec (April 2014): 8.3.2 - // Constructors of classes with no extends clause may not contain super calls, whereas - // constructors of derived classes must contain at least one super call somewhere in their function body. + // Constructors of classes with no extends clause and constructors of classes that extends null may not contain super calls, + // whereas constructors of derived classes must contain at least one super call somewhere in their function body. const containingClassDecl = node.parent; if (getClassExtendsHeritageClauseElement(containingClassDecl)) { - const containingClassSymbol = getSymbolOfNode(containingClassDecl); - const containingClassInstanceType = getDeclaredTypeOfSymbol(containingClassSymbol); - const baseConstructorType = getBaseConstructorTypeOfClass(containingClassInstanceType); - - if (containsSuperCall(node.body)) { - if (baseConstructorType === nullType) { - error(node, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); + const classExtendsNull = classDeclarationExtendsNull(containingClassDecl); + const superCall = getSuperCallInConstructor(node); + if (superCall) { + if (classExtendsNull) { + error(superCall, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } // The first statement in the body of a constructor (excluding prologue directives) must be a super call @@ -11902,6 +11956,7 @@ namespace ts { if (superCallShouldBeFirst) { const statements = (node.body).statements; let superCallStatement: ExpressionStatement; + for (const statement of statements) { if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { superCallStatement = statement; @@ -11916,7 +11971,7 @@ namespace ts { } } } - else if (baseConstructorType !== nullType) { + else if (!classExtendsNull) { error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 31448c2859c..78f441c4b89 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -430,7 +430,6 @@ namespace ts { IntrinsicElement = IntrinsicNamedElement | IntrinsicIndexedElement, } - /* @internal */ export const enum RelationComparisonResult { Succeeded = 1, // Should be truthy @@ -2041,10 +2040,9 @@ namespace ts { LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement - HasSeenSuperCall = 0x00080000, // Set during the binding when encounter 'super' - ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body. - BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body. - NeedsLoopOutParameter = 0x00400000, // Block scoped binding whose value should be explicitly copied outside of the converted loop + ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body. + BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body. + NeedsLoopOutParameter = 0x00200000, // Block scoped binding whose value should be explicitly copied outside of the converted loop } /* @internal */ @@ -2064,6 +2062,8 @@ namespace ts { importOnRightSide?: Symbol; // for import declarations - import that appear on the right side jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element + hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. + superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing } export const enum TypeFlags { diff --git a/tests/baselines/reference/classExtendsNull.errors.txt b/tests/baselines/reference/classExtendsNull.errors.txt index 7bb44774826..905c90c42fd 100644 --- a/tests/baselines/reference/classExtendsNull.errors.txt +++ b/tests/baselines/reference/classExtendsNull.errors.txt @@ -1,17 +1,14 @@ -tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' +tests/cases/compiler/classExtendsNull.ts(3,9): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' ==== tests/cases/compiler/classExtendsNull.ts (1 errors) ==== class C extends null { constructor() { - ~~~~~~~~~~~~~~~ super(); - ~~~~~~~~~~~~~~~~ - return Object.create(null); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - } - ~~~~~ + ~~~~~~~ !!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' + return Object.create(null); + } } class D extends null { diff --git a/tests/baselines/reference/superCallBeforeThisAccessing1.js b/tests/baselines/reference/superCallBeforeThisAccessing1.js new file mode 100644 index 00000000000..1fc7ab39c91 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing1.js @@ -0,0 +1,40 @@ +//// [superCallBeforeThisAccessing1.ts] +declare var Factory: any + +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + super(i); + var s = { + t: this._t + } + var i = Factory.create(s); + } +} + + +//// [superCallBeforeThisAccessing1.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 Base = (function () { + function Base(c) { + } + return Base; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.call(this, i); + var s = { + t: this._t + }; + var i = Factory.create(s); + } + return D; +}(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing1.symbols b/tests/baselines/reference/superCallBeforeThisAccessing1.symbols new file mode 100644 index 00000000000..5a153728a73 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing1.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts === +declare var Factory: any +>Factory : Symbol(Factory, Decl(superCallBeforeThisAccessing1.ts, 0, 11)) + +class Base { +>Base : Symbol(Base, Decl(superCallBeforeThisAccessing1.ts, 0, 24)) + + constructor(c) { } +>c : Symbol(c, Decl(superCallBeforeThisAccessing1.ts, 3, 16)) +} +class D extends Base { +>D : Symbol(D, Decl(superCallBeforeThisAccessing1.ts, 4, 1)) +>Base : Symbol(Base, Decl(superCallBeforeThisAccessing1.ts, 0, 24)) + + private _t; +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing1.ts, 5, 22)) + + constructor() { + super(i); +>super : Symbol(Base, Decl(superCallBeforeThisAccessing1.ts, 0, 24)) +>i : Symbol(i, Decl(superCallBeforeThisAccessing1.ts, 12, 11)) + + var s = { +>s : Symbol(s, Decl(superCallBeforeThisAccessing1.ts, 9, 11)) + + t: this._t +>t : Symbol(t, Decl(superCallBeforeThisAccessing1.ts, 9, 17)) +>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing1.ts, 5, 22)) +>this : Symbol(D, Decl(superCallBeforeThisAccessing1.ts, 4, 1)) +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing1.ts, 5, 22)) + } + var i = Factory.create(s); +>i : Symbol(i, Decl(superCallBeforeThisAccessing1.ts, 12, 11)) +>Factory : Symbol(Factory, Decl(superCallBeforeThisAccessing1.ts, 0, 11)) +>s : Symbol(s, Decl(superCallBeforeThisAccessing1.ts, 9, 11)) + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing1.types b/tests/baselines/reference/superCallBeforeThisAccessing1.types new file mode 100644 index 00000000000..e947653584a --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing1.types @@ -0,0 +1,43 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts === +declare var Factory: any +>Factory : any + +class Base { +>Base : Base + + constructor(c) { } +>c : any +} +class D extends Base { +>D : D +>Base : Base + + private _t; +>_t : any + + constructor() { + super(i); +>super(i) : void +>super : typeof Base +>i : any + + var s = { +>s : { t: any; } +>{ t: this._t } : { t: any; } + + t: this._t +>t : any +>this._t : any +>this : this +>_t : any + } + var i = Factory.create(s); +>i : any +>Factory.create(s) : any +>Factory.create : any +>Factory : any +>create : any +>s : { t: any; } + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing2.js b/tests/baselines/reference/superCallBeforeThisAccessing2.js new file mode 100644 index 00000000000..e5acf06bbfd --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing2.js @@ -0,0 +1,31 @@ +//// [superCallBeforeThisAccessing2.ts] +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + super(() => { this._t }); // no error. only check when this is directly accessing in constructor + } +} + + +//// [superCallBeforeThisAccessing2.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 Base = (function () { + function Base(c) { + } + return Base; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + var _this = this; + _super.call(this, function () { _this._t; }); // no error. only check when this is directly accessing in constructor + } + return D; +}(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing2.symbols b/tests/baselines/reference/superCallBeforeThisAccessing2.symbols new file mode 100644 index 00000000000..2df2e62354a --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing2.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts === +class Base { +>Base : Symbol(Base, Decl(superCallBeforeThisAccessing2.ts, 0, 0)) + + constructor(c) { } +>c : Symbol(c, Decl(superCallBeforeThisAccessing2.ts, 1, 16)) +} +class D extends Base { +>D : Symbol(D, Decl(superCallBeforeThisAccessing2.ts, 2, 1)) +>Base : Symbol(Base, Decl(superCallBeforeThisAccessing2.ts, 0, 0)) + + private _t; +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing2.ts, 3, 22)) + + constructor() { + super(() => { this._t }); // no error. only check when this is directly accessing in constructor +>super : Symbol(Base, Decl(superCallBeforeThisAccessing2.ts, 0, 0)) +>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing2.ts, 3, 22)) +>this : Symbol(D, Decl(superCallBeforeThisAccessing2.ts, 2, 1)) +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing2.ts, 3, 22)) + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing2.types b/tests/baselines/reference/superCallBeforeThisAccessing2.types new file mode 100644 index 00000000000..cf0f54b6246 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing2.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts === +class Base { +>Base : Base + + constructor(c) { } +>c : any +} +class D extends Base { +>D : D +>Base : Base + + private _t; +>_t : any + + constructor() { + super(() => { this._t }); // no error. only check when this is directly accessing in constructor +>super(() => { this._t }) : void +>super : typeof Base +>() => { this._t } : () => void +>this._t : any +>this : this +>_t : any + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing3.errors.txt b/tests/baselines/reference/superCallBeforeThisAccessing3.errors.txt new file mode 100644 index 00000000000..90b9b034263 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing3.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts(9,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. + + +==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts (1 errors) ==== + class Base { + constructor(c) { } + } + class D extends Base { + private _t; + constructor() { + let x = () => { this._t }; + x(); // no error; we only check super is called before this when the container is a constructor + this._t; // error + ~~~~ +!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. + super(undefined); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/superCallBeforeThisAccessing3.js b/tests/baselines/reference/superCallBeforeThisAccessing3.js new file mode 100644 index 00000000000..101d74e4bc7 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing3.js @@ -0,0 +1,37 @@ +//// [superCallBeforeThisAccessing3.ts] +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + let x = () => { this._t }; + x(); // no error; we only check super is called before this when the container is a constructor + this._t; // error + super(undefined); + } +} + + +//// [superCallBeforeThisAccessing3.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 Base = (function () { + function Base(c) { + } + return Base; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + var _this = this; + var x = function () { _this._t; }; + x(); // no error; we only check super is called before this when the container is a constructor + this._t; // error + _super.call(this, undefined); + } + return D; +}(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing4.errors.txt b/tests/baselines/reference/superCallBeforeThisAccessing4.errors.txt new file mode 100644 index 00000000000..91c3e7763f6 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing4.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts(5,9): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' +tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts(12,9): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' + + +==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts (2 errors) ==== + class D extends null { + private _t; + constructor() { + this._t; + super(); + ~~~~~~~ +!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' + } + } + + class E extends null { + private _t; + constructor() { + super(); + ~~~~~~~ +!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' + this._t; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superCallBeforeThisAccessing4.js b/tests/baselines/reference/superCallBeforeThisAccessing4.js new file mode 100644 index 00000000000..9c3c5ab60c4 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing4.js @@ -0,0 +1,39 @@ +//// [superCallBeforeThisAccessing4.ts] +class D extends null { + private _t; + constructor() { + this._t; + super(); + } +} + +class E extends null { + private _t; + constructor() { + super(); + this._t; + } +} + +//// [superCallBeforeThisAccessing4.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 D = (function (_super) { + __extends(D, _super); + function D() { + this._t; + _super.call(this); + } + return D; +}(null)); +var E = (function (_super) { + __extends(E, _super); + function E() { + _super.call(this); + this._t; + } + return E; +}(null)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing5.js b/tests/baselines/reference/superCallBeforeThisAccessing5.js new file mode 100644 index 00000000000..3281a3f8b55 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing5.js @@ -0,0 +1,22 @@ +//// [superCallBeforeThisAccessing5.ts] +class D extends null { + private _t; + constructor() { + this._t; // No error + } +} + + +//// [superCallBeforeThisAccessing5.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 D = (function (_super) { + __extends(D, _super); + function D() { + this._t; // No error + } + return D; +}(null)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing5.symbols b/tests/baselines/reference/superCallBeforeThisAccessing5.symbols new file mode 100644 index 00000000000..a7628e3b8df --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing5.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts === +class D extends null { +>D : Symbol(D, Decl(superCallBeforeThisAccessing5.ts, 0, 0)) + + private _t; +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing5.ts, 0, 22)) + + constructor() { + this._t; // No error +>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing5.ts, 0, 22)) +>this : Symbol(D, Decl(superCallBeforeThisAccessing5.ts, 0, 0)) +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing5.ts, 0, 22)) + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing5.types b/tests/baselines/reference/superCallBeforeThisAccessing5.types new file mode 100644 index 00000000000..2c0fc33c4dc --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing5.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts === +class D extends null { +>D : D +>null : null + + private _t; +>_t : any + + constructor() { + this._t; // No error +>this._t : any +>this : this +>_t : any + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing6.errors.txt b/tests/baselines/reference/superCallBeforeThisAccessing6.errors.txt new file mode 100644 index 00000000000..346b2d58bec --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing6.errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts(7,15): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. + + +==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts (1 errors) ==== + class Base { + constructor(c) { } + } + class D extends Base { + private _t; + constructor() { + super(this); + ~~~~ +!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/superCallBeforeThisAccessing6.js b/tests/baselines/reference/superCallBeforeThisAccessing6.js new file mode 100644 index 00000000000..746ce9f2791 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing6.js @@ -0,0 +1,30 @@ +//// [superCallBeforeThisAccessing6.ts] +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + super(this); + } +} + + +//// [superCallBeforeThisAccessing6.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 Base = (function () { + function Base(c) { + } + return Base; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.call(this, this); + } + return D; +}(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing7.errors.txt b/tests/baselines/reference/superCallBeforeThisAccessing7.errors.txt new file mode 100644 index 00000000000..4e374fd96ea --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing7.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts(8,16): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. + + +==== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts (1 errors) ==== + class Base { + constructor(c) { } + } + class D extends Base { + private _t; + constructor() { + let x = { + j: this._t, + ~~~~ +!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class. + } + super(undefined); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/superCallBeforeThisAccessing7.js b/tests/baselines/reference/superCallBeforeThisAccessing7.js new file mode 100644 index 00000000000..c3aa1655cf7 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing7.js @@ -0,0 +1,36 @@ +//// [superCallBeforeThisAccessing7.ts] +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + let x = { + j: this._t, + } + super(undefined); + } +} + + +//// [superCallBeforeThisAccessing7.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 Base = (function () { + function Base(c) { + } + return Base; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + var x = { + j: this._t + }; + _super.call(this, undefined); + } + return D; +}(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing8.js b/tests/baselines/reference/superCallBeforeThisAccessing8.js new file mode 100644 index 00000000000..0865c4305a5 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing8.js @@ -0,0 +1,36 @@ +//// [superCallBeforeThisAccessing8.ts] +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + let x = { + k: super(undefined), + j: this._t, // no error + } + } +} + + +//// [superCallBeforeThisAccessing8.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 Base = (function () { + function Base(c) { + } + return Base; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + var x = { + k: _super.call(this, undefined), + j: this._t + }; + } + return D; +}(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing8.symbols b/tests/baselines/reference/superCallBeforeThisAccessing8.symbols new file mode 100644 index 00000000000..65341ee9fe3 --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing8.symbols @@ -0,0 +1,32 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts === +class Base { +>Base : Symbol(Base, Decl(superCallBeforeThisAccessing8.ts, 0, 0)) + + constructor(c) { } +>c : Symbol(c, Decl(superCallBeforeThisAccessing8.ts, 1, 16)) +} +class D extends Base { +>D : Symbol(D, Decl(superCallBeforeThisAccessing8.ts, 2, 1)) +>Base : Symbol(Base, Decl(superCallBeforeThisAccessing8.ts, 0, 0)) + + private _t; +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing8.ts, 3, 22)) + + constructor() { + let x = { +>x : Symbol(x, Decl(superCallBeforeThisAccessing8.ts, 6, 11)) + + k: super(undefined), +>k : Symbol(k, Decl(superCallBeforeThisAccessing8.ts, 6, 17)) +>super : Symbol(Base, Decl(superCallBeforeThisAccessing8.ts, 0, 0)) +>undefined : Symbol(undefined) + + j: this._t, // no error +>j : Symbol(j, Decl(superCallBeforeThisAccessing8.ts, 7, 32)) +>this._t : Symbol(_t, Decl(superCallBeforeThisAccessing8.ts, 3, 22)) +>this : Symbol(D, Decl(superCallBeforeThisAccessing8.ts, 2, 1)) +>_t : Symbol(_t, Decl(superCallBeforeThisAccessing8.ts, 3, 22)) + } + } +} + diff --git a/tests/baselines/reference/superCallBeforeThisAccessing8.types b/tests/baselines/reference/superCallBeforeThisAccessing8.types new file mode 100644 index 00000000000..dd92d924ceb --- /dev/null +++ b/tests/baselines/reference/superCallBeforeThisAccessing8.types @@ -0,0 +1,34 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts === +class Base { +>Base : Base + + constructor(c) { } +>c : any +} +class D extends Base { +>D : D +>Base : Base + + private _t; +>_t : any + + constructor() { + let x = { +>x : { k: void; j: any; } +>{ k: super(undefined), j: this._t, // no error } : { k: void; j: any; } + + k: super(undefined), +>k : void +>super(undefined) : void +>super : typeof Base +>undefined : undefined + + j: this._t, // no error +>j : any +>this._t : any +>this : this +>_t : any + } + } +} + diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts new file mode 100644 index 00000000000..e5d63f2e930 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing1.ts @@ -0,0 +1,15 @@ +declare var Factory: any + +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + super(i); + var s = { + t: this._t + } + var i = Factory.create(s); + } +} diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts new file mode 100644 index 00000000000..1b0a0d541e9 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing2.ts @@ -0,0 +1,9 @@ +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + super(() => { this._t }); // no error. only check when this is directly accessing in constructor + } +} diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts new file mode 100644 index 00000000000..1386998aaae --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing3.ts @@ -0,0 +1,12 @@ +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + let x = () => { this._t }; + x(); // no error; we only check super is called before this when the container is a constructor + this._t; // error + super(undefined); + } +} diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts new file mode 100644 index 00000000000..9135e03b0ce --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing4.ts @@ -0,0 +1,15 @@ +class D extends null { + private _t; + constructor() { + this._t; + super(); + } +} + +class E extends null { + private _t; + constructor() { + super(); + this._t; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts new file mode 100644 index 00000000000..17820277585 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing5.ts @@ -0,0 +1,6 @@ +class D extends null { + private _t; + constructor() { + this._t; // No error + } +} diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts new file mode 100644 index 00000000000..8f36f2eb056 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing6.ts @@ -0,0 +1,9 @@ +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + super(this); + } +} diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts new file mode 100644 index 00000000000..d40c96a60f3 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing7.ts @@ -0,0 +1,12 @@ +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + let x = { + j: this._t, + } + super(undefined); + } +} diff --git a/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts new file mode 100644 index 00000000000..5742cdab845 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallBeforeThisAccessing8.ts @@ -0,0 +1,12 @@ +class Base { + constructor(c) { } +} +class D extends Base { + private _t; + constructor() { + let x = { + k: super(undefined), + j: this._t, // no error + } + } +} From 2a674579d3f626471a32dfadee179079a686172d Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Thu, 11 Feb 2016 14:08:18 -0800 Subject: [PATCH 02/22] Remove duplicate function from merging --- src/compiler/checker.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6508ce755d0..fb6a0528c74 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7328,10 +7328,6 @@ namespace ts { } } - function isSuperCallExpression(n: Node): boolean { - return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.SuperKeyword; - } - function findFirstSuperCall(n: Node): Node { if (isSuperCallExpression(n)) { return n; From 0aad5e5e4554d671cd5efd9979928b4bdc3d8cae Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Thu, 11 Feb 2016 14:29:22 -0800 Subject: [PATCH 03/22] Remove incorrect commment resulting from merging --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb6a0528c74..dc3704586dd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11927,8 +11927,8 @@ namespace ts { } // TS 1.0 spec (April 2014): 8.3.2 - // Constructors of classes with no extends clause and constructors of classes that extends null may not contain super calls, - // whereas constructors of derived classes must contain at least one super call somewhere in their function body. + // Constructors of classes with no extends clause may not contain super calls, whereas + // constructors of derived classes must contain at least one super call somewhere in their function body. const containingClassDecl = node.parent; if (getClassExtendsHeritageClauseElement(containingClassDecl)) { const classExtendsNull = classDeclarationExtendsNull(containingClassDecl); From 22979db64cfb53d7d73c001c15b57efbecbe4e99 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Sun, 3 Jan 2016 06:10:47 -0500 Subject: [PATCH 04/22] Add test --- .../typeGuards/typeGuardOfFormFunctionEquality.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardOfFormFunctionEquality.ts diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormFunctionEquality.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormFunctionEquality.ts new file mode 100644 index 00000000000..baff942bb8e --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormFunctionEquality.ts @@ -0,0 +1,14 @@ +declare function isString1(a: number, b: Object): b is string; + +declare function isString2(a: Object): a is string; + +switch (isString1(0, "")) { + case isString2(""): + default: +} + +var x = isString1(0, "") === isString2(""); + +function isString3(a: number, b: number, c: Object): c is string { + return isString1(0, c); +} From cf13a71af43da3c7b0833066c5218982ccf5f301 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Jan 2016 15:06:17 -0800 Subject: [PATCH 05/22] Move type predicates back onto signatures, remove narrowing for property/get type guards. --- src/compiler/checker.ts | 248 ++++++++++++++++++-------------------- src/compiler/types.ts | 19 ++- src/compiler/utilities.ts | 4 + 3 files changed, 130 insertions(+), 141 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6b43b3802c2..9b7b2bd12c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -131,8 +131,8 @@ namespace ts { const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); - const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); + const anySignature = createSignature(undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); + const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); @@ -1711,6 +1711,15 @@ namespace ts { return result; } + function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { + const writer = getSingleLineStringWriter(); + getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); + const result = writer.string(); + releaseStringWriter(writer); + + return result; + } + function getTypeAliasForTypeLiteral(type: Type): Symbol { if (type.symbol && type.symbol.flags & SymbolFlags.TypeLiteral) { let node = type.symbol.declarations[0].parent; @@ -1844,16 +1853,10 @@ namespace ts { function writeType(type: Type, flags: TypeFormatFlags) { // Write undefined/null type as any if (type.flags & TypeFlags.Intrinsic) { - if (type.flags & TypeFlags.PredicateType) { - buildTypePredicateDisplay(writer, (type as PredicateType).predicate); - buildTypeDisplay((type as PredicateType).predicate.type, writer, enclosingDeclaration, flags, symbolStack); - } - else { - // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving - writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) - ? "any" - : (type).intrinsicName); - } + // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving + writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) + ? "any" + : (type).intrinsicName); } else if (type.flags & TypeFlags.ThisType) { if (inObjectTypeLiteral) { @@ -2213,7 +2216,7 @@ namespace ts { writePunctuation(writer, SyntaxKind.CloseParenToken); } - function buildTypePredicateDisplay(writer: SymbolWriter, predicate: TypePredicate) { + function buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]): void { if (isIdentifierTypePredicate(predicate)) { writer.writeParameter(predicate.parameterName); } @@ -2223,6 +2226,7 @@ namespace ts { writeSpace(writer); writeKeyword(writer, SyntaxKind.IsKeyword); writeSpace(writer); + buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack); } function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { @@ -2235,8 +2239,13 @@ namespace ts { } writeSpace(writer); - const returnType = getReturnTypeOfSignature(signature); - buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack); + if (signature.typePredicate) { + buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack); + } + else { + const returnType = getReturnTypeOfSignature(signature); + buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack); + } } function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, symbolStack?: Symbol[]) { @@ -2255,6 +2264,7 @@ namespace ts { } buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, symbolStack); + buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack); } @@ -2262,6 +2272,7 @@ namespace ts { buildSymbolDisplay, buildTypeDisplay, buildTypeParameterDisplay, + buildTypePredicateDisplay, buildParameterDisplay, buildDisplayForParametersAndDelimiters, buildDisplayForTypeParametersAndDelimiters, @@ -2800,9 +2811,6 @@ namespace ts { if (declaration.kind === SyntaxKind.PropertyAssignment) { return type; } - if (type.flags & TypeFlags.PredicateType && (declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature)) { - return type; - } return getWidenedType(type); } @@ -3533,12 +3541,13 @@ namespace ts { } function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[], - resolvedReturnType: Type, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { + resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { const sig = new Signature(checker); sig.declaration = declaration; sig.typeParameters = typeParameters; sig.parameters = parameters; sig.resolvedReturnType = resolvedReturnType; + sig.typePredicate = typePredicate; sig.minArgumentCount = minArgumentCount; sig.hasRestParameter = hasRestParameter; sig.hasStringLiterals = hasStringLiterals; @@ -3547,14 +3556,14 @@ namespace ts { function cloneSignature(sig: Signature): Signature { return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, - sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals); + sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals); } function getDefaultConstructSignatures(classType: InterfaceType): Signature[] { const baseConstructorType = getBaseConstructorTypeOfClass(classType); const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); if (baseSignatures.length === 0) { - return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)]; } const baseTypeNode = getBaseTypeNodeOfClass(classType); const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode); @@ -4086,6 +4095,7 @@ namespace ts { let minArgumentCount = -1; const isJSConstructSignature = isJSDocConstructSignature(declaration); let returnType: Type = undefined; + let typePredicate: TypePredicate = undefined; // If this is a JSDoc construct signature, then skip the first parameter in the // parameter list. The first parameter represents the return type of the construct @@ -4129,6 +4139,9 @@ namespace ts { } else if (declaration.type) { returnType = getTypeFromTypeNode(declaration.type); + if (declaration.type.kind === SyntaxKind.TypePredicate) { + typePredicate = createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode); + } } else { if (declaration.flags & NodeFlags.JavaScriptFile) { @@ -4150,7 +4163,7 @@ namespace ts { } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, hasRestParameter(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -4862,25 +4875,6 @@ namespace ts { return links.resolvedType; } - function getPredicateType(node: TypePredicateNode): Type { - return createPredicateType(getSymbolOfNode(node), createTypePredicateFromTypePredicateNode(node)); - } - - function createPredicateType(symbol: Symbol, predicate: ThisTypePredicate | IdentifierTypePredicate) { - const type = createType(TypeFlags.Boolean | TypeFlags.PredicateType) as PredicateType; - type.symbol = symbol; - type.predicate = predicate; - return type; - } - - function getTypeFromPredicateTypeNode(node: TypePredicateNode): Type { - const links = getNodeLinks(node); - if (!links.resolvedType) { - links.resolvedType = getPredicateType(node); - } - return links.resolvedType; - } - function getTypeFromTypeNode(node: TypeNode): Type { switch (node.kind) { case SyntaxKind.AnyKeyword: @@ -4905,7 +4899,7 @@ namespace ts { case SyntaxKind.JSDocTypeReference: return getTypeFromTypeReference(node); case SyntaxKind.TypePredicate: - return getTypeFromPredicateTypeNode(node); + return booleanType; case SyntaxKind.ExpressionWithTypeArguments: return getTypeFromTypeReference(node); case SyntaxKind.TypeQuery: @@ -5057,6 +5051,7 @@ namespace ts { function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature { let freshTypeParameters: TypeParameter[]; + let freshTypePredicate: TypePredicate; if (signature.typeParameters && !eraseTypeParameters) { // First create a fresh set of type parameters, then include a mapping from the old to the // new type parameters in the mapper function. Finally store this mapper in the new type @@ -5067,9 +5062,13 @@ namespace ts { tp.mapper = mapper; } } + if (signature.typePredicate) { + freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper); + } const result = createSignature(signature.declaration, freshTypeParameters, instantiateList(signature.parameters, mapper, instantiateSymbol), instantiateType(signature.resolvedReturnType, mapper), + freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals); result.target = signature; result.mapper = mapper; @@ -5139,10 +5138,6 @@ namespace ts { if (type.flags & TypeFlags.Intersection) { return getIntersectionType(instantiateList((type).types, mapper, instantiateType)); } - if (type.flags & TypeFlags.PredicateType) { - const predicate = (type as PredicateType).predicate; - return createPredicateType(type.symbol, cloneTypePredicate(predicate, mapper)); - } } return type; } @@ -5288,21 +5283,58 @@ namespace ts { const sourceReturnType = getReturnTypeOfSignature(source); // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions - if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) { - if (!(sourceReturnType.flags & TypeFlags.PredicateType)) { + if (target.typePredicate) { + if (source.typePredicate) { + result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes); + } + else if (isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { errorReporter(Diagnostics.Signature_0_must_have_a_type_predicate, signatureToString(source)); } return Ternary.False; } } + else { + result &= compareTypes(sourceReturnType, targetReturnType, reportErrors); + } - result &= compareTypes(sourceReturnType, targetReturnType, reportErrors); } return result; } + function compareTypePredicateRelatedTo(source: TypePredicate, + target: TypePredicate, + reportErrors: boolean, + errorReporter: (d: DiagnosticMessage, arg0?: string, arg1?: string) => void, + compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary { + if (source.kind !== target.kind) { + if (reportErrors) { + errorReporter(Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); + errorReporter(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); + } + return Ternary.False; + } + + if (source.kind === TypePredicateKind.Identifier) { + const sourceIdentifierPredicate = source as IdentifierTypePredicate; + const targetIdentifierPredicate = target as IdentifierTypePredicate; + if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + if (reportErrors) { + errorReporter(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + errorReporter(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); + } + return Ternary.False; + } + } + + const related = compareTypes(source.type, target.type, reportErrors); + if (related === Ternary.False && reportErrors) { + errorReporter(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); + } + return related; + } + function isImplementationCompatibleWithOverload(implementation: Signature, overload: Signature): boolean { const erasedSource = getErasedSignature(implementation); const erasedTarget = getErasedSignature(overload); @@ -5429,33 +5461,6 @@ namespace ts { if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True; } if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) { - if (source.flags & TypeFlags.PredicateType && target.flags & TypeFlags.PredicateType) { - const sourcePredicate = source as PredicateType; - const targetPredicate = target as PredicateType; - if (sourcePredicate.predicate.kind !== targetPredicate.predicate.kind) { - if (reportErrors) { - reportError(Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); - reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typeToString(source), typeToString(target)); - } - return Ternary.False; - } - if (sourcePredicate.predicate.kind === TypePredicateKind.Identifier) { - const sourceIdentifierPredicate = sourcePredicate.predicate as IdentifierTypePredicate; - const targetIdentifierPredicate = targetPredicate.predicate as IdentifierTypePredicate; - if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { - if (reportErrors) { - reportError(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); - reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typeToString(source), typeToString(target)); - } - return Ternary.False; - } - } - const related = isRelatedTo(sourcePredicate.predicate.type, targetPredicate.predicate.type, reportErrors, headMessage); - if (related === Ternary.False && reportErrors) { - reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typeToString(source), typeToString(target)); - } - return related; - } return Ternary.True; } @@ -6311,9 +6316,6 @@ namespace ts { if (type.flags & (TypeFlags.Undefined | TypeFlags.Null)) { return anyType; } - if (type.flags & TypeFlags.PredicateType) { - return booleanType; - } if (type.flags & TypeFlags.ObjectLiteral) { return getWidenedTypeOfObjectLiteral(type); } @@ -6541,11 +6543,6 @@ namespace ts { inferFromTypes(sourceTypes[i], targetTypes[i]); } } - else if (source.flags & TypeFlags.PredicateType && target.flags & TypeFlags.PredicateType) { - if ((source as PredicateType).predicate.kind === (target as PredicateType).predicate.kind) { - inferFromTypes((source as PredicateType).predicate.type, (target as PredicateType).predicate.type); - } - } else if (source.flags & TypeFlags.Tuple && target.flags & TypeFlags.Tuple && (source).elementTypes.length === (target).elementTypes.length) { // If source and target are tuples of the same size, infer from element types const sourceTypes = (source).elementTypes; @@ -6641,7 +6638,13 @@ namespace ts { function inferFromSignature(source: Signature, target: Signature) { forEachMatchingParameterType(source, target, inferFromTypes); - inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); + + if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) { + inferFromTypes(source.typePredicate.type, target.typePredicate.type); + } + else { + inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); + } } function inferFromIndexTypes(source: Type, target: Type, sourceKind: IndexKind, targetKind: IndexKind) { @@ -7067,46 +7070,33 @@ namespace ts { return originalType; } - function narrowTypeByTypePredicate(type: Type, expr: CallExpression, assumeTrue: boolean): Type { + function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { if (type.flags & TypeFlags.Any) { return type; } - const signature = getResolvedSignature(expr); - const predicateType = getReturnTypeOfSignature(signature); - - if (!predicateType || !(predicateType.flags & TypeFlags.PredicateType)) { + const signature = getResolvedSignature(callExpression); + + const predicate = signature.typePredicate; + if (!predicate) { return type; } - const predicate = (predicateType as PredicateType).predicate; + if (isIdentifierTypePredicate(predicate)) { - const callExpression = expr as CallExpression; if (callExpression.arguments[predicate.parameterIndex] && getSymbolAtTypePredicatePosition(callExpression.arguments[predicate.parameterIndex]) === symbol) { return getNarrowedType(type, predicate.type, assumeTrue); } } else { - const expression = skipParenthesizedNodes(expr.expression); - return narrowTypeByThisTypePredicate(type, predicate, expression, assumeTrue); + const invokedExpression = skipParenthesizedNodes(callExpression.expression); + return narrowTypeByThisTypePredicate(type, predicate, invokedExpression, assumeTrue); } return type; } - function narrowTypeByTypePredicateMember(type: Type, expr: ElementAccessExpression | PropertyAccessExpression, assumeTrue: boolean): Type { - if (type.flags & TypeFlags.Any) { - return type; - } - const memberType = getTypeOfExpression(expr); - if (!(memberType.flags & TypeFlags.PredicateType)) { - return type; - } - - return narrowTypeByThisTypePredicate(type, (memberType as PredicateType).predicate as ThisTypePredicate, expr, assumeTrue); - } - - function narrowTypeByThisTypePredicate(type: Type, predicate: ThisTypePredicate, expression: Expression, assumeTrue: boolean): Type { - if (expression.kind === SyntaxKind.ElementAccessExpression || expression.kind === SyntaxKind.PropertyAccessExpression) { - const accessExpression = expression as ElementAccessExpression | PropertyAccessExpression; + function narrowTypeByThisTypePredicate(type: Type, predicate: ThisTypePredicate, invokedExpression: Expression, assumeTrue: boolean): Type { + if (invokedExpression.kind === SyntaxKind.ElementAccessExpression || invokedExpression.kind === SyntaxKind.PropertyAccessExpression) { + const accessExpression = invokedExpression as ElementAccessExpression | PropertyAccessExpression; const possibleIdentifier = skipParenthesizedNodes(accessExpression.expression); if (possibleIdentifier.kind === SyntaxKind.Identifier && getSymbolAtTypePredicatePosition(possibleIdentifier) === symbol) { return getNarrowedType(type, predicate.type, assumeTrue); @@ -7121,6 +7111,7 @@ namespace ts { case SyntaxKind.Identifier: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.QualifiedName: + // TODO (drosen): Why a qualified name? return getSymbolOfEntityNameOrPropertyAccessExpression(expr as Node as (EntityName | PropertyAccessExpression)); } } @@ -7153,9 +7144,6 @@ namespace ts { return narrowType(type, (expr).operand, !assumeTrue); } break; - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.PropertyAccessExpression: - return narrowTypeByTypePredicateMember(type, expr as (ElementAccessExpression | PropertyAccessExpression), assumeTrue); } return type; } @@ -10544,12 +10532,13 @@ namespace ts { return aggregatedTypes; } - /* - *TypeScript Specification 1.0 (6.3) - July 2014 - * An explicitly typed function whose return type isn't the Void type, - * the Any type, or a union type containing the Void or Any type as a constituent - * must have at least one return statement somewhere in its body. - * An exception to this rule is if the function implementation consists of a single 'throw' statement. + /** + * TypeScript Specification 1.0 (6.3) - July 2014 + * An explicitly typed function whose return type isn't the Void type, + * the Any type, or a union type containing the Void or Any type as a constituent + * must have at least one return statement somewhere in its body. + * An exception to this rule is if the function implementation consists of a single 'throw' statement. + * * @param returnType - return type of the function, can be undefined if return type is not explicitly specified */ function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: FunctionLikeDeclaration, returnType: Type): void { @@ -11579,16 +11568,16 @@ namespace ts { if (!parent) { return; } - const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(parent)); - if (!returnType || !(returnType.flags & TypeFlags.PredicateType)) { + const typePredicate = getSignatureFromDeclaration(parent).typePredicate; + if (!typePredicate) { return; } + const { parameterName } = node; - if (parameterName.kind === SyntaxKind.ThisType) { + if (isThisTypePredicate(typePredicate)) { getTypeFromThisTypeNode(parameterName as ThisTypeNode); } else { - const typePredicate = (returnType).predicate; if (typePredicate.parameterIndex >= 0) { if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) { error(parameterName, @@ -11603,12 +11592,8 @@ namespace ts { else if (parameterName) { let hasReportedError = false; for (const { name } of parent.parameters) { - if ((name.kind === SyntaxKind.ObjectBindingPattern || - name.kind === SyntaxKind.ArrayBindingPattern) && - checkIfTypePredicateVariableIsDeclaredInBindingPattern( - name, - parameterName, - typePredicate.parameterName)) { + if (isBindingPattern(name) && + checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { hasReportedError = true; break; } @@ -11676,8 +11661,9 @@ namespace ts { forEach(node.parameters, checkParameter); - checkSourceElement(node.type); - + if (node.type) { + checkSourceElement(node.type); + } if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); @@ -13634,7 +13620,7 @@ namespace ts { error(node.expression, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } - else if (func.type || isGetAccessorWithAnnotatedSetAccessor(func) || returnType.flags & TypeFlags.PredicateType) { + else if (func.type || isGetAccessorWithAnnotatedSetAccessor(func)) { if (isAsyncFunctionLike(func)) { const promisedType = getPromisedType(returnType); const awaitedType = checkAwaitedType(exprType, node.expression, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6b9f49cac01..7f88879c75f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1749,6 +1749,7 @@ namespace ts { buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; @@ -1814,22 +1815,24 @@ namespace ts { Identifier } - export interface TypePredicate { + export interface TypePredicateBase { kind: TypePredicateKind; type: Type; } // @kind (TypePredicateKind.This) - export interface ThisTypePredicate extends TypePredicate { + export interface ThisTypePredicate extends TypePredicateBase { _thisTypePredicateBrand: any; } // @kind (TypePredicateKind.Identifier) - export interface IdentifierTypePredicate extends TypePredicate { + export interface IdentifierTypePredicate extends TypePredicateBase { parameterName: string; parameterIndex: number; } + export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate; + /* @internal */ export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration; @@ -2095,7 +2098,6 @@ namespace ts { ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6 ThisType = 0x02000000, // This type ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties - PredicateType = 0x08000000, // Predicate types are also Boolean types, but should not be considered Intrinsics - there's no way to capture this with flags /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null, @@ -2107,7 +2109,7 @@ namespace ts { UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, /* @internal */ - RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral | PredicateType, + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral, /* @internal */ PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType } @@ -2128,11 +2130,6 @@ namespace ts { intrinsicName: string; // Name of intrinsic type } - // Predicate types (TypeFlags.Predicate) - export interface PredicateType extends Type { - predicate: ThisTypePredicate | IdentifierTypePredicate; - } - // String literal types (TypeFlags.StringLiteral) export interface StringLiteralType extends Type { text: string; // Text of string literal @@ -2267,6 +2264,8 @@ namespace ts { erasedSignatureCache?: Signature; // Erased version of signature (deferred) /* @internal */ isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison + /* @internal */ + typePredicate?: TypePredicate; } export const enum IndexKind { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0903d937d7b..4df8d723f5e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -746,6 +746,10 @@ namespace ts { return predicate && predicate.kind === TypePredicateKind.Identifier; } + export function isThisTypePredicate(predicate: TypePredicate): predicate is ThisTypePredicate { + return predicate && predicate.kind === TypePredicateKind.This; + } + export function getContainingFunction(node: Node): FunctionLikeDeclaration { while (true) { node = node.parent; From 7c7e2aa032e6312a0ca4dcb3f2d7870153ca7298 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Jan 2016 17:23:56 -0800 Subject: [PATCH 06/22] Error on nodes which should not have type predicates. --- src/compiler/checker.ts | 5 ++++- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9b7b2bd12c8..3ee1f2c6b72 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11563,11 +11563,14 @@ namespace ts { return -1; } - function checkTypePredicate(node: TypePredicateNode) { + function checkTypePredicate(node: TypePredicateNode): void { const parent = getTypePredicateParent(node); if (!parent) { + // The parent must not be valid. + error(node.parent, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); return; } + const typePredicate = getSignatureFromDeclaration(parent).typePredicate; if (!typePredicate) { return; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 25b86e67d34..2c8de840fc0 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -723,6 +723,10 @@ "category": "Error", "code": 1227 }, + "A type predicate is only allowed in return type position for functions and methods.": { + "category": "Error", + "code": 1228 + }, "A type predicate cannot reference a rest parameter.": { "category": "Error", "code": 1229 From ec0eabb2e9843a654c5e07ddf100f4e8df2a9a1f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Jan 2016 17:25:40 -0800 Subject: [PATCH 07/22] Minor rename. --- src/compiler/parser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 66d33f9d7d9..ee9eee6a62b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1937,7 +1937,7 @@ namespace ts { return finishNode(node); } - function parseTypePredicate(lhs: Identifier | ThisTypeNode): TypePredicateNode { + function parseThisTypePredicate(lhs: Identifier | ThisTypeNode): TypePredicateNode { nextToken(); const node = createNode(SyntaxKind.TypePredicate, lhs.pos) as TypePredicateNode; node.parameterName = lhs; @@ -2362,7 +2362,7 @@ namespace ts { case SyntaxKind.ThisKeyword: { const thisKeyword = parseThisTypeNode(); if (token === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { - return parseTypePredicate(thisKeyword); + return parseThisTypePredicate(thisKeyword); } else { return thisKeyword; From 050f52f07de838c75fcaaafe6ac3165da883e50a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Jan 2016 18:00:23 -0800 Subject: [PATCH 08/22] Added tests. --- .../typeGuards/typePredicateOnVariableDeclaration01.ts | 3 +++ .../typeGuards/typePredicateOnVariableDeclaration02.ts | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration01.ts create mode 100644 tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts diff --git a/tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration01.ts b/tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration01.ts new file mode 100644 index 00000000000..a445e18ee40 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration01.ts @@ -0,0 +1,3 @@ +// @declaration: true + +var x: this is string; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts b/tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts new file mode 100644 index 00000000000..4b010287337 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts @@ -0,0 +1,3 @@ +// @declaration: true + +var y: z is number; \ No newline at end of file From b191a00b1c7fb2ce6c5adbb6213e808d446ce500 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Jan 2016 18:04:48 -0800 Subject: [PATCH 09/22] Actually, it makes more sense to error on the predicate annotation than anything else. --- 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 3ee1f2c6b72..dcaa5f97d78 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11567,7 +11567,7 @@ namespace ts { const parent = getTypePredicateParent(node); if (!parent) { // The parent must not be valid. - error(node.parent, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); + error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); return; } From ab5bc714a5169a3218b3ce2ed3a941c21af9f9eb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 29 Jan 2016 16:58:19 -0800 Subject: [PATCH 10/22] Removed trailing whitespace for linter. --- 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 dcaa5f97d78..e90623e24f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7075,7 +7075,7 @@ namespace ts { return type; } const signature = getResolvedSignature(callExpression); - + const predicate = signature.typePredicate; if (!predicate) { return type; From ba392403cc125cf2b3702b21b76521e02753d551 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 29 Jan 2016 17:03:16 -0800 Subject: [PATCH 11/22] Fixed up fourslash tests to only test functions. --- .../thisPredicateFunctionCompletions01.ts | 52 ++++++++ .../thisPredicateFunctionCompletions02.ts | 43 +++++++ ... => thisPredicateFunctionCompletions03.ts} | 0 .../thisPredicateFunctionQuickInfo01.ts | 59 +++++++++ .../thisPredicateFunctionQuickInfo02.ts | 57 +++++++++ .../thisPredicateMemberCompletions.ts | 95 -------------- .../fourslash/thisPredicateMemberQuickInfo.ts | 117 ------------------ 7 files changed, 211 insertions(+), 212 deletions(-) create mode 100644 tests/cases/fourslash/thisPredicateFunctionCompletions01.ts create mode 100644 tests/cases/fourslash/thisPredicateFunctionCompletions02.ts rename tests/cases/fourslash/{thisPredicateFunctionCompletions.ts => thisPredicateFunctionCompletions03.ts} (100%) create mode 100644 tests/cases/fourslash/thisPredicateFunctionQuickInfo01.ts create mode 100644 tests/cases/fourslash/thisPredicateFunctionQuickInfo02.ts delete mode 100644 tests/cases/fourslash/thisPredicateMemberCompletions.ts delete mode 100644 tests/cases/fourslash/thisPredicateMemberQuickInfo.ts diff --git a/tests/cases/fourslash/thisPredicateFunctionCompletions01.ts b/tests/cases/fourslash/thisPredicateFunctionCompletions01.ts new file mode 100644 index 00000000000..8c9abb85418 --- /dev/null +++ b/tests/cases/fourslash/thisPredicateFunctionCompletions01.ts @@ -0,0 +1,52 @@ +/// + +//// class FileSystemObject { +//// isFile(): this is Item { +//// return this instanceof Item; +//// } +//// isDirectory(): this is Directory { +//// return this instanceof Directory; +//// } +//// isNetworked(): this is (Networked & this) { +//// return !!(this as Networked).host; +//// } +//// constructor(public path: string) {} +//// } +//// +//// class Item extends FileSystemObject { +//// constructor(path: string, public content: string) { super(path); } +//// } +//// class Directory extends FileSystemObject { +//// children: FileSystemObject[]; +//// } +//// interface Networked { +//// host: string; +//// } +//// +//// const obj: FileSystemObject = new Item("/foo", ""); +//// if (obj.isFile()) { +//// obj./*1*/; +//// if (obj.isNetworked()) { +//// obj./*2*/; +//// } +//// } +//// if (obj.isDirectory()) { +//// obj./*3*/; +//// if (obj.isNetworked()) { +//// obj./*4*/; +//// } +//// } +//// if (obj.isNetworked()) { +//// obj./*5*/; +//// } + +goTo.marker("1"); +verify.completionListContains("content"); +goTo.marker("2"); +verify.completionListContains("host"); +goTo.marker("3"); +verify.completionListContains("children"); +goTo.marker("4"); +verify.completionListContains("host"); +goTo.marker("5"); +verify.completionListContains("host"); \ No newline at end of file diff --git a/tests/cases/fourslash/thisPredicateFunctionCompletions02.ts b/tests/cases/fourslash/thisPredicateFunctionCompletions02.ts new file mode 100644 index 00000000000..e2e311ea649 --- /dev/null +++ b/tests/cases/fourslash/thisPredicateFunctionCompletions02.ts @@ -0,0 +1,43 @@ +/// + +//// interface Sundries { +//// broken: boolean; +//// } +//// +//// interface Supplies { +//// spoiled: boolean; +//// } +//// +//// interface Crate { +//// contents: T; +//// isSundries(): this is Crate; +//// isSupplies(): this is Crate; +//// isPackedTight(): this is (this & {extraContents: T}); +//// } +//// const crate: Crate; +//// if (crate.isPackedTight()) { +//// crate./*1*/; +//// } +//// if (crate.isSundries()) { +//// crate.contents./*2*/; +//// if (crate.isPackedTight()) { +//// crate./*3*/; +//// } +//// } +//// if (crate.isSupplies()) { +//// crate.contents./*4*/; +//// if (crate.isPackedTight()) { +//// crate./*5*/; +//// } +//// } + +goTo.marker("1"); +verify.completionListContains("extraContents"); +goTo.marker("2"); +verify.completionListContains("broken"); +goTo.marker("3"); +verify.completionListContains("extraContents"); +goTo.marker("4"); +verify.completionListContains("spoiled"); +goTo.marker("5"); +verify.completionListContains("extraContents"); \ No newline at end of file diff --git a/tests/cases/fourslash/thisPredicateFunctionCompletions.ts b/tests/cases/fourslash/thisPredicateFunctionCompletions03.ts similarity index 100% rename from tests/cases/fourslash/thisPredicateFunctionCompletions.ts rename to tests/cases/fourslash/thisPredicateFunctionCompletions03.ts diff --git a/tests/cases/fourslash/thisPredicateFunctionQuickInfo01.ts b/tests/cases/fourslash/thisPredicateFunctionQuickInfo01.ts new file mode 100644 index 00000000000..135df559189 --- /dev/null +++ b/tests/cases/fourslash/thisPredicateFunctionQuickInfo01.ts @@ -0,0 +1,59 @@ +/// + +//// class FileSystemObject { +//// /*1*/isFile(): this is Item { +//// return this instanceof Item; +//// } +//// /*2*/isDirectory(): this is Directory { +//// return this instanceof Directory; +//// } +//// /*3*/isNetworked(): this is (Networked & this) { +//// return !!(this as Networked).host; +//// } +//// constructor(public path: string) {} +//// } +//// +//// class Item extends FileSystemObject { +//// constructor(path: string, public content: string) { super(path); } +//// } +//// class Directory extends FileSystemObject { +//// children: FileSystemObject[]; +//// } +//// interface Networked { +//// host: string; +//// } +//// +//// const obj: FileSystemObject = new Item("/foo", ""); +//// if (obj.isFile/*4*/()) { +//// obj.; +//// if (obj.isNetworked/*5*/()) { +//// obj.; +//// } +//// } +//// if (obj.isDirectory/*6*/()) { +//// obj.; +//// if (obj.isNetworked/*7*/()) { +//// obj.; +//// } +//// } +//// if (obj.isNetworked/*8*/()) { +//// obj.; +//// } + +goTo.marker("1"); +verify.quickInfoIs("(method) FileSystemObject.isFile(): this is Item"); +goTo.marker("2"); +verify.quickInfoIs("(method) FileSystemObject.isDirectory(): this is Directory"); +goTo.marker("3"); +verify.quickInfoIs("(method) FileSystemObject.isNetworked(): this is Networked & this"); + +goTo.marker("4"); +verify.quickInfoIs("(method) FileSystemObject.isFile(): this is Item"); +goTo.marker("5"); +verify.quickInfoIs("(method) FileSystemObject.isNetworked(): this is Networked & Item"); +goTo.marker("6"); +verify.quickInfoIs("(method) FileSystemObject.isDirectory(): this is Directory"); +goTo.marker("7"); +verify.quickInfoIs("(method) FileSystemObject.isNetworked(): this is Networked & Directory"); +goTo.marker("8"); +verify.quickInfoIs("(method) FileSystemObject.isNetworked(): this is Networked & FileSystemObject"); \ No newline at end of file diff --git a/tests/cases/fourslash/thisPredicateFunctionQuickInfo02.ts b/tests/cases/fourslash/thisPredicateFunctionQuickInfo02.ts new file mode 100644 index 00000000000..b8135026c82 --- /dev/null +++ b/tests/cases/fourslash/thisPredicateFunctionQuickInfo02.ts @@ -0,0 +1,57 @@ +/// + +//// interface Sundries { +//// broken: boolean; +//// } +//// +//// interface Supplies { +//// spoiled: boolean; +//// } +//// +//// interface Crate { +//// contents: T; +//// /*1*/isSundries(): this is Crate; +//// /*2*/isSupplies(): this is Crate; +//// /*3*/isPackedTight(): this is (this & {extraContents: T}); +//// } +//// const crate: Crate; +//// if (crate.isPackedTight/*4*/()) { +//// crate.; +//// } +//// if (crate.isSundries/*5*/()) { +//// crate.contents.; +//// if (crate.isPackedTight/*6*/()) { +//// crate.; +//// } +//// } +//// if (crate.isSupplies/*7*/()) { +//// crate.contents.; +//// if (crate.isPackedTight/*8*/()) { +//// crate.; +//// } +//// } + +goTo.marker("1"); +verify.quickInfoIs("(method) Crate.isSundries(): this is Crate"); +goTo.marker("2"); +verify.quickInfoIs("(method) Crate.isSupplies(): this is Crate"); +goTo.marker("3"); +verify.quickInfoIs(`(method) Crate.isPackedTight(): this is this & { + extraContents: T; +}`); +goTo.marker("4"); +verify.quickInfoIs(`(method) Crate.isPackedTight(): this is Crate & { + extraContents: any; +}`); +goTo.marker("5"); +verify.quickInfoIs("(method) Crate.isSundries(): this is Crate"); +goTo.marker("6"); +verify.quickInfoIs(`(method) Crate.isPackedTight(): this is Crate & { + extraContents: Sundries; +}`); +goTo.marker("7"); +verify.quickInfoIs("(method) Crate.isSupplies(): this is Crate"); +goTo.marker("8"); +verify.quickInfoIs(`(method) Crate.isPackedTight(): this is Crate & { + extraContents: Supplies; +}`); \ No newline at end of file diff --git a/tests/cases/fourslash/thisPredicateMemberCompletions.ts b/tests/cases/fourslash/thisPredicateMemberCompletions.ts deleted file mode 100644 index 24ce742faac..00000000000 --- a/tests/cases/fourslash/thisPredicateMemberCompletions.ts +++ /dev/null @@ -1,95 +0,0 @@ -/// - -//// class FileSystemObject { -//// get is/*1*/File(): this is Item { -//// return this instanceof Item; -//// } -//// set is/*2*/File(param) { -//// // noop -//// } -//// get is/*3*/Directory(): this is Directory { -//// return this instanceof Directory; -//// } -//// is/*4*/Networked: this is (Networked & this); -//// constructor(public path: string) {} -//// } -//// -//// class Item extends FileSystemObject { -//// constructor(path: string, public content: string) { super(path); } -//// } -//// class Directory extends FileSystemObject { -//// children: FileSystemObject[]; -//// } -//// interface Networked { -//// host: string; -//// } -//// -//// interface Sundries { -//// broken: boolean; -//// } -//// -//// interface Supplies { -//// spoiled: boolean; -//// } -//// -//// interface Crate { -//// contents: T; -//// is/*5*/Sundries: this is Crate; -//// is/*6*/Supplies: this is Crate; -//// is/*7*/PackedTight: this is (this & {extraContents: T}); -//// } -//// -//// const obj: FileSystemObject = new Item("/foo", ""); -//// if (obj.is/*8*/File) { -//// obj./*9*/; -//// if (obj.is/*10*/Networked) { -//// obj./*11*/; -//// } -//// } -//// if (obj.is/*12*/Directory) { -//// obj./*13*/; -//// if (obj.is/*14*/Networked) { -//// obj./*15*/; -//// } -//// } -//// if (obj.is/*16*/Networked) { -//// obj./*17*/; -//// } -//// -//// const crate: Crate; -//// if (crate.is/*18*/PackedTight) { -//// crate./*19*/; -//// } -//// if (crate.is/*20*/Sundries) { -//// crate.contents./*21*/; -//// if (crate.is/*22*/PackedTight) { -//// crate./*23*/ -//// } -//// } -//// if (crate.is/*24*/Supplies) { -//// crate.contents./*25*/; -//// if (crate.is/*26*/PackedTight) { -//// crate./*27*/ -//// } -//// } - -goTo.marker("9"); -verify.completionListContains("content"); -goTo.marker("11"); -verify.completionListContains("host"); -goTo.marker("13"); -verify.completionListContains("children"); -goTo.marker("15"); -verify.completionListContains("host"); -goTo.marker("17"); -verify.completionListContains("host"); -goTo.marker("19"); -verify.completionListContains("extraContents"); -goTo.marker("21"); -verify.completionListContains("broken"); -goTo.marker("23"); -verify.completionListContains("extraContents"); -goTo.marker("25"); -verify.completionListContains("spoiled"); -goTo.marker("27"); -verify.completionListContains("extraContents"); \ No newline at end of file diff --git a/tests/cases/fourslash/thisPredicateMemberQuickInfo.ts b/tests/cases/fourslash/thisPredicateMemberQuickInfo.ts deleted file mode 100644 index 20d519e0008..00000000000 --- a/tests/cases/fourslash/thisPredicateMemberQuickInfo.ts +++ /dev/null @@ -1,117 +0,0 @@ -/// - -//// class FileSystemObject { -//// get is/*1*/File(): this is Item { -//// return this instanceof Item; -//// } -//// set is/*2*/File(param) { -//// // noop -//// } -//// get is/*3*/Directory(): this is Directory { -//// return this instanceof Directory; -//// } -//// is/*4*/Networked: this is (Networked & this); -//// constructor(public path: string) {} -//// } -//// -//// class Item extends FileSystemObject { -//// constructor(path: string, public content: string) { super(path); } -//// } -//// class Directory extends FileSystemObject { -//// children: FileSystemObject[]; -//// } -//// interface Networked { -//// host: string; -//// } -//// -//// interface Sundries { -//// broken: boolean; -//// } -//// -//// interface Supplies { -//// spoiled: boolean; -//// } -//// -//// interface Crate { -//// contents: T; -//// is/*5*/Sundries: this is Crate; -//// is/*6*/Supplies: this is Crate; -//// is/*7*/PackedTight: this is (this & {extraContents: T}); -//// } -//// -//// const obj: FileSystemObject = new Item("/foo", ""); -//// if (obj.is/*8*/File) { -//// obj./*9*/; -//// if (obj.is/*10*/Networked) { -//// obj./*11*/; -//// } -//// } -//// if (obj.is/*12*/Directory) { -//// obj./*13*/; -//// if (obj.is/*14*/Networked) { -//// obj./*15*/; -//// } -//// } -//// if (obj.is/*16*/Networked) { -//// obj./*17*/; -//// } -//// -//// const crate: Crate; -//// if (crate.is/*18*/PackedTight) { -//// crate./*19*/; -//// } -//// if (crate.is/*20*/Sundries) { -//// crate.contents./*21*/; -//// if (crate.is/*22*/PackedTight) { -//// crate./*23*/ -//// } -//// } -//// if (crate.is/*24*/Supplies) { -//// crate.contents./*25*/; -//// if (crate.is/*26*/PackedTight) { -//// crate./*27*/ -//// } -//// } - -goTo.marker("1"); -verify.quickInfoIs("(property) FileSystemObject.isFile: this is Item"); -goTo.marker("2"); -verify.quickInfoIs("(property) FileSystemObject.isFile: this is Item"); -goTo.marker("3"); -verify.quickInfoIs("(property) FileSystemObject.isDirectory: this is Directory"); -goTo.marker("4"); -verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & this"); -goTo.marker("5"); -verify.quickInfoIs("(property) Crate.isSundries: this is Crate"); -goTo.marker("6"); -verify.quickInfoIs("(property) Crate.isSupplies: this is Crate"); -goTo.marker("7"); -verify.quickInfoIs(`(property) Crate.isPackedTight: this is this & { - extraContents: T; -}`); -goTo.marker("8"); -verify.quickInfoIs("(property) FileSystemObject.isFile: this is Item"); -goTo.marker("10"); -verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & Item"); -goTo.marker("12"); -verify.quickInfoIs("(property) FileSystemObject.isDirectory: this is Directory"); -goTo.marker("14"); -verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & Directory"); -goTo.marker("16"); -verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & FileSystemObject"); -goTo.marker("18"); -verify.quickInfoIs(`(property) Crate.isPackedTight: this is Crate & { - extraContents: any; -}`); -goTo.marker("20"); -verify.quickInfoIs("(property) Crate.isSundries: this is Crate"); -goTo.marker("22"); -verify.quickInfoIs(`(property) Crate.isPackedTight: this is Crate & { - extraContents: Sundries; -}`); -goTo.marker("24"); -verify.quickInfoIs("(property) Crate.isSupplies: this is Crate"); -goTo.marker("26"); -verify.quickInfoIs(`(property) Crate.isPackedTight: this is Crate & { - extraContents: Supplies; -}`); \ No newline at end of file From f944d3e997792d21b2162cd0e2507fe85d4298d5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 10 Feb 2016 15:19:27 -0800 Subject: [PATCH 12/22] Addressed CR feedback. --- src/compiler/checker.ts | 4 +--- src/compiler/parser.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e90623e24f8..2fc3245b701 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7110,9 +7110,7 @@ namespace ts { switch (expr.kind) { case SyntaxKind.Identifier: case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.QualifiedName: - // TODO (drosen): Why a qualified name? - return getSymbolOfEntityNameOrPropertyAccessExpression(expr as Node as (EntityName | PropertyAccessExpression)); + return getSymbolOfEntityNameOrPropertyAccessExpression(expr as (Identifier | PropertyAccessExpression)); } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ee9eee6a62b..65fec19126b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1937,7 +1937,7 @@ namespace ts { return finishNode(node); } - function parseThisTypePredicate(lhs: Identifier | ThisTypeNode): TypePredicateNode { + function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode { nextToken(); const node = createNode(SyntaxKind.TypePredicate, lhs.pos) as TypePredicateNode; node.parameterName = lhs; From 1e2760696ecc00cefa7c8db16cf6af03107f08e4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 12 Feb 2016 14:12:21 -0800 Subject: [PATCH 13/22] Added tests for declaration emit. --- .../declarationEmitIdentifierPredicates01.ts | 6 ++++++ ...onEmitIdentifierPredicatesWithPrivateName01.ts | 10 ++++++++++ .../declarationEmitThisPredicates01.ts | 11 +++++++++++ .../declarationEmitThisPredicates02.ts | 15 +++++++++++++++ ...larationEmitThisPredicatesWithPrivateName01.ts | 11 +++++++++++ ...larationEmitThisPredicatesWithPrivateName02.ts | 15 +++++++++++++++ 6 files changed, 68 insertions(+) create mode 100644 tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts create mode 100644 tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts create mode 100644 tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates01.ts create mode 100644 tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts create mode 100644 tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts create mode 100644 tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts new file mode 100644 index 00000000000..c4a223f07ef --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts @@ -0,0 +1,6 @@ +// @declaration: true +// @module: commonjs + +export function f(x: any): x is number { + return typeof x === "number"; +} \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts new file mode 100644 index 00000000000..1398b2bc040 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts @@ -0,0 +1,10 @@ +// @declaration: true +// @module: commonjs + +interface I { + a: number; +} + +export function f(x: any): x is I { + return typeof x.a === "number"; +} \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates01.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates01.ts new file mode 100644 index 00000000000..69af9c5b077 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates01.ts @@ -0,0 +1,11 @@ +// @declaration: true +// @module: commonjs + +export class C { + m(): this is D { + return this instanceof D; + } +} + +export class D extends C { +} \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts new file mode 100644 index 00000000000..02f2a798831 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts @@ -0,0 +1,15 @@ +// @declaration: true +// @module: commonjs + +export interface Foo { + a: string; + b: number; + c: boolean; +} + +export const obj = { + m(): this is Foo { + let dis = this as Foo; + return dis.a != null && dis.b != null && dis.c != null; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts new file mode 100644 index 00000000000..461c7d17571 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts @@ -0,0 +1,11 @@ +// @declaration: true +// @module: commonjs + +export class C { + m(): this is D { + return this instanceof D; + } +} + +class D extends C { +} \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts new file mode 100644 index 00000000000..c238bb16ec8 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts @@ -0,0 +1,15 @@ +// @declaration: true +// @module: commonjs + +interface Foo { + a: string; + b: number; + c: boolean; +} + +export const obj = { + m(): this is Foo { + let dis = this as Foo; + return dis.a != null && dis.b != null && dis.c != null; + } +} \ No newline at end of file From 1e849f895ce82a439a08563dd5a32d0492e8ffa3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 12 Feb 2016 16:28:48 -0800 Subject: [PATCH 14/22] Accepted baselines. --- .../arrayBufferIsViewNarrowsType.types | 2 +- ...larationEmitIdentifierPredicates01.symbols | 10 + ...eclarationEmitIdentifierPredicates01.types | 13 + ...fierPredicatesWithPrivateName01.errors.txt | 14 + .../declarationEmitThisPredicates01.symbols | 19 ++ .../declarationEmitThisPredicates01.types | 20 ++ ...declarationEmitThisPredicates02.errors.txt | 19 ++ ...ThisPredicatesWithPrivateName01.errors.txt | 15 ++ ...ThisPredicatesWithPrivateName02.errors.txt | 22 ++ tests/baselines/reference/isArray.types | 2 +- .../stringLiteralCheckedInIf02.types | 2 +- .../stringLiteralTypesAsTags01.types | 4 +- .../stringLiteralTypesAsTags02.types | 4 +- .../stringLiteralTypesAsTags03.types | 4 +- .../stringLiteralTypesTypePredicates01.types | 4 +- .../reference/typeGuardFunction.types | 14 +- .../typeGuardFunctionErrors.errors.txt | 18 +- .../reference/typeGuardFunctionGenerics.types | 4 +- .../typeGuardFunctionOfFormThis.types | 36 +-- .../typeGuardOfFormFunctionEquality.symbols | 41 +++ .../typeGuardOfFormFunctionEquality.types | 54 ++++ .../reference/typeGuardOfFormIsType.types | 16 +- .../typeGuardOfFormIsTypeOnInterfaces.types | 16 +- .../typeGuardOfFormThisMember.errors.txt | 130 +++++++++ .../typeGuardOfFormThisMember.symbols | 240 ----------------- .../reference/typeGuardOfFormThisMember.types | 254 ------------------ ...typeGuardOfFormThisMemberErrors.errors.txt | 30 +-- ...redicateOnVariableDeclaration01.errors.txt | 8 + ...redicateOnVariableDeclaration02.errors.txt | 20 ++ .../unionAndIntersectionInference1.types | 4 +- 30 files changed, 469 insertions(+), 570 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitIdentifierPredicates01.symbols create mode 100644 tests/baselines/reference/declarationEmitIdentifierPredicates01.types create mode 100644 tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.errors.txt create mode 100644 tests/baselines/reference/declarationEmitThisPredicates01.symbols create mode 100644 tests/baselines/reference/declarationEmitThisPredicates01.types create mode 100644 tests/baselines/reference/declarationEmitThisPredicates02.errors.txt create mode 100644 tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.errors.txt create mode 100644 tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt create mode 100644 tests/baselines/reference/typeGuardOfFormFunctionEquality.symbols create mode 100644 tests/baselines/reference/typeGuardOfFormFunctionEquality.types create mode 100644 tests/baselines/reference/typeGuardOfFormThisMember.errors.txt delete mode 100644 tests/baselines/reference/typeGuardOfFormThisMember.symbols delete mode 100644 tests/baselines/reference/typeGuardOfFormThisMember.types create mode 100644 tests/baselines/reference/typePredicateOnVariableDeclaration01.errors.txt create mode 100644 tests/baselines/reference/typePredicateOnVariableDeclaration02.errors.txt diff --git a/tests/baselines/reference/arrayBufferIsViewNarrowsType.types b/tests/baselines/reference/arrayBufferIsViewNarrowsType.types index b9d4f3db81b..129b7d601d8 100644 --- a/tests/baselines/reference/arrayBufferIsViewNarrowsType.types +++ b/tests/baselines/reference/arrayBufferIsViewNarrowsType.types @@ -4,7 +4,7 @@ var obj: Object; >Object : Object if (ArrayBuffer.isView(obj)) { ->ArrayBuffer.isView(obj) : arg is ArrayBufferView +>ArrayBuffer.isView(obj) : boolean >ArrayBuffer.isView : (arg: any) => arg is ArrayBufferView >ArrayBuffer : ArrayBufferConstructor >isView : (arg: any) => arg is ArrayBufferView diff --git a/tests/baselines/reference/declarationEmitIdentifierPredicates01.symbols b/tests/baselines/reference/declarationEmitIdentifierPredicates01.symbols new file mode 100644 index 00000000000..eb8b1151ceb --- /dev/null +++ b/tests/baselines/reference/declarationEmitIdentifierPredicates01.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts === + +export function f(x: any): x is number { +>f : Symbol(f, Decl(declarationEmitIdentifierPredicates01.ts, 0, 0)) +>x : Symbol(x, Decl(declarationEmitIdentifierPredicates01.ts, 1, 18)) +>x : Symbol(x, Decl(declarationEmitIdentifierPredicates01.ts, 1, 18)) + + return typeof x === "number"; +>x : Symbol(x, Decl(declarationEmitIdentifierPredicates01.ts, 1, 18)) +} diff --git a/tests/baselines/reference/declarationEmitIdentifierPredicates01.types b/tests/baselines/reference/declarationEmitIdentifierPredicates01.types new file mode 100644 index 00000000000..7d8a5668265 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIdentifierPredicates01.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts === + +export function f(x: any): x is number { +>f : (x: any) => x is number +>x : any +>x : any + + return typeof x === "number"; +>typeof x === "number" : boolean +>typeof x : string +>x : any +>"number" : string +} diff --git a/tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.errors.txt b/tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.errors.txt new file mode 100644 index 00000000000..e9084c45490 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts(6,33): error TS4060: Return type of exported function has or is using private name 'I'. + + +==== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts (1 errors) ==== + + interface I { + a: number; + } + + export function f(x: any): x is I { + ~ +!!! error TS4060: Return type of exported function has or is using private name 'I'. + return typeof x.a === "number"; + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitThisPredicates01.symbols b/tests/baselines/reference/declarationEmitThisPredicates01.symbols new file mode 100644 index 00000000000..d57f937d6c5 --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicates01.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates01.ts === + +export class C { +>C : Symbol(C, Decl(declarationEmitThisPredicates01.ts, 0, 0)) + + m(): this is D { +>m : Symbol(m, Decl(declarationEmitThisPredicates01.ts, 1, 16)) +>D : Symbol(D, Decl(declarationEmitThisPredicates01.ts, 5, 1)) + + return this instanceof D; +>this : Symbol(C, Decl(declarationEmitThisPredicates01.ts, 0, 0)) +>D : Symbol(D, Decl(declarationEmitThisPredicates01.ts, 5, 1)) + } +} + +export class D extends C { +>D : Symbol(D, Decl(declarationEmitThisPredicates01.ts, 5, 1)) +>C : Symbol(C, Decl(declarationEmitThisPredicates01.ts, 0, 0)) +} diff --git a/tests/baselines/reference/declarationEmitThisPredicates01.types b/tests/baselines/reference/declarationEmitThisPredicates01.types new file mode 100644 index 00000000000..9d801a40965 --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicates01.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates01.ts === + +export class C { +>C : C + + m(): this is D { +>m : () => this is D +>D : D + + return this instanceof D; +>this instanceof D : boolean +>this : this +>D : typeof D + } +} + +export class D extends C { +>D : D +>C : C +} diff --git a/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt b/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt new file mode 100644 index 00000000000..4d95cf01136 --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts(9,10): error TS2526: A 'this' type is available only in a non-static member of a class or interface. + + +==== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts (1 errors) ==== + + export interface Foo { + a: string; + b: number; + c: boolean; + } + + export const obj = { + m(): this is Foo { + ~~~~ +!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface. + let dis = this as Foo; + return dis.a != null && dis.b != null && dis.c != null; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.errors.txt b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.errors.txt new file mode 100644 index 00000000000..67c76283f80 --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts(3,18): error TS4055: Return type of public method from exported class has or is using private name 'D'. + + +==== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts (1 errors) ==== + + export class C { + m(): this is D { + ~ +!!! error TS4055: Return type of public method from exported class has or is using private name 'D'. + return this instanceof D; + } + } + + class D extends C { + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt new file mode 100644 index 00000000000..86c0f478133 --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt @@ -0,0 +1,22 @@ +tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts(8,14): error TS4025: Exported variable 'obj' has or is using private name 'Foo'. +tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts(9,10): error TS2526: A 'this' type is available only in a non-static member of a class or interface. + + +==== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts (2 errors) ==== + + interface Foo { + a: string; + b: number; + c: boolean; + } + + export const obj = { + ~~~ +!!! error TS4025: Exported variable 'obj' has or is using private name 'Foo'. + m(): this is Foo { + ~~~~ +!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface. + let dis = this as Foo; + return dis.a != null && dis.b != null && dis.c != null; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/isArray.types b/tests/baselines/reference/isArray.types index de54e9d064c..bc452b12bef 100644 --- a/tests/baselines/reference/isArray.types +++ b/tests/baselines/reference/isArray.types @@ -4,7 +4,7 @@ var maybeArray: number | number[]; if (Array.isArray(maybeArray)) { ->Array.isArray(maybeArray) : arg is any[] +>Array.isArray(maybeArray) : boolean >Array.isArray : (arg: any) => arg is any[] >Array : ArrayConstructor >isArray : (arg: any) => arg is any[] diff --git a/tests/baselines/reference/stringLiteralCheckedInIf02.types b/tests/baselines/reference/stringLiteralCheckedInIf02.types index f91eea03097..79f4c6a223a 100644 --- a/tests/baselines/reference/stringLiteralCheckedInIf02.types +++ b/tests/baselines/reference/stringLiteralCheckedInIf02.types @@ -31,7 +31,7 @@ function f(foo: T) { >T : ("a" | "b")[] | "a" | "b" if (isS(foo)) { ->isS(foo) : t is "a" | "b" +>isS(foo) : boolean >isS : (t: ("a" | "b")[] | "a" | "b") => t is "a" | "b" >foo : ("a" | "b")[] | "a" | "b" diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.types b/tests/baselines/reference/stringLiteralTypesAsTags01.types index 6966ede5482..a7f403e76ec 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags01.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.types @@ -88,7 +88,7 @@ let x: A = { } if (hasKind(x, "A")) { ->hasKind(x, "A") : entity is A +>hasKind(x, "A") : boolean >hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } >x : A >"A" : "A" @@ -105,7 +105,7 @@ else { if (!hasKind(x, "B")) { >!hasKind(x, "B") : boolean ->hasKind(x, "B") : entity is B +>hasKind(x, "B") : boolean >hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } >x : A >"B" : "B" diff --git a/tests/baselines/reference/stringLiteralTypesAsTags02.types b/tests/baselines/reference/stringLiteralTypesAsTags02.types index 0b8ea0faf67..edad220b086 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags02.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags02.types @@ -82,7 +82,7 @@ let x: A = { } if (hasKind(x, "A")) { ->hasKind(x, "A") : entity is A +>hasKind(x, "A") : boolean >hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } >x : A >"A" : "A" @@ -99,7 +99,7 @@ else { if (!hasKind(x, "B")) { >!hasKind(x, "B") : boolean ->hasKind(x, "B") : entity is B +>hasKind(x, "B") : boolean >hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } >x : A >"B" : "B" diff --git a/tests/baselines/reference/stringLiteralTypesAsTags03.types b/tests/baselines/reference/stringLiteralTypesAsTags03.types index a1d83a1c058..25816659388 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags03.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags03.types @@ -85,7 +85,7 @@ let x: A = { } if (hasKind(x, "A")) { ->hasKind(x, "A") : entity is A +>hasKind(x, "A") : boolean >hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } >x : A >"A" : "A" @@ -102,7 +102,7 @@ else { if (!hasKind(x, "B")) { >!hasKind(x, "B") : boolean ->hasKind(x, "B") : entity is B +>hasKind(x, "B") : boolean >hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } >x : A >"B" : "B" diff --git a/tests/baselines/reference/stringLiteralTypesTypePredicates01.types b/tests/baselines/reference/stringLiteralTypesTypePredicates01.types index 43c8271b76b..41da80afd30 100644 --- a/tests/baselines/reference/stringLiteralTypesTypePredicates01.types +++ b/tests/baselines/reference/stringLiteralTypesTypePredicates01.types @@ -36,7 +36,7 @@ var x: Kind = "A"; >"A" : "A" if (kindIs(x, "A")) { ->kindIs(x, "A") : kind is "A" +>kindIs(x, "A") : boolean >kindIs : { (kind: "A" | "B", is: "A"): kind is "A"; (kind: "A" | "B", is: "B"): kind is "B"; } >x : "A" | "B" >"A" : "A" @@ -53,7 +53,7 @@ else { if (!kindIs(x, "B")) { >!kindIs(x, "B") : boolean ->kindIs(x, "B") : kind is "B" +>kindIs(x, "B") : boolean >kindIs : { (kind: "A" | "B", is: "A"): kind is "A"; (kind: "A" | "B", is: "B"): kind is "B"; } >x : "A" | "B" >"B" : "B" diff --git a/tests/baselines/reference/typeGuardFunction.types b/tests/baselines/reference/typeGuardFunction.types index 9bab1e7ca2c..50a5fcaf324 100644 --- a/tests/baselines/reference/typeGuardFunction.types +++ b/tests/baselines/reference/typeGuardFunction.types @@ -54,7 +54,7 @@ var b: B; // Basic if (isC(a)) { ->isC(a) : p1 is C +>isC(a) : boolean >isC : (p1: any) => p1 is C >a : A @@ -70,7 +70,7 @@ var subType: C; >C : C if(isA(subType)) { ->isA(subType) : p1 is A +>isA(subType) : boolean >isA : (p1: any) => p1 is A >subType : C @@ -87,7 +87,7 @@ var union: A | B; >B : B if(isA(union)) { ->isA(union) : p1 is A +>isA(union) : boolean >isA : (p1: any) => p1 is A >union : A | B @@ -118,7 +118,7 @@ declare function isC_multipleParams(p1, p2): p1 is C; >C : C if (isC_multipleParams(a, 0)) { ->isC_multipleParams(a, 0) : p1 is C +>isC_multipleParams(a, 0) : boolean >isC_multipleParams : (p1: any, p2: any) => p1 is C >a : A >0 : number @@ -197,7 +197,7 @@ declare function acceptingBoolean(a: boolean); acceptingBoolean(isA(a)); >acceptingBoolean(isA(a)) : any >acceptingBoolean : (a: boolean) => any ->isA(a) : p1 is A +>isA(a) : boolean >isA : (p1: any) => p1 is A >a : A @@ -223,8 +223,8 @@ let union2: C | B; let union3: boolean | B = isA(union2) || union2; >union3 : boolean | B >B : B ->isA(union2) || union2 : p1 is A | B ->isA(union2) : p1 is A +>isA(union2) || union2 : boolean | B +>isA(union2) : boolean >isA : (p1: any) => p1 is A >union2 : C | B >union2 : B diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index 9ecad007672..8e4bf651518 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(2,7): error TS2300: Duplicate identifier 'A'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'x is A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'boolean'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,55): error TS2304: Cannot find name 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS1144: '{' or ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS2304: Cannot find name 'is'. @@ -43,9 +43,13 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,22) tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,22): error TS2304: Cannot find name 'is'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,25): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,27): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(104,25): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(105,16): error TS2322: Type 'boolean' is not assignable to type 'D'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(105,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(107,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(110,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(111,16): error TS2408: Setters cannot return a value. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(116,18): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,22): error TS2304: Cannot find name 'p1'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,25): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,25): error TS2304: Cannot find name 'is'. @@ -57,7 +61,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(133,34 tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. -==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (50 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (54 errors) ==== class A { ~ @@ -76,7 +80,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 function hasANonBooleanReturnStatement(x): x is A { return ''; ~~ -!!! error TS2322: Type 'string' is not assignable to type 'x is A'. +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. } function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { @@ -245,6 +249,8 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 // Non-compatiable type predicate positions for signature declarations class D { constructor(p1: A): p1 is C { + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return true; ~~~~ !!! error TS2322: Type 'boolean' is not assignable to type 'D'. @@ -252,9 +258,13 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 !!! error TS2409: Return type of constructor signature must be assignable to the instance type of the class } get m1(p1: A): p1 is C { + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return true; } set m2(p1: A): p1 is C { + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return true; ~~~~ !!! error TS2408: Setters cannot return a value. @@ -263,6 +273,8 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 interface I1 { new (p1: A): p1 is C; + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. } interface I2 { diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.types b/tests/baselines/reference/typeGuardFunctionGenerics.types index 1f2ad2b69be..c4655e71f0c 100644 --- a/tests/baselines/reference/typeGuardFunctionGenerics.types +++ b/tests/baselines/reference/typeGuardFunctionGenerics.types @@ -100,7 +100,7 @@ let test1: boolean = funA(isB); >isB : (p1: any) => p1 is B if (funB(retC, a)) { ->funB(retC, a) : p2 is C +>funB(retC, a) : boolean >funB : (p1: (p1: any) => T, p2: any) => p2 is T >retC : (x: any) => C >a : A @@ -118,7 +118,7 @@ let test2: B = funC(isB); >isB : (p1: any) => p1 is B if (funD(isC, a)) { ->funD(isC, a) : p2 is C +>funD(isC, a) : boolean >funD : (p1: (p1: any) => p1 is T, p2: any) => p2 is T >isC : (p1: any) => p1 is C >a : A diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThis.types b/tests/baselines/reference/typeGuardFunctionOfFormThis.types index e91c77dd07a..6b21fea3457 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThis.types +++ b/tests/baselines/reference/typeGuardFunctionOfFormThis.types @@ -45,7 +45,7 @@ let a: RoyalGuard = new FollowerGuard(); >FollowerGuard : typeof FollowerGuard if (a.isLeader()) { ->a.isLeader() : this is LeadGuard +>a.isLeader() : boolean >a.isLeader : () => this is LeadGuard >a : RoyalGuard >isLeader : () => this is LeadGuard @@ -57,7 +57,7 @@ if (a.isLeader()) { >lead : () => void } else if (a.isFollower()) { ->a.isFollower() : this is FollowerGuard +>a.isFollower() : boolean >a.isFollower : () => this is FollowerGuard >a : RoyalGuard >isFollower : () => this is FollowerGuard @@ -78,7 +78,7 @@ let b: GuardInterface; >GuardInterface : GuardInterface if (b.isLeader()) { ->b.isLeader() : this is LeadGuard +>b.isLeader() : boolean >b.isLeader : () => this is LeadGuard >b : GuardInterface >isLeader : () => this is LeadGuard @@ -90,7 +90,7 @@ if (b.isLeader()) { >lead : () => void } else if (b.isFollower()) { ->b.isFollower() : this is FollowerGuard +>b.isFollower() : boolean >b.isFollower : () => this is FollowerGuard >b : GuardInterface >isFollower : () => this is FollowerGuard @@ -103,8 +103,8 @@ else if (b.isFollower()) { } if (((a.isLeader)())) { ->((a.isLeader)()) : this is LeadGuard ->(a.isLeader)() : this is LeadGuard +>((a.isLeader)()) : boolean +>(a.isLeader)() : boolean >(a.isLeader) : () => this is LeadGuard >a.isLeader : () => this is LeadGuard >a : RoyalGuard @@ -117,8 +117,8 @@ if (((a.isLeader)())) { >lead : () => void } else if (((a).isFollower())) { ->((a).isFollower()) : this is FollowerGuard ->(a).isFollower() : this is FollowerGuard +>((a).isFollower()) : boolean +>(a).isFollower() : boolean >(a).isFollower : () => this is FollowerGuard >(a) : RoyalGuard >a : RoyalGuard @@ -132,8 +132,8 @@ else if (((a).isFollower())) { } if (((a["isLeader"])())) { ->((a["isLeader"])()) : this is LeadGuard ->(a["isLeader"])() : this is LeadGuard +>((a["isLeader"])()) : boolean +>(a["isLeader"])() : boolean >(a["isLeader"]) : () => this is LeadGuard >a["isLeader"] : () => this is LeadGuard >a : RoyalGuard @@ -146,8 +146,8 @@ if (((a["isLeader"])())) { >lead : () => void } else if (((a)["isFollower"]())) { ->((a)["isFollower"]()) : this is FollowerGuard ->(a)["isFollower"]() : this is FollowerGuard +>((a)["isFollower"]()) : boolean +>(a)["isFollower"]() : boolean >(a)["isFollower"] : () => this is FollowerGuard >(a) : RoyalGuard >a : RoyalGuard @@ -166,7 +166,7 @@ var holder2 = {a}; >a : RoyalGuard if (holder2.a.isLeader()) { ->holder2.a.isLeader() : this is LeadGuard +>holder2.a.isLeader() : boolean >holder2.a.isLeader : () => this is LeadGuard >holder2.a : RoyalGuard >holder2 : { a: RoyalGuard; } @@ -232,7 +232,7 @@ let guard = new ArrowGuard(); >ArrowGuard : typeof ArrowGuard if (guard.isElite()) { ->guard.isElite() : this is ArrowElite +>guard.isElite() : boolean >guard.isElite : () => this is ArrowElite >guard : ArrowGuard >isElite : () => this is ArrowElite @@ -244,7 +244,7 @@ if (guard.isElite()) { >defend : () => void } else if (guard.isMedic()) { ->guard.isMedic() : this is ArrowMedic +>guard.isMedic() : boolean >guard.isMedic : () => this is ArrowMedic >guard : ArrowGuard >isMedic : () => this is ArrowMedic @@ -297,7 +297,7 @@ let crate: Crate<{}>; >Crate : Crate if (crate.isSundries()) { ->crate.isSundries() : this is Crate +>crate.isSundries() : boolean >crate.isSundries : () => this is Crate >crate : Crate<{}> >isSundries : () => this is Crate @@ -312,7 +312,7 @@ if (crate.isSundries()) { >true : boolean } else if (crate.isSupplies()) { ->crate.isSupplies() : this is Crate +>crate.isSupplies() : boolean >crate.isSupplies : () => this is Crate >crate : Crate<{}> >isSupplies : () => this is Crate @@ -405,7 +405,7 @@ a.isFollower = mimic.isFollower; >isFollower : () => this is MimicFollower if (mimic.isFollower()) { ->mimic.isFollower() : this is MimicFollower +>mimic.isFollower() : boolean >mimic.isFollower : () => this is MimicFollower >mimic : MimicGuard >isFollower : () => this is MimicFollower diff --git a/tests/baselines/reference/typeGuardOfFormFunctionEquality.symbols b/tests/baselines/reference/typeGuardOfFormFunctionEquality.symbols new file mode 100644 index 00000000000..f1384050176 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormFunctionEquality.symbols @@ -0,0 +1,41 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormFunctionEquality.ts === +declare function isString1(a: number, b: Object): b is string; +>isString1 : Symbol(isString1, Decl(typeGuardOfFormFunctionEquality.ts, 0, 0)) +>a : Symbol(a, Decl(typeGuardOfFormFunctionEquality.ts, 0, 27)) +>b : Symbol(b, Decl(typeGuardOfFormFunctionEquality.ts, 0, 37)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b : Symbol(b, Decl(typeGuardOfFormFunctionEquality.ts, 0, 37)) + +declare function isString2(a: Object): a is string; +>isString2 : Symbol(isString2, Decl(typeGuardOfFormFunctionEquality.ts, 0, 62)) +>a : Symbol(a, Decl(typeGuardOfFormFunctionEquality.ts, 2, 27)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(typeGuardOfFormFunctionEquality.ts, 2, 27)) + +switch (isString1(0, "")) { +>isString1 : Symbol(isString1, Decl(typeGuardOfFormFunctionEquality.ts, 0, 0)) + + case isString2(""): +>isString2 : Symbol(isString2, Decl(typeGuardOfFormFunctionEquality.ts, 0, 62)) + + default: +} + +var x = isString1(0, "") === isString2(""); +>x : Symbol(x, Decl(typeGuardOfFormFunctionEquality.ts, 9, 3)) +>isString1 : Symbol(isString1, Decl(typeGuardOfFormFunctionEquality.ts, 0, 0)) +>isString2 : Symbol(isString2, Decl(typeGuardOfFormFunctionEquality.ts, 0, 62)) + +function isString3(a: number, b: number, c: Object): c is string { +>isString3 : Symbol(isString3, Decl(typeGuardOfFormFunctionEquality.ts, 9, 43)) +>a : Symbol(a, Decl(typeGuardOfFormFunctionEquality.ts, 11, 19)) +>b : Symbol(b, Decl(typeGuardOfFormFunctionEquality.ts, 11, 29)) +>c : Symbol(c, Decl(typeGuardOfFormFunctionEquality.ts, 11, 40)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>c : Symbol(c, Decl(typeGuardOfFormFunctionEquality.ts, 11, 40)) + + return isString1(0, c); +>isString1 : Symbol(isString1, Decl(typeGuardOfFormFunctionEquality.ts, 0, 0)) +>c : Symbol(c, Decl(typeGuardOfFormFunctionEquality.ts, 11, 40)) +} + diff --git a/tests/baselines/reference/typeGuardOfFormFunctionEquality.types b/tests/baselines/reference/typeGuardOfFormFunctionEquality.types new file mode 100644 index 00000000000..55f2e2aac0e --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormFunctionEquality.types @@ -0,0 +1,54 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormFunctionEquality.ts === +declare function isString1(a: number, b: Object): b is string; +>isString1 : (a: number, b: Object) => b is string +>a : number +>b : Object +>Object : Object +>b : any + +declare function isString2(a: Object): a is string; +>isString2 : (a: Object) => a is string +>a : Object +>Object : Object +>a : any + +switch (isString1(0, "")) { +>isString1(0, "") : boolean +>isString1 : (a: number, b: Object) => b is string +>0 : number +>"" : string + + case isString2(""): +>isString2("") : boolean +>isString2 : (a: Object) => a is string +>"" : string + + default: +} + +var x = isString1(0, "") === isString2(""); +>x : boolean +>isString1(0, "") === isString2("") : boolean +>isString1(0, "") : boolean +>isString1 : (a: number, b: Object) => b is string +>0 : number +>"" : string +>isString2("") : boolean +>isString2 : (a: Object) => a is string +>"" : string + +function isString3(a: number, b: number, c: Object): c is string { +>isString3 : (a: number, b: number, c: Object) => c is string +>a : number +>b : number +>c : Object +>Object : Object +>c : any + + return isString1(0, c); +>isString1(0, c) : boolean +>isString1 : (a: number, b: Object) => b is string +>0 : number +>c : Object +} + diff --git a/tests/baselines/reference/typeGuardOfFormIsType.types b/tests/baselines/reference/typeGuardOfFormIsType.types index aa8f8cc7d60..e2059be7b63 100644 --- a/tests/baselines/reference/typeGuardOfFormIsType.types +++ b/tests/baselines/reference/typeGuardOfFormIsType.types @@ -67,7 +67,7 @@ str = isC1(c1Orc2) && c1Orc2.p1; // C1 >str = isC1(c1Orc2) && c1Orc2.p1 : string >str : string >isC1(c1Orc2) && c1Orc2.p1 : string ->isC1(c1Orc2) : x is C1 +>isC1(c1Orc2) : boolean >isC1 : (x: any) => x is C1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -78,7 +78,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2 >num = isC2(c1Orc2) && c1Orc2.p2 : number >num : number >isC2(c1Orc2) && c1Orc2.p2 : number ->isC2(c1Orc2) : x is C2 +>isC2(c1Orc2) : boolean >isC2 : (x: any) => x is C2 >c1Orc2 : C1 | C2 >c1Orc2.p2 : number @@ -89,7 +89,7 @@ str = isD1(c1Orc2) && c1Orc2.p1; // D1 >str = isD1(c1Orc2) && c1Orc2.p1 : string >str : string >isD1(c1Orc2) && c1Orc2.p1 : string ->isD1(c1Orc2) : x is D1 +>isD1(c1Orc2) : boolean >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -100,7 +100,7 @@ num = isD1(c1Orc2) && c1Orc2.p3; // D1 >num = isD1(c1Orc2) && c1Orc2.p3 : number >num : number >isD1(c1Orc2) && c1Orc2.p3 : number ->isD1(c1Orc2) : x is D1 +>isD1(c1Orc2) : boolean >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p3 : number @@ -116,7 +116,7 @@ num = isC2(c2Ord1) && c2Ord1.p2; // C2 >num = isC2(c2Ord1) && c2Ord1.p2 : number >num : number >isC2(c2Ord1) && c2Ord1.p2 : number ->isC2(c2Ord1) : x is C2 +>isC2(c2Ord1) : boolean >isC2 : (x: any) => x is C2 >c2Ord1 : C2 | D1 >c2Ord1.p2 : number @@ -127,7 +127,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1 >num = isD1(c2Ord1) && c2Ord1.p3 : number >num : number >isD1(c2Ord1) && c2Ord1.p3 : number ->isD1(c2Ord1) : x is D1 +>isD1(c2Ord1) : boolean >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p3 : number @@ -138,7 +138,7 @@ str = isD1(c2Ord1) && c2Ord1.p1; // D1 >str = isD1(c2Ord1) && c2Ord1.p1 : string >str : string >isD1(c2Ord1) && c2Ord1.p1 : string ->isD1(c2Ord1) : x is D1 +>isD1(c2Ord1) : boolean >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p1 : string @@ -150,7 +150,7 @@ var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 >C2 : C2 >D1 : D1 >isC1(c2Ord1) && c2Ord1 : D1 ->isC1(c2Ord1) : x is C1 +>isC1(c2Ord1) : boolean >isC1 : (x: any) => x is C1 >c2Ord1 : C2 | D1 >c2Ord1 : D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types index 4e28e6a4d38..ea169e95413 100644 --- a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types @@ -98,7 +98,7 @@ str = isC1(c1Orc2) && c1Orc2.p1; // C1 >str = isC1(c1Orc2) && c1Orc2.p1 : string >str : string >isC1(c1Orc2) && c1Orc2.p1 : string ->isC1(c1Orc2) : x is C1 +>isC1(c1Orc2) : boolean >isC1 : (x: any) => x is C1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -109,7 +109,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2 >num = isC2(c1Orc2) && c1Orc2.p2 : number >num : number >isC2(c1Orc2) && c1Orc2.p2 : number ->isC2(c1Orc2) : x is C2 +>isC2(c1Orc2) : boolean >isC2 : (x: any) => x is C2 >c1Orc2 : C1 | C2 >c1Orc2.p2 : number @@ -120,7 +120,7 @@ str = isD1(c1Orc2) && c1Orc2.p1; // D1 >str = isD1(c1Orc2) && c1Orc2.p1 : string >str : string >isD1(c1Orc2) && c1Orc2.p1 : string ->isD1(c1Orc2) : x is D1 +>isD1(c1Orc2) : boolean >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -131,7 +131,7 @@ num = isD1(c1Orc2) && c1Orc2.p3; // D1 >num = isD1(c1Orc2) && c1Orc2.p3 : number >num : number >isD1(c1Orc2) && c1Orc2.p3 : number ->isD1(c1Orc2) : x is D1 +>isD1(c1Orc2) : boolean >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p3 : number @@ -147,7 +147,7 @@ num = isC2(c2Ord1) && c2Ord1.p2; // C2 >num = isC2(c2Ord1) && c2Ord1.p2 : number >num : number >isC2(c2Ord1) && c2Ord1.p2 : number ->isC2(c2Ord1) : x is C2 +>isC2(c2Ord1) : boolean >isC2 : (x: any) => x is C2 >c2Ord1 : C2 | D1 >c2Ord1.p2 : number @@ -158,7 +158,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1 >num = isD1(c2Ord1) && c2Ord1.p3 : number >num : number >isD1(c2Ord1) && c2Ord1.p3 : number ->isD1(c2Ord1) : x is D1 +>isD1(c2Ord1) : boolean >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p3 : number @@ -169,7 +169,7 @@ str = isD1(c2Ord1) && c2Ord1.p1; // D1 >str = isD1(c2Ord1) && c2Ord1.p1 : string >str : string >isD1(c2Ord1) && c2Ord1.p1 : string ->isD1(c2Ord1) : x is D1 +>isD1(c2Ord1) : boolean >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p1 : string @@ -181,7 +181,7 @@ var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 >C2 : C2 >D1 : D1 >isC1(c2Ord1) && c2Ord1 : D1 ->isC1(c2Ord1) : x is C1 +>isC1(c2Ord1) : boolean >isC1 : (x: any) => x is C1 >c2Ord1 : C2 | D1 >c2Ord1 : D1 diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.errors.txt b/tests/baselines/reference/typeGuardOfFormThisMember.errors.txt new file mode 100644 index 00000000000..21dc896fbd9 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormThisMember.errors.txt @@ -0,0 +1,130 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(4,10): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(5,17): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(11,22): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(14,16): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(34,8): error TS2339: Property 'content' does not exist on type 'FileSystemObject'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(36,9): error TS2339: Property 'host' does not exist on type 'FileSystemObject'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(37,9): error TS2339: Property 'content' does not exist on type 'FileSystemObject'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(41,8): error TS2339: Property 'children' does not exist on type 'FileSystemObject'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(44,8): error TS2339: Property 'host' does not exist on type 'FileSystemObject'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(57,13): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(58,15): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(63,9): error TS2339: Property 'lead' does not exist on type 'GenericGuard'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(66,9): error TS2339: Property 'follow' does not exist on type 'GenericGuard'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(70,19): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts(79,11): error TS2339: Property 'do' does not exist on type 'SpecificGuard'. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts (15 errors) ==== + // There's a 'File' class in the stdlib, wrap with a namespace to avoid collision + namespace Test { + export class FileSystemObject { + isFSO: this is FileSystemObject; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + get isFile(): this is File { + ~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + return this instanceof File; + } + set isFile(param) { + // noop + } + get isDirectory(): this is Directory { + ~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + return this instanceof Directory; + } + isNetworked: this is (Networked & this); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + constructor(public path: string) {} + } + + export class File extends FileSystemObject { + constructor(path: string, public content: string) { super(path); } + } + export class Directory extends FileSystemObject { + children: FileSystemObject[]; + } + export interface Networked { + host: string; + } + + let file: FileSystemObject = new File("foo/bar.txt", "foo"); + file.isNetworked = false; + file.isFSO = file.isFile; + file.isFile = true; + let x = file.isFile; + if (file.isFile) { + file.content; + ~~~~~~~ +!!! error TS2339: Property 'content' does not exist on type 'FileSystemObject'. + if (file.isNetworked) { + file.host; + ~~~~ +!!! error TS2339: Property 'host' does not exist on type 'FileSystemObject'. + file.content; + ~~~~~~~ +!!! error TS2339: Property 'content' does not exist on type 'FileSystemObject'. + } + } + else if (file.isDirectory) { + file.children; + ~~~~~~~~ +!!! error TS2339: Property 'children' does not exist on type 'FileSystemObject'. + } + else if (file.isNetworked) { + file.host; + ~~~~ +!!! error TS2339: Property 'host' does not exist on type 'FileSystemObject'. + } + + interface GenericLeadGuard extends GenericGuard { + lead(): void; + } + + interface GenericFollowerGuard extends GenericGuard { + follow(): void; + } + + interface GenericGuard { + target: T; + isLeader: this is (GenericLeadGuard); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + isFollower: this is GenericFollowerGuard; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + } + + let guard: GenericGuard; + if (guard.isLeader) { + guard.lead(); + ~~~~ +!!! error TS2339: Property 'lead' does not exist on type 'GenericGuard'. + } + else if (guard.isFollower) { + guard.follow(); + ~~~~~~ +!!! error TS2339: Property 'follow' does not exist on type 'GenericGuard'. + } + + interface SpecificGuard { + isMoreSpecific: this is MoreSpecificGuard; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + } + + interface MoreSpecificGuard extends SpecificGuard { + do(): void; + } + + let general: SpecificGuard; + if (general.isMoreSpecific) { + general.do(); + ~~ +!!! error TS2339: Property 'do' does not exist on type 'SpecificGuard'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.symbols b/tests/baselines/reference/typeGuardOfFormThisMember.symbols deleted file mode 100644 index 50e15b68ca4..00000000000 --- a/tests/baselines/reference/typeGuardOfFormThisMember.symbols +++ /dev/null @@ -1,240 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts === -// There's a 'File' class in the stdlib, wrap with a namespace to avoid collision -namespace Test { ->Test : Symbol(Test, Decl(typeGuardOfFormThisMember.ts, 0, 0)) - - export class FileSystemObject { ->FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) - - isFSO: this is FileSystemObject; ->isFSO : Symbol(isFSO, Decl(typeGuardOfFormThisMember.ts, 2, 32)) ->FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) - - get isFile(): this is File { ->isFile : Symbol(isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) - - return this instanceof File; ->this : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) - } - set isFile(param) { ->isFile : Symbol(isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) ->param : Symbol(param, Decl(typeGuardOfFormThisMember.ts, 7, 13)) - - // noop - } - get isDirectory(): this is Directory { ->isDirectory : Symbol(isDirectory, Decl(typeGuardOfFormThisMember.ts, 9, 3)) ->Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 19, 2)) - - return this instanceof Directory; ->this : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 19, 2)) - } - isNetworked: this is (Networked & this); ->isNetworked : Symbol(isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) ->Networked : Symbol(Networked, Decl(typeGuardOfFormThisMember.ts, 22, 2)) - - constructor(public path: string) {} ->path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 14, 14)) - } - - export class File extends FileSystemObject { ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) ->FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) - - constructor(path: string, public content: string) { super(path); } ->path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 18, 14)) ->content : Symbol(content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) ->super : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 18, 14)) - } - export class Directory extends FileSystemObject { ->Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 19, 2)) ->FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) - - children: FileSystemObject[]; ->children : Symbol(children, Decl(typeGuardOfFormThisMember.ts, 20, 50)) ->FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) - } - export interface Networked { ->Networked : Symbol(Networked, Decl(typeGuardOfFormThisMember.ts, 22, 2)) - - host: string; ->host : Symbol(host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) - } - - let file: FileSystemObject = new File("foo/bar.txt", "foo"); ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) - - file.isNetworked = false; ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) - - file.isFSO = file.isFile; ->file.isFSO : Symbol(FileSystemObject.isFSO, Decl(typeGuardOfFormThisMember.ts, 2, 32)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isFSO : Symbol(FileSystemObject.isFSO, Decl(typeGuardOfFormThisMember.ts, 2, 32)) ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) - - file.isFile = true; ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) - - let x = file.isFile; ->x : Symbol(x, Decl(typeGuardOfFormThisMember.ts, 31, 4)) ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) - - if (file.isFile) { ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) - - file.content; ->file.content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) - - if (file.isNetworked) { ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) - - file.host; ->file.host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) - - file.content; ->file.content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) - } - } - else if (file.isDirectory) { ->file.isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 9, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 9, 3)) - - file.children; ->file.children : Symbol(Directory.children, Decl(typeGuardOfFormThisMember.ts, 20, 50)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->children : Symbol(Directory.children, Decl(typeGuardOfFormThisMember.ts, 20, 50)) - } - else if (file.isNetworked) { ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) - - file.host; ->file.host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) ->host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) - } - - interface GenericLeadGuard extends GenericGuard { ->GenericLeadGuard : Symbol(GenericLeadGuard, Decl(typeGuardOfFormThisMember.ts, 44, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 46, 28)) ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 46, 28)) - - lead(): void; ->lead : Symbol(lead, Decl(typeGuardOfFormThisMember.ts, 46, 56)) - } - - interface GenericFollowerGuard extends GenericGuard { ->GenericFollowerGuard : Symbol(GenericFollowerGuard, Decl(typeGuardOfFormThisMember.ts, 48, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 50, 32)) ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 50, 32)) - - follow(): void; ->follow : Symbol(follow, Decl(typeGuardOfFormThisMember.ts, 50, 60)) - } - - interface GenericGuard { ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) - - target: T; ->target : Symbol(target, Decl(typeGuardOfFormThisMember.ts, 54, 28)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) - - isLeader: this is (GenericLeadGuard); ->isLeader : Symbol(isLeader, Decl(typeGuardOfFormThisMember.ts, 55, 12)) ->GenericLeadGuard : Symbol(GenericLeadGuard, Decl(typeGuardOfFormThisMember.ts, 44, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) - - isFollower: this is GenericFollowerGuard; ->isFollower : Symbol(isFollower, Decl(typeGuardOfFormThisMember.ts, 56, 42)) ->GenericFollowerGuard : Symbol(GenericFollowerGuard, Decl(typeGuardOfFormThisMember.ts, 48, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) - } - - let guard: GenericGuard; ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) - - if (guard.isLeader) { ->guard.isLeader : Symbol(GenericGuard.isLeader, Decl(typeGuardOfFormThisMember.ts, 55, 12)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) ->isLeader : Symbol(GenericGuard.isLeader, Decl(typeGuardOfFormThisMember.ts, 55, 12)) - - guard.lead(); ->guard.lead : Symbol(GenericLeadGuard.lead, Decl(typeGuardOfFormThisMember.ts, 46, 56)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) ->lead : Symbol(GenericLeadGuard.lead, Decl(typeGuardOfFormThisMember.ts, 46, 56)) - } - else if (guard.isFollower) { ->guard.isFollower : Symbol(GenericGuard.isFollower, Decl(typeGuardOfFormThisMember.ts, 56, 42)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) ->isFollower : Symbol(GenericGuard.isFollower, Decl(typeGuardOfFormThisMember.ts, 56, 42)) - - guard.follow(); ->guard.follow : Symbol(GenericFollowerGuard.follow, Decl(typeGuardOfFormThisMember.ts, 50, 60)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) ->follow : Symbol(GenericFollowerGuard.follow, Decl(typeGuardOfFormThisMember.ts, 50, 60)) - } - - interface SpecificGuard { ->SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 66, 2)) - - isMoreSpecific: this is MoreSpecificGuard; ->isMoreSpecific : Symbol(isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 68, 26)) ->MoreSpecificGuard : Symbol(MoreSpecificGuard, Decl(typeGuardOfFormThisMember.ts, 70, 2)) - } - - interface MoreSpecificGuard extends SpecificGuard { ->MoreSpecificGuard : Symbol(MoreSpecificGuard, Decl(typeGuardOfFormThisMember.ts, 70, 2)) ->SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 66, 2)) - - do(): void; ->do : Symbol(do, Decl(typeGuardOfFormThisMember.ts, 72, 52)) - } - - let general: SpecificGuard; ->general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 76, 4)) ->SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 66, 2)) - - if (general.isMoreSpecific) { ->general.isMoreSpecific : Symbol(SpecificGuard.isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 68, 26)) ->general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 76, 4)) ->isMoreSpecific : Symbol(SpecificGuard.isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 68, 26)) - - general.do(); ->general.do : Symbol(MoreSpecificGuard.do, Decl(typeGuardOfFormThisMember.ts, 72, 52)) ->general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 76, 4)) ->do : Symbol(MoreSpecificGuard.do, Decl(typeGuardOfFormThisMember.ts, 72, 52)) - } -} - diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.types b/tests/baselines/reference/typeGuardOfFormThisMember.types deleted file mode 100644 index 68343947fb4..00000000000 --- a/tests/baselines/reference/typeGuardOfFormThisMember.types +++ /dev/null @@ -1,254 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts === -// There's a 'File' class in the stdlib, wrap with a namespace to avoid collision -namespace Test { ->Test : typeof Test - - export class FileSystemObject { ->FileSystemObject : FileSystemObject - - isFSO: this is FileSystemObject; ->isFSO : this is FileSystemObject ->FileSystemObject : FileSystemObject - - get isFile(): this is File { ->isFile : this is File ->File : File - - return this instanceof File; ->this instanceof File : boolean ->this : this ->File : typeof File - } - set isFile(param) { ->isFile : this is File ->param : boolean - - // noop - } - get isDirectory(): this is Directory { ->isDirectory : this is Directory ->Directory : Directory - - return this instanceof Directory; ->this instanceof Directory : boolean ->this : this ->Directory : typeof Directory - } - isNetworked: this is (Networked & this); ->isNetworked : this is Networked & this ->Networked : Networked - - constructor(public path: string) {} ->path : string - } - - export class File extends FileSystemObject { ->File : File ->FileSystemObject : FileSystemObject - - constructor(path: string, public content: string) { super(path); } ->path : string ->content : string ->super(path) : void ->super : typeof FileSystemObject ->path : string - } - export class Directory extends FileSystemObject { ->Directory : Directory ->FileSystemObject : FileSystemObject - - children: FileSystemObject[]; ->children : FileSystemObject[] ->FileSystemObject : FileSystemObject - } - export interface Networked { ->Networked : Networked - - host: string; ->host : string - } - - let file: FileSystemObject = new File("foo/bar.txt", "foo"); ->file : FileSystemObject ->FileSystemObject : FileSystemObject ->new File("foo/bar.txt", "foo") : File ->File : typeof File ->"foo/bar.txt" : string ->"foo" : string - - file.isNetworked = false; ->file.isNetworked = false : boolean ->file.isNetworked : this is Networked & FileSystemObject ->file : FileSystemObject ->isNetworked : this is Networked & FileSystemObject ->false : boolean - - file.isFSO = file.isFile; ->file.isFSO = file.isFile : this is File ->file.isFSO : this is FileSystemObject ->file : FileSystemObject ->isFSO : this is FileSystemObject ->file.isFile : this is File ->file : FileSystemObject ->isFile : this is File - - file.isFile = true; ->file.isFile = true : boolean ->file.isFile : this is File ->file : FileSystemObject ->isFile : this is File ->true : boolean - - let x = file.isFile; ->x : boolean ->file.isFile : this is File ->file : FileSystemObject ->isFile : this is File - - if (file.isFile) { ->file.isFile : this is File ->file : FileSystemObject ->isFile : this is File - - file.content; ->file.content : string ->file : File ->content : string - - if (file.isNetworked) { ->file.isNetworked : this is Networked & File ->file : File ->isNetworked : this is Networked & File - - file.host; ->file.host : string ->file : Networked & File ->host : string - - file.content; ->file.content : string ->file : Networked & File ->content : string - } - } - else if (file.isDirectory) { ->file.isDirectory : this is Directory ->file : FileSystemObject ->isDirectory : this is Directory - - file.children; ->file.children : FileSystemObject[] ->file : Directory ->children : FileSystemObject[] - } - else if (file.isNetworked) { ->file.isNetworked : this is Networked & FileSystemObject ->file : FileSystemObject ->isNetworked : this is Networked & FileSystemObject - - file.host; ->file.host : string ->file : Networked & FileSystemObject ->host : string - } - - interface GenericLeadGuard extends GenericGuard { ->GenericLeadGuard : GenericLeadGuard ->T : T ->GenericGuard : GenericGuard ->T : T - - lead(): void; ->lead : () => void - } - - interface GenericFollowerGuard extends GenericGuard { ->GenericFollowerGuard : GenericFollowerGuard ->T : T ->GenericGuard : GenericGuard ->T : T - - follow(): void; ->follow : () => void - } - - interface GenericGuard { ->GenericGuard : GenericGuard ->T : T - - target: T; ->target : T ->T : T - - isLeader: this is (GenericLeadGuard); ->isLeader : this is GenericLeadGuard ->GenericLeadGuard : GenericLeadGuard ->T : T - - isFollower: this is GenericFollowerGuard; ->isFollower : this is GenericFollowerGuard ->GenericFollowerGuard : GenericFollowerGuard ->T : T - } - - let guard: GenericGuard; ->guard : GenericGuard ->GenericGuard : GenericGuard ->File : File - - if (guard.isLeader) { ->guard.isLeader : this is GenericLeadGuard ->guard : GenericGuard ->isLeader : this is GenericLeadGuard - - guard.lead(); ->guard.lead() : void ->guard.lead : () => void ->guard : GenericLeadGuard ->lead : () => void - } - else if (guard.isFollower) { ->guard.isFollower : this is GenericFollowerGuard ->guard : GenericGuard ->isFollower : this is GenericFollowerGuard - - guard.follow(); ->guard.follow() : void ->guard.follow : () => void ->guard : GenericFollowerGuard ->follow : () => void - } - - interface SpecificGuard { ->SpecificGuard : SpecificGuard - - isMoreSpecific: this is MoreSpecificGuard; ->isMoreSpecific : this is MoreSpecificGuard ->MoreSpecificGuard : MoreSpecificGuard - } - - interface MoreSpecificGuard extends SpecificGuard { ->MoreSpecificGuard : MoreSpecificGuard ->SpecificGuard : SpecificGuard - - do(): void; ->do : () => void - } - - let general: SpecificGuard; ->general : SpecificGuard ->SpecificGuard : SpecificGuard - - if (general.isMoreSpecific) { ->general.isMoreSpecific : this is MoreSpecificGuard ->general : SpecificGuard ->isMoreSpecific : this is MoreSpecificGuard - - general.do(); ->general.do() : void ->general.do : () => void ->general : MoreSpecificGuard ->do : () => void - } -} - diff --git a/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt index 754cbffe6e6..88e9d41cc7b 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt +++ b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt @@ -1,27 +1,32 @@ -tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(29,2): error TS1226: Type predicate 'this is File' is not assignable to 'this is Networked & FileSystemObject'. - Type 'File' is not assignable to type 'Networked & FileSystemObject'. - Type 'File' is not assignable to type 'Networked'. - Property 'host' is missing in type 'File'. -tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(31,2): error TS1226: Type predicate 'this is FileSystemObject' is not assignable to 'this is File'. - Type 'FileSystemObject' is not assignable to type 'File'. - Property 'content' is missing in type 'FileSystemObject'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(4,10): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(5,17): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(11,22): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(14,16): error TS1228: A type predicate is only allowed in return type position for functions and methods. -==== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts (2 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts (4 errors) ==== // There's a 'File' class in the stdlib, wrap with a namespace to avoid collision namespace Test { export class FileSystemObject { isFSO: this is FileSystemObject; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. get isFile(): this is File { + ~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return this instanceof File; } set isFile(param) { // noop } get isDirectory(): this is Directory { + ~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return this instanceof Directory; } isNetworked: this is (Networked & this); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. constructor(public path: string) {} } @@ -37,15 +42,6 @@ tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.t let file: FileSystemObject = new File("foo/bar.txt", "foo"); file.isNetworked = file.isFile; - ~~~~~~~~~~~~~~~~ -!!! error TS1226: Type predicate 'this is File' is not assignable to 'this is Networked & FileSystemObject'. -!!! error TS1226: Type 'File' is not assignable to type 'Networked & FileSystemObject'. -!!! error TS1226: Type 'File' is not assignable to type 'Networked'. -!!! error TS1226: Property 'host' is missing in type 'File'. file.isFSO = file.isNetworked; file.isFile = file.isFSO; - ~~~~~~~~~~~ -!!! error TS1226: Type predicate 'this is FileSystemObject' is not assignable to 'this is File'. -!!! error TS1226: Type 'FileSystemObject' is not assignable to type 'File'. -!!! error TS1226: Property 'content' is missing in type 'FileSystemObject'. } \ No newline at end of file diff --git a/tests/baselines/reference/typePredicateOnVariableDeclaration01.errors.txt b/tests/baselines/reference/typePredicateOnVariableDeclaration01.errors.txt new file mode 100644 index 00000000000..b713dd12ae7 --- /dev/null +++ b/tests/baselines/reference/typePredicateOnVariableDeclaration01.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration01.ts(2,8): error TS1228: A type predicate is only allowed in return type position for functions and methods. + + +==== tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration01.ts (1 errors) ==== + + var x: this is string; + ~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. \ No newline at end of file diff --git a/tests/baselines/reference/typePredicateOnVariableDeclaration02.errors.txt b/tests/baselines/reference/typePredicateOnVariableDeclaration02.errors.txt new file mode 100644 index 00000000000..af967b22b79 --- /dev/null +++ b/tests/baselines/reference/typePredicateOnVariableDeclaration02.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts(2,8): error TS2304: Cannot find name 'z'. +tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts(2,8): error TS4025: Exported variable 'y' has or is using private name 'z'. +tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts(2,10): error TS1005: '=' expected. +tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts(2,10): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts(2,13): error TS1005: ',' expected. + + +==== tests/cases/conformance/expressions/typeGuards/typePredicateOnVariableDeclaration02.ts (5 errors) ==== + + var y: z is number; + ~ +!!! error TS2304: Cannot find name 'z'. + ~ +!!! error TS4025: Exported variable 'y' has or is using private name 'z'. + ~~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~~~~~~ +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/unionAndIntersectionInference1.types b/tests/baselines/reference/unionAndIntersectionInference1.types index 073a677b659..5d23688f0b7 100644 --- a/tests/baselines/reference/unionAndIntersectionInference1.types +++ b/tests/baselines/reference/unionAndIntersectionInference1.types @@ -110,7 +110,7 @@ function foo1(value: void|a): void { >a : a if (isVoid(value)) { ->isVoid(value) : value is void +>isVoid(value) : boolean >isVoid : (value: void | a) => value is void >value : void | a @@ -130,7 +130,7 @@ function baz1(value: void|a): void { >a : a if (isNonVoid(value)) { ->isNonVoid(value) : value is a +>isNonVoid(value) : boolean >isNonVoid : (value: void | a) => value is a >value : void | a From 9960064bc30ba7556497246bb2bad426bee6f9c6 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 12 Feb 2016 16:30:19 -0800 Subject: [PATCH 15/22] classic resolution: don't perform folder walk if module name is relative --- src/compiler/program.ts | 27 ++++++++++++------- ...elativeNamesInClassicResolution.errors.txt | 11 ++++++++ .../relativeNamesInClassicResolution.ts | 7 +++++ tests/cases/unittests/moduleResolution.ts | 23 +++++++--------- 4 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 tests/baselines/reference/relativeNamesInClassicResolution.errors.txt create mode 100644 tests/cases/compiler/relativeNamesInClassicResolution.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0acb13f02d3..56a08dcc7f2 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -533,18 +533,25 @@ namespace ts { } let referencedSourceFile: string; - while (true) { - const searchName = normalizePath(combinePaths(containingDirectory, moduleName)); - referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state); - if (referencedSourceFile) { - break; + if (moduleHasNonRelativeName(moduleName)) { + while (true) { + const searchName = normalizePath(combinePaths(containingDirectory, moduleName)); + referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state); + if (referencedSourceFile) { + break; + } + const parentPath = getDirectoryPath(containingDirectory); + if (parentPath === containingDirectory) { + break; + } + containingDirectory = parentPath; } - const parentPath = getDirectoryPath(containingDirectory); - if (parentPath === containingDirectory) { - break; - } - containingDirectory = parentPath; } + else { + const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); + referencedSourceFile = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state); + } + return referencedSourceFile ? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations } diff --git a/tests/baselines/reference/relativeNamesInClassicResolution.errors.txt b/tests/baselines/reference/relativeNamesInClassicResolution.errors.txt new file mode 100644 index 00000000000..65a42775331 --- /dev/null +++ b/tests/baselines/reference/relativeNamesInClassicResolution.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/somefolder/a.ts(2,17): error TS2307: Cannot find module './b'. + + +==== tests/cases/compiler/somefolder/a.ts (1 errors) ==== + + import {x} from "./b" + ~~~~~ +!!! error TS2307: Cannot find module './b'. + +==== tests/cases/compiler/b.ts (0 errors) ==== + export let x = 1; \ No newline at end of file diff --git a/tests/cases/compiler/relativeNamesInClassicResolution.ts b/tests/cases/compiler/relativeNamesInClassicResolution.ts new file mode 100644 index 00000000000..7c73a2e3cad --- /dev/null +++ b/tests/cases/compiler/relativeNamesInClassicResolution.ts @@ -0,0 +1,7 @@ +// @module:amd + +// @filename: somefolder/a.ts +import {x} from "./b" + +// @filename: b.ts +export let x = 1; \ No newline at end of file diff --git a/tests/cases/unittests/moduleResolution.ts b/tests/cases/unittests/moduleResolution.ts index 1173f579f2c..9a52d9896e4 100644 --- a/tests/cases/unittests/moduleResolution.ts +++ b/tests/cases/unittests/moduleResolution.ts @@ -48,7 +48,7 @@ module ts { return hasProperty(directories, path); }, fileExists: path => { - assert.isTrue(hasProperty(directories, getDirectoryPath(path)), "'fileExists' request in non-existing directory"); + assert.isTrue(hasProperty(directories, getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`); return hasProperty(map, path); } } @@ -814,7 +814,6 @@ import b = require("./moduleB.ts"); it ("classic + rootDirs", () => { test(/*hasDirectoryExists*/ false); - test(/*hasDirectoryExists*/ true); function test(hasDirectoryExists: boolean) { let file1: File = { name: "/root/folder1/file1.ts" }; @@ -844,24 +843,20 @@ import b = require("./moduleB.ts"); "/root/generated/folder1/file1.d.ts", // then try alternative rootDir entry ]); - check("../folder1/file1_1", file3, file4, [ - // load from initial location + check("folder1/file1_1", file3, file4, [ + // current location + "/root/generated/folder2/folder1/file1_1.ts", + "/root/generated/folder2/folder1/file1_1.tsx", + "/root/generated/folder2/folder1/file1_1.d.ts", + // other entry in rootDirs "/root/generated/folder1/file1_1.ts", "/root/generated/folder1/file1_1.tsx", "/root/generated/folder1/file1_1.d.ts", - // load from alternative rootDir entry - "/root/folder1/file1_1.ts", - "/root/folder1/file1_1.tsx", - "/root/folder1/file1_1.d.ts", - // fallback to classic - // step1: initial location - "/root/generated/folder1/file1_1.ts", - "/root/generated/folder1/file1_1.tsx", - "/root/generated/folder1/file1_1.d.ts", - // step2: walk 1 level up + // fallback "/root/folder1/file1_1.ts", "/root/folder1/file1_1.tsx", "/root/folder1/file1_1.d.ts", + // found one ]); function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) { From 3ecc42beb2b2fb95dde32b2b7d764e84c86540c0 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 12 Feb 2016 17:16:50 -0800 Subject: [PATCH 16/22] added misssing files --- .../relativeNamesInClassicResolution.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/baselines/reference/relativeNamesInClassicResolution.js diff --git a/tests/baselines/reference/relativeNamesInClassicResolution.js b/tests/baselines/reference/relativeNamesInClassicResolution.js new file mode 100644 index 00000000000..a6c5a06ea3d --- /dev/null +++ b/tests/baselines/reference/relativeNamesInClassicResolution.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/relativeNamesInClassicResolution.ts] //// + +//// [a.ts] + +import {x} from "./b" + +//// [b.ts] +export let x = 1; + +//// [a.js] +define(["require", "exports"], function (require, exports) { + "use strict"; +}); +//// [b.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.x = 1; +}); From c5d5d13e61f67f5cb8df0ee3417ee82f2b121bce Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 12 Feb 2016 17:28:10 -0800 Subject: [PATCH 17/22] Remove the 'module' option from 'tsconfig.json' files. --- src/compiler/tsconfig.json | 3 +-- src/server/tsconfig.json | 1 - src/services/tsconfig.json | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index ca297c087cf..5460f162935 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "module": "commonjs", "noImplicitAny": true, "removeComments": true, "preserveConstEnums": true, @@ -8,9 +7,9 @@ "sourceMap": true }, "files": [ + "types.ts", "core.ts", "sys.ts", - "types.ts", "diagnosticInformationMap.generated.ts", "scanner.ts", "parser.ts", diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index 2c8538c61e3..0772210cb15 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "module": "commonjs", "noImplicitAny": true, "removeComments": true, "preserveConstEnums": true, diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 5dcee789243..001071ed88d 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "module": "commonjs", "noImplicitAny": true, "removeComments": true, "preserveConstEnums": true, From e29be4b2d99f7fea5ff18e64011f518722a801c1 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 12 Feb 2016 17:39:46 -0800 Subject: [PATCH 18/22] Added the accidentally-ignored js files. --- .../declarationEmitIdentifierPredicates01.js | 16 +++++++ ...itIdentifierPredicatesWithPrivateName01.js | 16 +++++++ .../declarationEmitThisPredicates01.js | 43 +++++++++++++++++++ .../declarationEmitThisPredicates02.js | 34 +++++++++++++++ ...tionEmitThisPredicatesWithPrivateName01.js | 34 +++++++++++++++ ...tionEmitThisPredicatesWithPrivateName02.js | 23 ++++++++++ .../typeGuardOfFormFunctionEquality.js | 26 +++++++++++ .../typePredicateOnVariableDeclaration01.js | 10 +++++ .../typePredicateOnVariableDeclaration02.js | 6 +++ 9 files changed, 208 insertions(+) create mode 100644 tests/baselines/reference/declarationEmitIdentifierPredicates01.js create mode 100644 tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.js create mode 100644 tests/baselines/reference/declarationEmitThisPredicates01.js create mode 100644 tests/baselines/reference/declarationEmitThisPredicates02.js create mode 100644 tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.js create mode 100644 tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js create mode 100644 tests/baselines/reference/typeGuardOfFormFunctionEquality.js create mode 100644 tests/baselines/reference/typePredicateOnVariableDeclaration01.js create mode 100644 tests/baselines/reference/typePredicateOnVariableDeclaration02.js diff --git a/tests/baselines/reference/declarationEmitIdentifierPredicates01.js b/tests/baselines/reference/declarationEmitIdentifierPredicates01.js new file mode 100644 index 00000000000..73141eb9af9 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIdentifierPredicates01.js @@ -0,0 +1,16 @@ +//// [declarationEmitIdentifierPredicates01.ts] + +export function f(x: any): x is number { + return typeof x === "number"; +} + +//// [declarationEmitIdentifierPredicates01.js] +"use strict"; +function f(x) { + return typeof x === "number"; +} +exports.f = f; + + +//// [declarationEmitIdentifierPredicates01.d.ts] +export declare function f(x: any): x is number; diff --git a/tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.js b/tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.js new file mode 100644 index 00000000000..234542d8d99 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIdentifierPredicatesWithPrivateName01.js @@ -0,0 +1,16 @@ +//// [declarationEmitIdentifierPredicatesWithPrivateName01.ts] + +interface I { + a: number; +} + +export function f(x: any): x is I { + return typeof x.a === "number"; +} + +//// [declarationEmitIdentifierPredicatesWithPrivateName01.js] +"use strict"; +function f(x) { + return typeof x.a === "number"; +} +exports.f = f; diff --git a/tests/baselines/reference/declarationEmitThisPredicates01.js b/tests/baselines/reference/declarationEmitThisPredicates01.js new file mode 100644 index 00000000000..d05b5c46dad --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicates01.js @@ -0,0 +1,43 @@ +//// [declarationEmitThisPredicates01.ts] + +export class C { + m(): this is D { + return this instanceof D; + } +} + +export class D extends C { +} + +//// [declarationEmitThisPredicates01.js] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + C.prototype.m = function () { + return this instanceof D; + }; + return C; +}()); +exports.C = C; +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.apply(this, arguments); + } + return D; +}(C)); +exports.D = D; + + +//// [declarationEmitThisPredicates01.d.ts] +export declare class C { + m(): this is D; +} +export declare class D extends C { +} diff --git a/tests/baselines/reference/declarationEmitThisPredicates02.js b/tests/baselines/reference/declarationEmitThisPredicates02.js new file mode 100644 index 00000000000..e938a615b6d --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicates02.js @@ -0,0 +1,34 @@ +//// [declarationEmitThisPredicates02.ts] + +export interface Foo { + a: string; + b: number; + c: boolean; +} + +export const obj = { + m(): this is Foo { + let dis = this as Foo; + return dis.a != null && dis.b != null && dis.c != null; + } +} + +//// [declarationEmitThisPredicates02.js] +"use strict"; +exports.obj = { + m: function () { + var dis = this; + return dis.a != null && dis.b != null && dis.c != null; + } +}; + + +//// [declarationEmitThisPredicates02.d.ts] +export interface Foo { + a: string; + b: number; + c: boolean; +} +export declare const obj: { + m(): this is Foo; +}; diff --git a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.js b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.js new file mode 100644 index 00000000000..e34dcc9810f --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName01.js @@ -0,0 +1,34 @@ +//// [declarationEmitThisPredicatesWithPrivateName01.ts] + +export class C { + m(): this is D { + return this instanceof D; + } +} + +class D extends C { +} + +//// [declarationEmitThisPredicatesWithPrivateName01.js] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + C.prototype.m = function () { + return this instanceof D; + }; + return C; +}()); +exports.C = C; +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.apply(this, arguments); + } + return D; +}(C)); diff --git a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js new file mode 100644 index 00000000000..df0d5b7903a --- /dev/null +++ b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js @@ -0,0 +1,23 @@ +//// [declarationEmitThisPredicatesWithPrivateName02.ts] + +interface Foo { + a: string; + b: number; + c: boolean; +} + +export const obj = { + m(): this is Foo { + let dis = this as Foo; + return dis.a != null && dis.b != null && dis.c != null; + } +} + +//// [declarationEmitThisPredicatesWithPrivateName02.js] +"use strict"; +exports.obj = { + m: function () { + var dis = this; + return dis.a != null && dis.b != null && dis.c != null; + } +}; diff --git a/tests/baselines/reference/typeGuardOfFormFunctionEquality.js b/tests/baselines/reference/typeGuardOfFormFunctionEquality.js new file mode 100644 index 00000000000..c15c1a739a9 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormFunctionEquality.js @@ -0,0 +1,26 @@ +//// [typeGuardOfFormFunctionEquality.ts] +declare function isString1(a: number, b: Object): b is string; + +declare function isString2(a: Object): a is string; + +switch (isString1(0, "")) { + case isString2(""): + default: +} + +var x = isString1(0, "") === isString2(""); + +function isString3(a: number, b: number, c: Object): c is string { + return isString1(0, c); +} + + +//// [typeGuardOfFormFunctionEquality.js] +switch (isString1(0, "")) { + case isString2(""): + default: +} +var x = isString1(0, "") === isString2(""); +function isString3(a, b, c) { + return isString1(0, c); +} diff --git a/tests/baselines/reference/typePredicateOnVariableDeclaration01.js b/tests/baselines/reference/typePredicateOnVariableDeclaration01.js new file mode 100644 index 00000000000..5831142cf5c --- /dev/null +++ b/tests/baselines/reference/typePredicateOnVariableDeclaration01.js @@ -0,0 +1,10 @@ +//// [typePredicateOnVariableDeclaration01.ts] + +var x: this is string; + +//// [typePredicateOnVariableDeclaration01.js] +var x; + + +//// [typePredicateOnVariableDeclaration01.d.ts] +declare var x: this is string; diff --git a/tests/baselines/reference/typePredicateOnVariableDeclaration02.js b/tests/baselines/reference/typePredicateOnVariableDeclaration02.js new file mode 100644 index 00000000000..b28a89116ba --- /dev/null +++ b/tests/baselines/reference/typePredicateOnVariableDeclaration02.js @@ -0,0 +1,6 @@ +//// [typePredicateOnVariableDeclaration02.ts] + +var y: z is number; + +//// [typePredicateOnVariableDeclaration02.js] +var y = is, number; From f601e6dd760b667c50298b2c0d334cd7a2d06d52 Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Wed, 3 Feb 2016 12:54:48 -0800 Subject: [PATCH 19/22] Allow decorators in JavaScript files --- src/compiler/diagnosticMessages.json | 5 ----- src/compiler/program.ts | 3 --- .../jsFileCompilationDecoratorSyntax.errors.txt | 9 --------- .../reference/jsFileCompilationDecoratorSyntax.symbols | 4 ++++ .../reference/jsFileCompilationDecoratorSyntax.types | 5 +++++ .../cases/compiler/jsFileCompilationDecoratorSyntax.ts | 1 + .../fourslash/getJavaScriptSemanticDiagnostics21.ts | 10 +--------- 7 files changed, 11 insertions(+), 26 deletions(-) delete mode 100644 tests/baselines/reference/jsFileCompilationDecoratorSyntax.errors.txt create mode 100644 tests/baselines/reference/jsFileCompilationDecoratorSyntax.symbols create mode 100644 tests/baselines/reference/jsFileCompilationDecoratorSyntax.types diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 25b86e67d34..a34a7b02c3b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2729,11 +2729,6 @@ "category": "Error", "code": 8016 }, - "'decorators' can only be used in a .ts file.": { - "category": "Error", - "code": 8017 - }, - "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": { "category": "Error", "code": 9002 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 7a2e65ed33b..bfea431d9ad 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1168,9 +1168,6 @@ namespace ts { let typeAssertionExpression = node; diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file)); return true; - case SyntaxKind.Decorator: - diagnostics.push(createDiagnosticForNode(node, Diagnostics.decorators_can_only_be_used_in_a_ts_file)); - return true; } return forEachChild(node, walk); diff --git a/tests/baselines/reference/jsFileCompilationDecoratorSyntax.errors.txt b/tests/baselines/reference/jsFileCompilationDecoratorSyntax.errors.txt deleted file mode 100644 index a39d2e1665c..00000000000 --- a/tests/baselines/reference/jsFileCompilationDecoratorSyntax.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -tests/cases/compiler/a.js(1,1): error TS8017: 'decorators' can only be used in a .ts file. - - -!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -==== tests/cases/compiler/a.js (1 errors) ==== - @internal class C { } - ~~~~~~~~~ -!!! error TS8017: 'decorators' can only be used in a .ts file. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationDecoratorSyntax.symbols b/tests/baselines/reference/jsFileCompilationDecoratorSyntax.symbols new file mode 100644 index 00000000000..02973b43147 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationDecoratorSyntax.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/a.js === +@internal class C { } +>C : Symbol(C, Decl(a.js, 0, 0)) + diff --git a/tests/baselines/reference/jsFileCompilationDecoratorSyntax.types b/tests/baselines/reference/jsFileCompilationDecoratorSyntax.types new file mode 100644 index 00000000000..ee1f14129d5 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationDecoratorSyntax.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/a.js === +@internal class C { } +>internal : any +>C : C + diff --git a/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts b/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts index 2ef95db01fe..ece41012dfe 100644 --- a/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts +++ b/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts @@ -1,3 +1,4 @@ // @allowJs: true +// @noEmit: true // @filename: a.js @internal class C { } \ No newline at end of file diff --git a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts index b71677554a2..04dae8b592b 100644 --- a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts +++ b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts @@ -4,12 +4,4 @@ // @Filename: a.js //// @internal class C {} -verify.getSemanticDiagnostics(`[ - { - "message": "'decorators' can only be used in a .ts file.", - "start": 0, - "length": 9, - "category": "error", - "code": 8017 - } -]`); \ No newline at end of file +verify.getSemanticDiagnostics(`[]`); From ed7abcc1e9ac32a637eafaf5befbf9d060b41c1e Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Fri, 12 Feb 2016 19:19:23 -0800 Subject: [PATCH 20/22] Set experimentalDecorators warning for JavaScript --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- src/compiler/program.ts | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6b43b3802c2..d385d9cff74 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12740,7 +12740,7 @@ namespace ts { } if (!compilerOptions.experimentalDecorators) { - error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning); + error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_experimentalDecorators_to_remove_this_warning); } if (compilerOptions.emitDecoratorMetadata) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a34a7b02c3b..40235bc1710 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -687,7 +687,7 @@ "category": "Error", "code": 1218 }, - "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning.": { + "Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning.": { "category": "Error", "code": 1219 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bfea431d9ad..00f8fb441d5 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1168,6 +1168,11 @@ namespace ts { let typeAssertionExpression = node; diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file)); return true; + case SyntaxKind.Decorator: + if (!options.experimentalDecorators) { + diagnostics.push(createDiagnosticForNode(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_experimentalDecorators_to_remove_this_warning)) + } + return true; } return forEachChild(node, walk); From fb474d13dde2eb6a0747edee7ffe63ed47967d41 Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Fri, 12 Feb 2016 19:35:05 -0800 Subject: [PATCH 21/22] Updated tests --- tests/baselines/reference/generatorTypeCheck39.errors.txt | 4 ++-- tests/baselines/reference/generatorTypeCheck59.errors.txt | 4 ++-- tests/baselines/reference/generatorTypeCheck61.errors.txt | 4 ++-- tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts | 3 ++- tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/baselines/reference/generatorTypeCheck39.errors.txt b/tests/baselines/reference/generatorTypeCheck39.errors.txt index ae24837f712..c9d916f63e9 100644 --- a/tests/baselines/reference/generatorTypeCheck39.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck39.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(5,16): error TS1163: A 'yield' expression is only allowed in a generator body. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(6,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(6,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(7,13): error TS1163: A 'yield' expression is only allowed in a generator body. @@ -13,7 +13,7 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(7,13): erro !!! error TS1163: A 'yield' expression is only allowed in a generator body. class C { ~ -!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning. +!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. x = yield 0; ~~~~~ !!! error TS1163: A 'yield' expression is only allowed in a generator body. diff --git a/tests/baselines/reference/generatorTypeCheck59.errors.txt b/tests/baselines/reference/generatorTypeCheck59.errors.txt index d8179803821..4ba93f10ae0 100644 --- a/tests/baselines/reference/generatorTypeCheck59.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck59.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(3,11): error TS1163: A 'yield' expression is only allowed in a generator body. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(4,9): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(4,9): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts (2 errors) ==== @@ -10,6 +10,6 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(4,9): error !!! error TS1163: A 'yield' expression is only allowed in a generator body. m() { } ~ -!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning. +!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. }; } \ No newline at end of file diff --git a/tests/baselines/reference/generatorTypeCheck61.errors.txt b/tests/baselines/reference/generatorTypeCheck61.errors.txt index b38e96d31ce..2ecfe49973d 100644 --- a/tests/baselines/reference/generatorTypeCheck61.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck61.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(2,7): error TS1163: A 'yield' expression is only allowed in a generator body. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(3,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(3,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts (2 errors) ==== @@ -9,5 +9,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(3,11): erro !!! error TS1163: A 'yield' expression is only allowed in a generator body. class C {}; ~ -!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning. +!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. } \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts b/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts index ece41012dfe..6627fb5dca0 100644 --- a/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts +++ b/tests/cases/compiler/jsFileCompilationDecoratorSyntax.ts @@ -1,4 +1,5 @@ // @allowJs: true // @noEmit: true +// @experimentalDecorators: true // @filename: a.js -@internal class C { } \ No newline at end of file +@internal class C { } diff --git a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts index 04dae8b592b..8a7120acbb3 100644 --- a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts +++ b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics21.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @experimentalDecorators: true // @Filename: a.js //// @internal class C {} From fe60490c2a0c7b6b1eea145619593d0b489f056e Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Sat, 13 Feb 2016 08:02:16 -0800 Subject: [PATCH 22/22] Fixed wording and updated tests --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- src/compiler/program.ts | 2 +- tests/baselines/reference/generatorTypeCheck39.errors.txt | 4 ++-- tests/baselines/reference/generatorTypeCheck59.errors.txt | 4 ++-- tests/baselines/reference/generatorTypeCheck61.errors.txt | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d385d9cff74..7b9cc76b11b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12740,7 +12740,7 @@ namespace ts { } if (!compilerOptions.experimentalDecorators) { - error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_experimentalDecorators_to_remove_this_warning); + error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning); } if (compilerOptions.emitDecoratorMetadata) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 40235bc1710..1829e99eb16 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -687,7 +687,7 @@ "category": "Error", "code": 1218 }, - "Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning.": { + "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.": { "category": "Error", "code": 1219 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 00f8fb441d5..a51b3eed4bf 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1170,7 +1170,7 @@ namespace ts { return true; case SyntaxKind.Decorator: if (!options.experimentalDecorators) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_experimentalDecorators_to_remove_this_warning)) + diagnostics.push(createDiagnosticForNode(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning)); } return true; } diff --git a/tests/baselines/reference/generatorTypeCheck39.errors.txt b/tests/baselines/reference/generatorTypeCheck39.errors.txt index c9d916f63e9..aabb5a47a35 100644 --- a/tests/baselines/reference/generatorTypeCheck39.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck39.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(5,16): error TS1163: A 'yield' expression is only allowed in a generator body. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(6,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(6,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(7,13): error TS1163: A 'yield' expression is only allowed in a generator body. @@ -13,7 +13,7 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts(7,13): erro !!! error TS1163: A 'yield' expression is only allowed in a generator body. class C { ~ -!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. +!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. x = yield 0; ~~~~~ !!! error TS1163: A 'yield' expression is only allowed in a generator body. diff --git a/tests/baselines/reference/generatorTypeCheck59.errors.txt b/tests/baselines/reference/generatorTypeCheck59.errors.txt index 4ba93f10ae0..cba90154701 100644 --- a/tests/baselines/reference/generatorTypeCheck59.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck59.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(3,11): error TS1163: A 'yield' expression is only allowed in a generator body. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(4,9): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(4,9): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts (2 errors) ==== @@ -10,6 +10,6 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck59.ts(4,9): error !!! error TS1163: A 'yield' expression is only allowed in a generator body. m() { } ~ -!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. +!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. }; } \ No newline at end of file diff --git a/tests/baselines/reference/generatorTypeCheck61.errors.txt b/tests/baselines/reference/generatorTypeCheck61.errors.txt index 2ecfe49973d..ccc99f7ffbd 100644 --- a/tests/baselines/reference/generatorTypeCheck61.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck61.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(2,7): error TS1163: A 'yield' expression is only allowed in a generator body. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(3,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(3,11): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts (2 errors) ==== @@ -9,5 +9,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck61.ts(3,11): erro !!! error TS1163: A 'yield' expression is only allowed in a generator body. class C {}; ~ -!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set 'experimentalDecorators' to remove this warning. +!!! error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. } \ No newline at end of file