From d75de605480f9d1c91d43e8a70d3913c31172956 Mon Sep 17 00:00:00 2001 From: rChaser53 Date: Tue, 20 Aug 2019 04:08:34 +0900 Subject: [PATCH] Fix Cannot read property 'text' of undefined crash (#32734) * Fix Cannot read property 'text' of undefined crash * fix condition for tsx * Rename and improve the method --- src/compiler/checker.ts | 12 ++++++++---- .../reference/errorElaboration.errors.txt | 19 ++++++++++++++++++- tests/baselines/reference/errorElaboration.js | 11 +++++++++++ .../reference/errorElaboration.symbols | 12 ++++++++++++ .../reference/errorElaboration.types | 17 +++++++++++++++++ tests/cases/compiler/errorElaboration.ts | 5 +++++ 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 478c7b46075..7f7e36cb1f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3525,8 +3525,8 @@ namespace ts { } function getTypeNamesForErrorDisplay(left: Type, right: Type): [string, string] { - let leftStr = typeToString(left); - let rightStr = typeToString(right); + let leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left); + let rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right); if (leftStr === rightStr) { leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); @@ -3534,6 +3534,10 @@ namespace ts { return [leftStr, rightStr]; } + function symbolValueDeclarationIsContextSensitive(symbol: Symbol): boolean { + return symbol && symbol.valueDeclaration && isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration); + } + function toNodeBuilderFlags(flags = TypeFormatFlags.None): NodeBuilderFlags { return flags & TypeFormatFlags.NodeBuilderFlagsMask; } @@ -12718,8 +12722,8 @@ namespace ts { } function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) { - const sourceType = typeToString(source); - const targetType = typeToString(target); + const sourceType = symbolValueDeclarationIsContextSensitive(source.symbol) ? typeToString(source, source.symbol.valueDeclaration) : typeToString(source); + const targetType = symbolValueDeclarationIsContextSensitive(target.symbol) ? typeToString(target, target.symbol.valueDeclaration) : typeToString(target); if ((globalStringType === source && stringType === target) || (globalNumberType === source && numberType === target) || diff --git a/tests/baselines/reference/errorElaboration.errors.txt b/tests/baselines/reference/errorElaboration.errors.txt index 57971cad269..30c4fe8efd6 100644 --- a/tests/baselines/reference/errorElaboration.errors.txt +++ b/tests/baselines/reference/errorElaboration.errors.txt @@ -1,11 +1,15 @@ +tests/cases/compiler/errorElaboration.ts(10,18): error TS2300: Duplicate identifier 'foo'. tests/cases/compiler/errorElaboration.ts(12,5): error TS2345: Argument of type '() => Container>' is not assignable to parameter of type '() => Container>'. Type 'Container>' is not assignable to type 'Container>'. Type 'Ref' is not assignable to type 'Ref'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +tests/cases/compiler/errorElaboration.ts(22,7): error TS2300: Duplicate identifier 'foo'. +tests/cases/compiler/errorElaboration.ts(23,15): error TS2538: Type 'any' cannot be used as an index type. +tests/cases/compiler/errorElaboration.ts(23,19): error TS2339: Property 'bar' does not exist on type '(x: () => Container>) => void'. -==== tests/cases/compiler/errorElaboration.ts (2 errors) ==== +==== tests/cases/compiler/errorElaboration.ts (6 errors) ==== // Repro for #5712 interface Ref { @@ -16,6 +20,8 @@ tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is n m2: T; } declare function foo(x: () => Container>): void; + ~~~ +!!! error TS2300: Duplicate identifier 'foo'. let a: () => Container>; foo(a); ~ @@ -32,4 +38,15 @@ tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is n !!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. !!! related TS6500 tests/cases/compiler/errorElaboration.ts:16:18: The expected type comes from property 'foo' which is declared here on type '{ foo: "foo"; }' } + + // Repro for #32358 + + const foo = { bar: 'a' }; + ~~~ +!!! error TS2300: Duplicate identifier 'foo'. + const x = ({ [foo.bar]: c }) => undefined; + ~~~~~~~ +!!! error TS2538: Type 'any' cannot be used as an index type. + ~~~ +!!! error TS2339: Property 'bar' does not exist on type '(x: () => Container>) => void'. \ No newline at end of file diff --git a/tests/baselines/reference/errorElaboration.js b/tests/baselines/reference/errorElaboration.js index c1dd0a470d3..f5e021363e9 100644 --- a/tests/baselines/reference/errorElaboration.js +++ b/tests/baselines/reference/errorElaboration.js @@ -17,6 +17,11 @@ foo(a); function test(): {[A in "foo"]: A} { return {foo: "bar"}; } + +// Repro for #32358 + +const foo = { bar: 'a' }; +const x = ({ [foo.bar]: c }) => undefined; //// [errorElaboration.js] @@ -27,3 +32,9 @@ foo(a); function test() { return { foo: "bar" }; } +// Repro for #32358 +var foo = { bar: 'a' }; +var x = function (_a) { + var _b = foo.bar, c = _a[_b]; + return undefined; +}; diff --git a/tests/baselines/reference/errorElaboration.symbols b/tests/baselines/reference/errorElaboration.symbols index 839b19c0599..407fc9b2568 100644 --- a/tests/baselines/reference/errorElaboration.symbols +++ b/tests/baselines/reference/errorElaboration.symbols @@ -49,3 +49,15 @@ function test(): {[A in "foo"]: A} { >foo : Symbol(foo, Decl(errorElaboration.ts, 16, 10)) } +// Repro for #32358 + +const foo = { bar: 'a' }; +>foo : Symbol(foo, Decl(errorElaboration.ts, 21, 5)) +>bar : Symbol(bar, Decl(errorElaboration.ts, 21, 13)) + +const x = ({ [foo.bar]: c }) => undefined; +>x : Symbol(x, Decl(errorElaboration.ts, 22, 5)) +>foo : Symbol(foo, Decl(errorElaboration.ts, 8, 1)) +>c : Symbol(c, Decl(errorElaboration.ts, 22, 12)) +>undefined : Symbol(undefined) + diff --git a/tests/baselines/reference/errorElaboration.types b/tests/baselines/reference/errorElaboration.types index d46222071f4..6957a9f48b1 100644 --- a/tests/baselines/reference/errorElaboration.types +++ b/tests/baselines/reference/errorElaboration.types @@ -35,3 +35,20 @@ function test(): {[A in "foo"]: A} { >"bar" : "bar" } +// Repro for #32358 + +const foo = { bar: 'a' }; +>foo : { bar: string; } +>{ bar: 'a' } : { bar: string; } +>bar : string +>'a' : "a" + +const x = ({ [foo.bar]: c }) => undefined; +>x : ({ [foo.bar]: c }: {}) => any +>({ [foo.bar]: c }) => undefined : ({ [foo.bar]: c }: {}) => any +>foo.bar : any +>foo : (x: () => Container>) => void +>bar : any +>c : any +>undefined : undefined + diff --git a/tests/cases/compiler/errorElaboration.ts b/tests/cases/compiler/errorElaboration.ts index 87575f1df11..bea98f7e60a 100644 --- a/tests/cases/compiler/errorElaboration.ts +++ b/tests/cases/compiler/errorElaboration.ts @@ -16,3 +16,8 @@ foo(a); function test(): {[A in "foo"]: A} { return {foo: "bar"}; } + +// Repro for #32358 + +const foo = { bar: 'a' }; +const x = ({ [foo.bar]: c }) => undefined;