From 3ce7bd194097d7bec980ca8467fb36bf7234b7ff Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 17 Oct 2019 13:23:06 -0700 Subject: [PATCH 1/4] Fix stack overflow in circular assignment declaration It also needs to have multiple assignments so that it has a ValueModule flag. Fixes #33006 --- src/compiler/checker.ts | 3 --- ...cularMultipleAssignmentDeclaration.symbols | 15 +++++++++++ ...ircularMultipleAssignmentDeclaration.types | 25 +++++++++++++++++++ .../circularMultipleAssignmentDeclaration.ts | 6 +++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/circularMultipleAssignmentDeclaration.symbols create mode 100644 tests/baselines/reference/circularMultipleAssignmentDeclaration.types create mode 100644 tests/cases/conformance/salsa/circularMultipleAssignmentDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3228b6bf1dff4..255e07c6654c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7270,9 +7270,6 @@ namespace ts { // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` - if (symbol.flags & SymbolFlags.ValueModule) { - return getTypeOfFuncClassEnumModule(symbol); - } return reportCircularityError(symbol); } let type: Type | undefined; diff --git a/tests/baselines/reference/circularMultipleAssignmentDeclaration.symbols b/tests/baselines/reference/circularMultipleAssignmentDeclaration.symbols new file mode 100644 index 0000000000000..c298d31ee7c0c --- /dev/null +++ b/tests/baselines/reference/circularMultipleAssignmentDeclaration.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/salsa/circularMultipleAssignmentDeclaration.js === +ns.next = ns.next || { shared: {} }; +>ns.next : Symbol(ns.next, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 1, 3)) +>ns : Symbol(ns, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 0, 36)) +>next : Symbol(ns.next, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 1, 3)) +>ns.next : Symbol(ns.next, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 1, 3)) +>ns : Symbol(ns, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 0, 36)) +>next : Symbol(ns.next, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 1, 3)) +>shared : Symbol(shared, Decl(circularMultipleAssignmentDeclaration.js, 0, 22)) + +ns.next.shared.mymethod = {}; +>ns.next : Symbol(ns.next, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 1, 3)) +>ns : Symbol(ns, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 0, 36)) +>next : Symbol(ns.next, Decl(circularMultipleAssignmentDeclaration.js, 0, 0), Decl(circularMultipleAssignmentDeclaration.js, 1, 3)) + diff --git a/tests/baselines/reference/circularMultipleAssignmentDeclaration.types b/tests/baselines/reference/circularMultipleAssignmentDeclaration.types new file mode 100644 index 0000000000000..6b5239ed4e475 --- /dev/null +++ b/tests/baselines/reference/circularMultipleAssignmentDeclaration.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/salsa/circularMultipleAssignmentDeclaration.js === +ns.next = ns.next || { shared: {} }; +>ns.next = ns.next || { shared: {} } : any +>ns.next : any +>ns : typeof ns +>next : any +>ns.next || { shared: {} } : any +>ns.next : any +>ns : typeof ns +>next : any +>{ shared: {} } : { shared: {}; } +>shared : {} +>{} : {} + +ns.next.shared.mymethod = {}; +>ns.next.shared.mymethod = {} : {} +>ns.next.shared.mymethod : any +>ns.next.shared : any +>ns.next : any +>ns : typeof ns +>next : any +>shared : any +>mymethod : any +>{} : {} + diff --git a/tests/cases/conformance/salsa/circularMultipleAssignmentDeclaration.ts b/tests/cases/conformance/salsa/circularMultipleAssignmentDeclaration.ts new file mode 100644 index 0000000000000..bc2c992dafcc8 --- /dev/null +++ b/tests/cases/conformance/salsa/circularMultipleAssignmentDeclaration.ts @@ -0,0 +1,6 @@ +// @filename:circularMultipleAssignmentDeclaration.js +// @allowJs: true +// @checkJs: true +// @noEmit: true +ns.next = ns.next || { shared: {} }; +ns.next.shared.mymethod = {}; From e7132e201473b14ea7a72710743de9438e430e25 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 17 Oct 2019 13:26:02 -0700 Subject: [PATCH 2/4] remove errant comment --- src/compiler/checker.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 255e07c6654c7..d20c43088f176 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7269,7 +7269,6 @@ namespace ts { // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { - // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` return reportCircularityError(symbol); } let type: Type | undefined; From 4952683491e2bbc22b3ebcd94250aecf3173a40d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 17 Oct 2019 13:35:58 -0700 Subject: [PATCH 3/4] Remove other possible circularity --- src/compiler/checker.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d20c43088f176..b40d523ee0de9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7335,10 +7335,6 @@ namespace ts { } if (!popTypeResolution()) { - // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` - if (symbol.flags & SymbolFlags.ValueModule) { - return getTypeOfFuncClassEnumModule(symbol); - } return reportCircularityError(symbol); } return type; From e55b30ad187c7a2fff0e400b5b97bbc913b19ff5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 18 Oct 2019 08:37:44 -0700 Subject: [PATCH 4/4] Restore fallback with additional condition --- src/compiler/checker.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b40d523ee0de9..e98d96b6fed34 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7269,6 +7269,10 @@ namespace ts { // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { + // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` + if (symbol.flags & SymbolFlags.ValueModule && !(symbol.flags & SymbolFlags.Assignment)) { + return getTypeOfFuncClassEnumModule(symbol); + } return reportCircularityError(symbol); } let type: Type | undefined; @@ -7335,6 +7339,10 @@ namespace ts { } if (!popTypeResolution()) { + // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` + if (symbol.flags & SymbolFlags.ValueModule && !(symbol.flags & SymbolFlags.Assignment)) { + return getTypeOfFuncClassEnumModule(symbol); + } return reportCircularityError(symbol); } return type;