mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #9305 from RyanCavanaugh/fix9293
Properly detect circular constructor-declared `this` properties (JS)
This commit is contained in:
+19
-13
@@ -3151,23 +3151,29 @@ namespace ts {
|
||||
if (declaration.kind === SyntaxKind.ExportAssignment) {
|
||||
return links.type = checkExpression((<ExportAssignment>declaration).expression);
|
||||
}
|
||||
// Handle module.exports = expr
|
||||
if (declaration.kind === SyntaxKind.BinaryExpression) {
|
||||
return links.type = getUnionType(map(symbol.declarations, (decl: BinaryExpression) => checkExpressionCached(decl.right)));
|
||||
}
|
||||
if (declaration.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
// Declarations only exist for property access expressions for certain
|
||||
// special assignment kinds
|
||||
if (declaration.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
// Handle exports.p = expr or this.p = expr or className.prototype.method = expr
|
||||
return links.type = checkExpressionCached((<BinaryExpression>declaration.parent).right);
|
||||
}
|
||||
}
|
||||
// Handle variable, parameter or property
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||
return unknownType;
|
||||
}
|
||||
let type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
||||
|
||||
let type: Type = undefined;
|
||||
// Handle module.exports = expr or this.p = expr
|
||||
if (declaration.kind === SyntaxKind.BinaryExpression) {
|
||||
type = getUnionType(map(symbol.declarations, (decl: BinaryExpression) => checkExpressionCached(decl.right)));
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
// Declarations only exist for property access expressions for certain
|
||||
// special assignment kinds
|
||||
if (declaration.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
// Handle exports.p = expr or className.prototype.method = expr
|
||||
type = checkExpressionCached((<BinaryExpression>declaration.parent).right);
|
||||
}
|
||||
}
|
||||
|
||||
if (type === undefined) {
|
||||
type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
||||
}
|
||||
|
||||
if (!popTypeResolution()) {
|
||||
if ((<VariableLikeDeclaration>symbol.valueDeclaration).type) {
|
||||
// Variable has type annotation that circularly references the variable itself
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
|
||||
c;
|
||||
>c : Symbol(c, Decl(file2.ts, 0, 5))
|
||||
|
||||
=== tests/cases/compiler/file2.ts ===
|
||||
const c = 0;
|
||||
>c : Symbol(c, Decl(file2.ts, 0, 5))
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
|
||||
c;
|
||||
>c : number
|
||||
|
||||
=== tests/cases/compiler/file2.ts ===
|
||||
const c = 0;
|
||||
>c : number
|
||||
>0 : number
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
=== tests/cases/compiler/foo.js ===
|
||||
|
||||
export class StackOverflowTest {
|
||||
>StackOverflowTest : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
|
||||
|
||||
constructor () {
|
||||
this.testStackOverflow = this.testStackOverflow.bind(this)
|
||||
>this.testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
|
||||
>this : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
|
||||
>testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
|
||||
>this.testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
|
||||
>this : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
|
||||
>testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
|
||||
>this : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
=== tests/cases/compiler/foo.js ===
|
||||
|
||||
export class StackOverflowTest {
|
||||
>StackOverflowTest : StackOverflowTest
|
||||
|
||||
constructor () {
|
||||
this.testStackOverflow = this.testStackOverflow.bind(this)
|
||||
>this.testStackOverflow = this.testStackOverflow.bind(this) : any
|
||||
>this.testStackOverflow : any
|
||||
>this : this
|
||||
>testStackOverflow : any
|
||||
>this.testStackOverflow.bind(this) : any
|
||||
>this.testStackOverflow.bind : any
|
||||
>this.testStackOverflow : any
|
||||
>this : this
|
||||
>testStackOverflow : any
|
||||
>bind : any
|
||||
>this : this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
|
||||
l;
|
||||
>l : Symbol(l, Decl(file2.ts, 0, 5))
|
||||
|
||||
=== tests/cases/compiler/file2.ts ===
|
||||
const l = 0;
|
||||
>l : Symbol(l, Decl(file2.ts, 0, 5))
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
|
||||
l;
|
||||
>l : number
|
||||
|
||||
=== tests/cases/compiler/file2.ts ===
|
||||
const l = 0;
|
||||
>l : number
|
||||
>0 : number
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'
|
||||
|
||||
|
||||
!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'
|
||||
==== file.ts (0 errors) ====
|
||||
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
"use strict";
|
||||
//# sourceMappingURL=file.js.map
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'
|
||||
|
||||
|
||||
!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'
|
||||
==== file.ts (0 errors) ====
|
||||
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
"use strict";
|
||||
//# sourceMappingURL=file.js.map
|
||||
@@ -0,0 +1,9 @@
|
||||
// @allowJs: true
|
||||
// @noEmit: true
|
||||
|
||||
// @filename: foo.js
|
||||
export class StackOverflowTest {
|
||||
constructor () {
|
||||
this.testStackOverflow = this.testStackOverflow.bind(this)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user