Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control flow for constructor initialized properties #37920

Merged
merged 10 commits into from
Apr 28, 2020
6 changes: 3 additions & 3 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ namespace ts {
}
// We create a return control flow graph for IIFEs and constructors. For constructors
// we use the return control flow graph in strict property initialization checks.
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined;
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor || (isInJSFile && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression)) ? createBranchLabel() : undefined;
currentExceptionTarget = undefined;
currentBreakTarget = undefined;
currentContinueTarget = undefined;
Expand All @@ -680,8 +680,8 @@ namespace ts {
if (currentReturnTarget) {
addAntecedent(currentReturnTarget, currentFlow);
currentFlow = finishFlowLabel(currentReturnTarget);
if (node.kind === SyntaxKind.Constructor) {
(<ConstructorDeclaration>node).returnFlowNode = currentFlow;
if (node.kind === SyntaxKind.Constructor || (isInJSFile && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression))) {
(<FunctionLikeDeclaration>node).returnFlowNode = currentFlow;
}
}
if (!isIIFE) {
Expand Down
185 changes: 129 additions & 56 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,7 @@ namespace ts {
exclamationToken?: ExclamationToken;
body?: Block | Expression;
/* @internal */ endFlowNode?: FlowNode;
/* @internal */ returnFlowNode?: FlowNode;
}

export type FunctionLikeDeclaration =
Expand Down Expand Up @@ -1152,7 +1153,6 @@ namespace ts {
kind: SyntaxKind.Constructor;
parent: ClassLikeDeclaration;
body?: FunctionBody;
/* @internal */ returnFlowNode?: FlowNode;
}

/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */
Expand Down Expand Up @@ -4156,6 +4156,7 @@ namespace ts {
deferralParent?: Type; // Source union/intersection of a deferred type
cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target
typeOnlyDeclaration?: TypeOnlyCompatibleAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs
isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor
}

/* @internal */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ function Person(name) {

this.name = name;
>this.name = name : string
>this.name : string
>this.name : any
>this : this
>name : string
>name : any
>name : string
}
Person.prototype.describe = function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ someFunction(function(BaseClass) {

this.foo = "bar";
>this.foo = "bar" : "bar"
>this.foo : string
>this.foo : any
>this : this
>foo : string
>foo : any
>"bar" : "bar"
}
_render(error) {
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/checkJsFiles_noErrorLocation.types
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class B extends A {

this.foo = () => 3;
>this.foo = () => 3 : () => number
>this.foo : () => number
>this.foo : any
>this : this
>foo : () => number
>foo : any
>() => 3 : () => number
>3 : 3
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ class Derived {

this.x = 10;
>this.x = 10 : 10
>this.x : number
>this.x : any
>this : this
>x : number
>x : any
>10 : 10

var that = this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ function Wagon(numberOxen) {

this.numberOxen = numberOxen
>this.numberOxen = numberOxen : number
>this.numberOxen : number
>this.numberOxen : any
>this : this
>numberOxen : number
>numberOxen : any
>numberOxen : number
}
/** @param {Wagon[]=} wagons */
Expand Down Expand Up @@ -91,9 +91,9 @@ class Sql extends Wagon {

this.foonly = 12
>this.foonly = 12 : 12
>this.foonly : number
>this.foonly : any
>this : this
>foonly : number
>foonly : any
>12 : 12
}
/**
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/classExtendingAny.types
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ class B extends Err {

this.wat = 12
>this.wat = 12 : 12
>this.wat : number
>this.wat : any
>this : this
>wat : number
>wat : any
>12 : 12
}
f() {
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/constructorFunctions.types
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ function C6() {

this.functions = [x => x, x => x + 1, x => x - 1]
>this.functions = [x => x, x => x + 1, x => x - 1] : ((x: any) => any)[]
>this.functions : ((x: any) => any)[]
>this.functions : any
>this : this
>functions : ((x: any) => any)[]
>functions : any
>[x => x, x => x + 1, x => x - 1] : ((x: any) => any)[]
>x => x : (x: any) => any
>x : any
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/constructorFunctionsStrict.types
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ var j = new A(2)

k.x === j.x
>k.x === j.x : boolean
>k.x : number
>k.x : number | undefined
>k : A
>x : number
>j.x : number
>x : number | undefined
>j.x : number | undefined
>j : A
>x : number
>x : number | undefined

4 changes: 2 additions & 2 deletions tests/baselines/reference/exportNestedNamespaces.types
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ exports.Classic = class {
constructor() {
this.p = 1
>this.p = 1 : 1
>this.p : number
>this.p : any
>this : this
>p : number
>p : any
>1 : 1
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ class C {

this.inConstructor = 0;
>this.inConstructor = 0 : 0
>this.inConstructor : string | number
>this.inConstructor : any
>this : this
>inConstructor : string | number
>inConstructor : any
>0 : 0
}
else {
this.inConstructor = "string"
>this.inConstructor = "string" : "string"
>this.inConstructor : string | number
>this.inConstructor : any
>this : this
>inConstructor : string | number
>inConstructor : any
>"string" : "string"
}
this.inMultiple = 0;
>this.inMultiple = 0 : 0
>this.inMultiple : number
>this.inMultiple : any
>this : this
>inMultiple : number
>inMultiple : any
>0 : 0
}
method() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class Base {
constructor() {
this.p = 1
>this.p = 1 : 1
>this.p : number
>this.p : any
>this : this
>p : number
>p : any
>1 : 1
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class Derived extends Base {
// should be OK, and p should have type number from this assignment
this.p = 1
>this.p = 1 : 1
>this.p : number
>this.p : any
>this : this
>p : number
>p : any
>1 : 1
}
test() {
Expand Down
20 changes: 10 additions & 10 deletions tests/baselines/reference/jsDeclarationsClasses.types
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,16 @@ export class K {
constructor() {
this.p1 = 12;
>this.p1 = 12 : 12
>this.p1 : number
>this.p1 : any
>this : this
>p1 : number
>p1 : any
>12 : 12

this.p2 = "ok";
>this.p2 = "ok" : "ok"
>this.p2 : string
>this.p2 : any
>this : this
>p2 : string
>p2 : any
>"ok" : "ok"
}

Expand All @@ -243,9 +243,9 @@ export class M extends null {
constructor() {
this.prop = 12;
>this.prop = 12 : 12
>this.prop : number
>this.prop : any
>this : this
>prop : number
>prop : any
>12 : 12
}
}
Expand All @@ -270,9 +270,9 @@ export class N extends L {

this.another = param;
>this.another = param : T
>this.another : T
>this.another : any
>this : this
>another : T
>another : any
>param : T
}
}
Expand All @@ -298,9 +298,9 @@ export class O extends N {

this.another2 = param;
>this.another2 = param : U
>this.another2 : U
>this.another2 : any
>this : this
>another2 : U
>another2 : any
>param : U
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ module.exports = class Thing {

this.t = 12 + p;
>this.t = 12 + p : number
>this.t : number
>this.t : any
>this : this
>t : number
>t : any
>12 + p : number
>12 : 12
>p : number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ module.exports = class {

this.t = 12 + p;
>this.t = 12 + p : number
>this.t : number
>this.t : any
>this : this
>t : number
>t : any
>12 + p : number
>12 : 12
>p : number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ module.exports = class {

this.t = 12 + p;
>this.t = 12 + p : number
>this.t : number
>this.t : any
>this : this
>t : number
>t : any
>12 + p : number
>12 : 12
>p : number
Expand All @@ -34,9 +34,9 @@ module.exports.Sub = class {
constructor() {
this.instance = new module.exports(10);
>this.instance = new module.exports(10) : import("tests/cases/conformance/jsdoc/declarations/index")
>this.instance : import("tests/cases/conformance/jsdoc/declarations/index")
>this.instance : any
>this : this
>instance : import("tests/cases/conformance/jsdoc/declarations/index")
>instance : any
>new module.exports(10) : import("tests/cases/conformance/jsdoc/declarations/index")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index")
>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof import("tests/cases/conformance/jsdoc/declarations/index"); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ module.exports = class Q {
constructor() {
this.x = new A();
>this.x = new A() : A
>this.x : A
>this.x : any
>this : this
>x : A
>x : any
>new A() : A
>A : typeof A
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ module.exports.MyClass = function() {

this.x = 1
>this.x = 1 : 1
>this.x : number
>this.x : any
>this : this
>x : number
>x : any
>1 : 1
}
module.exports.MyClass.prototype = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class Container {
constructor() {
this.usage = new Obj();
>this.usage = new Obj() : import("tests/cases/conformance/jsdoc/declarations/obj")
>this.usage : import("tests/cases/conformance/jsdoc/declarations/obj")
>this.usage : any
>this : this
>usage : import("tests/cases/conformance/jsdoc/declarations/obj")
>usage : any
>new Obj() : import("tests/cases/conformance/jsdoc/declarations/obj")
>Obj : typeof import("tests/cases/conformance/jsdoc/declarations/obj")
}
Expand All @@ -38,9 +38,9 @@ module.exports = class Obj {
constructor() {
this.x = 12;
>this.x = 12 : 12
>this.x : number
>this.x : any
>this : this
>x : number
>x : any
>12 : 12
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ class Wrap {

this.connItem = c.item;
>this.connItem = c.item : number
>this.connItem : number
>this.connItem : any
>this : this
>connItem : number
>connItem : any
>c.item : number
>c : import("tests/cases/conformance/jsdoc/declarations/conn")
>item : number
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/jsFileClassPropertyType.types
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class C {
constructor () {
this.p = 0;
>this.p = 0 : 0
>this.p : number
>this.p : any
>this : this
>p : number
>p : any
>0 : 0
}
}
Expand Down
Loading