Enable CFA on this keyword unconditionally (#21490)

This commit is contained in:
Wesley Wigham
2018-02-02 00:30:03 -08:00
committed by GitHub
parent 06c5d393b5
commit 8b81d19b6d
5 changed files with 115 additions and 3 deletions

View File

@@ -13341,13 +13341,13 @@ namespace ts {
.expression; // x
const classSymbol = checkExpression(className).symbol;
if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
return getInferredClassType(classSymbol);
return getFlowTypeOfReference(node, getInferredClassType(classSymbol));
}
}
const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
if (thisType) {
return thisType;
return getFlowTypeOfReference(node, thisType);
}
}
@@ -13360,7 +13360,7 @@ namespace ts {
if (isInJavaScriptFile(node)) {
const type = getTypeForThisExpressionFromJSDoc(container);
if (type && type !== unknownType) {
return type;
return getFlowTypeOfReference(node, type);
}
}
}

View File

@@ -0,0 +1,26 @@
//// [controlFlowAnalysisOnBareThisKeyword.ts]
declare function isBig(x: any): x is { big: true };
function bigger(this: {}) {
if (isBig(this)) {
this.big; // Expect property to exist
}
}
function bar(this: string | number) {
if (typeof this === "string") {
const x: string = this;
}
}
//// [controlFlowAnalysisOnBareThisKeyword.js]
"use strict";
function bigger() {
if (isBig(this)) {
this.big; // Expect property to exist
}
}
function bar() {
if (typeof this === "string") {
var x = this;
}
}

View File

@@ -0,0 +1,34 @@
=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts ===
declare function isBig(x: any): x is { big: true };
>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0))
>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23))
>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23))
>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38))
function bigger(this: {}) {
>bigger : Symbol(bigger, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 51))
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16))
if (isBig(this)) {
>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0))
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16))
this.big; // Expect property to exist
>this.big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38))
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16))
>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38))
}
}
function bar(this: string | number) {
>bar : Symbol(bar, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 5, 1))
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13))
if (typeof this === "string") {
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13))
const x: string = this;
>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 9, 13))
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13))
}
}

View File

@@ -0,0 +1,39 @@
=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts ===
declare function isBig(x: any): x is { big: true };
>isBig : (x: any) => x is { big: true; }
>x : any
>x : any
>big : true
>true : true
function bigger(this: {}) {
>bigger : (this: {}) => void
>this : {}
if (isBig(this)) {
>isBig(this) : boolean
>isBig : (x: any) => x is { big: true; }
>this : {}
this.big; // Expect property to exist
>this.big : true
>this : { big: true; }
>big : true
}
}
function bar(this: string | number) {
>bar : (this: string | number) => void
>this : string | number
if (typeof this === "string") {
>typeof this === "string" : boolean
>typeof this : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>this : string | number
>"string" : "string"
const x: string = this;
>x : string
>this : string
}
}

View File

@@ -0,0 +1,13 @@
// @strict: true
declare function isBig(x: any): x is { big: true };
function bigger(this: {}) {
if (isBig(this)) {
this.big; // Expect property to exist
}
}
function bar(this: string | number) {
if (typeof this === "string") {
const x: string = this;
}
}