From b86dea03f2ca8ba71f46383dd5e7895fa5741143 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 21 Mar 2019 18:27:14 -0700 Subject: [PATCH] Fix crash caused by cyclic defaults (#30532) --- src/compiler/checker.ts | 8 ++++---- ...ReferentialDefaultNoStackOverflow.errors.txt | 16 ++++++++++++++++ .../selfReferentialDefaultNoStackOverflow.js | 17 +++++++++++++++++ ...elfReferentialDefaultNoStackOverflow.symbols | 13 +++++++++++++ .../selfReferentialDefaultNoStackOverflow.types | 17 +++++++++++++++++ .../selfReferentialDefaultNoStackOverflow.ts | 11 +++++++++++ 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/selfReferentialDefaultNoStackOverflow.errors.txt create mode 100644 tests/baselines/reference/selfReferentialDefaultNoStackOverflow.js create mode 100644 tests/baselines/reference/selfReferentialDefaultNoStackOverflow.symbols create mode 100644 tests/baselines/reference/selfReferentialDefaultNoStackOverflow.types create mode 100644 tests/cases/compiler/selfReferentialDefaultNoStackOverflow.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 22333f4ec02..a261a6c38d7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5474,9 +5474,6 @@ namespace ts { } return type; } - if (declaration.kind === SyntaxKind.ExportAssignment) { - return widenTypeForVariableLikeDeclaration(checkExpressionCached((declaration).expression), declaration); - } // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { @@ -5487,7 +5484,10 @@ namespace ts { return reportCircularityError(symbol); } let type: Type | undefined; - if (isInJSFile(declaration) && + if (declaration.kind === SyntaxKind.ExportAssignment) { + type = widenTypeForVariableLikeDeclaration(checkExpressionCached((declaration).expression), declaration); + } + else if (isInJSFile(declaration) && (isCallExpression(declaration) || isBinaryExpression(declaration) || isPropertyAccessExpression(declaration) && isBinaryExpression(declaration.parent))) { type = getWidenedTypeFromAssignmentDeclaration(symbol); } diff --git a/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.errors.txt b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.errors.txt new file mode 100644 index 00000000000..9cea32dfa59 --- /dev/null +++ b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/QSpinner.js(3,1): error TS7022: 'default' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + + +==== tests/cases/compiler/QSpinner.js (1 errors) ==== + import DefaultSpinner from './QSpinner' + + export default { + ~~~~~~~~~~~~~~~~ + mixins: [DefaultSpinner], + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + name: 'QSpinner' + ~~~~~~~~~~~~~~~~~~ + } + ~ +!!! error TS7022: 'default' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + \ No newline at end of file diff --git a/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.js b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.js new file mode 100644 index 00000000000..ae736acdb2f --- /dev/null +++ b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.js @@ -0,0 +1,17 @@ +//// [QSpinner.js] +import DefaultSpinner from './QSpinner' + +export default { + mixins: [DefaultSpinner], + name: 'QSpinner' +} + + +//// [QSpinner.js] +"use strict"; +exports.__esModule = true; +var QSpinner_1 = require("./QSpinner"); +exports["default"] = { + mixins: [QSpinner_1["default"]], + name: 'QSpinner' +}; diff --git a/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.symbols b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.symbols new file mode 100644 index 00000000000..b7ead9cab77 --- /dev/null +++ b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/QSpinner.js === +import DefaultSpinner from './QSpinner' +>DefaultSpinner : Symbol(DefaultSpinner, Decl(QSpinner.js, 0, 6)) + +export default { + mixins: [DefaultSpinner], +>mixins : Symbol(mixins, Decl(QSpinner.js, 2, 16)) +>DefaultSpinner : Symbol(DefaultSpinner, Decl(QSpinner.js, 0, 6)) + + name: 'QSpinner' +>name : Symbol(name, Decl(QSpinner.js, 3, 27)) +} + diff --git a/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.types b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.types new file mode 100644 index 00000000000..b4d1545186f --- /dev/null +++ b/tests/baselines/reference/selfReferentialDefaultNoStackOverflow.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/QSpinner.js === +import DefaultSpinner from './QSpinner' +>DefaultSpinner : any + +export default { +>{ mixins: [DefaultSpinner], name: 'QSpinner'} : { mixins: any[]; name: string; } + + mixins: [DefaultSpinner], +>mixins : any[] +>[DefaultSpinner] : any[] +>DefaultSpinner : any + + name: 'QSpinner' +>name : string +>'QSpinner' : "QSpinner" +} + diff --git a/tests/cases/compiler/selfReferentialDefaultNoStackOverflow.ts b/tests/cases/compiler/selfReferentialDefaultNoStackOverflow.ts new file mode 100644 index 00000000000..55199e6da29 --- /dev/null +++ b/tests/cases/compiler/selfReferentialDefaultNoStackOverflow.ts @@ -0,0 +1,11 @@ +// @allowJs: true +// @checkJs: true +// @strict: true +// @outDir: ./out +// @filename: QSpinner.js +import DefaultSpinner from './QSpinner' + +export default { + mixins: [DefaultSpinner], + name: 'QSpinner' +}