From b1571fcb71501d16f21173979365d4c4d53a11cb Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 29 Mar 2021 06:12:40 +0000 Subject: [PATCH 01/16] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6e01da81c05..50123efe16c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7940,9 +7940,9 @@ "dev": true }, "uglify-js": { - "version": "3.13.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.2.tgz", - "integrity": "sha512-SbMu4D2Vo95LMC/MetNaso1194M1htEA+JrqE9Hk+G2DhI+itfS9TRu9ZKeCahLDNa/J3n4MqUJ/fOHMzQpRWw==", + "version": "3.13.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.3.tgz", + "integrity": "sha512-otIc7O9LyxpUcQoXzj2hL4LPWKklO6LJWoJUzNa8A17Xgi4fOeDC8FBDOLHnC/Slo1CQgsZMcM6as0M76BZaig==", "dev": true, "optional": true }, From 11097c622cc53df73fea6cfb5076bd946148d9cf Mon Sep 17 00:00:00 2001 From: Greg Finley Date: Mon, 29 Mar 2021 04:14:44 -0700 Subject: [PATCH 02/16] Fix typo (#43404) * Fix typo * Fix off baseline Co-authored-by: Orta --- src/lib/es5.d.ts | 4 ++-- .../reference/completionEntryForUnionMethod.baseline | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index b8ae7ca57ef..bfa5241a84d 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1073,7 +1073,7 @@ interface ReadonlyArray { */ toString(): string; /** - * Returns a string representation of an array. The elements are converted to string using their toLocalString methods. + * Returns a string representation of an array. The elements are converted to string using their toLocaleString methods. */ toLocaleString(): string; /** @@ -1207,7 +1207,7 @@ interface Array { */ toString(): string; /** - * Returns a string representation of an array. The elements are converted to string using their toLocalString methods. + * Returns a string representation of an array. The elements are converted to string using their toLocaleString methods. */ toLocaleString(): string; /** diff --git a/tests/baselines/reference/completionEntryForUnionMethod.baseline b/tests/baselines/reference/completionEntryForUnionMethod.baseline index ce000ec6ddb..858d356be23 100644 --- a/tests/baselines/reference/completionEntryForUnionMethod.baseline +++ b/tests/baselines/reference/completionEntryForUnionMethod.baseline @@ -223,7 +223,7 @@ ], "documentation": [ { - "text": "Returns a string representation of an array. The elements are converted to string using their toLocalString methods.", + "text": "Returns a string representation of an array. The elements are converted to string using their toLocaleString methods.", "kind": "text" } ] From a3d207a9051f2e520b86f30c59f15d63e7f3e429 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 29 Mar 2021 12:44:05 -0700 Subject: [PATCH 03/16] Improve (and actually use) "always truthy promise" error (#43023) * Modify error message and actually use the error message. * Accepted baselines. --- src/compiler/checker.ts | 6 +-- src/compiler/diagnosticMessages.json | 4 +- src/services/codefixes/addMissingAwait.ts | 1 + .../codefixes/fixMissingCallParentheses.ts | 2 +- ...ruthinessCallExpressionCoercion.errors.txt | 28 ++++++------ ...uthinessCallExpressionCoercion1.errors.txt | 20 ++++----- ...uthinessCallExpressionCoercion2.errors.txt | 44 +++++++++---------- .../truthinessPromiseCoercion.errors.txt | 8 ++-- 8 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 193bb1d8c80..387d9187e6c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35248,8 +35248,8 @@ namespace ts { errorAndMaybeSuggestAwait( condExpr, /*maybeMissingAwait*/ true, - Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, - "true", getTypeNameForErrorDisplay(type), "false"); + Diagnostics.This_condition_will_always_return_true_since_this_0_appears_to_always_be_defined, + getTypeNameForErrorDisplay(type)); return; } @@ -35282,7 +35282,7 @@ namespace ts { const isUsed = isBinaryExpression(condExpr.parent) && isFunctionUsedInBinaryExpressionChain(condExpr.parent, testedSymbol) || body && isFunctionUsedInConditionBody(condExpr, body, testedNode, testedSymbol); if (!isUsed) { - error(location, Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead); + error(location, Diagnostics.This_condition_will_always_return_true_since_this_function_appears_to_always_be_defined_Did_you_mean_to_call_it_instead); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f7d4fcc84ee..33e528fa6d9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3168,7 +3168,7 @@ "category": "Error", "code": 2773 }, - "This condition will always return true since the function is always defined. Did you mean to call it instead?": { + "This condition will always return true since this function appears to always be defined. Did you mean to call it instead?": { "category": "Error", "code": 2774 }, @@ -3276,7 +3276,7 @@ "category": "Error", "code": 2800 }, - "This condition will always return true since the Promise is always truthy.": { + "This condition will always return true since this '{0}' appears to always be defined.": { "category": "Error", "code": 2801 }, diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index 1b16a33deb3..a31bf50f46e 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -14,6 +14,7 @@ namespace ts.codefix { Diagnostics.Operator_0_cannot_be_applied_to_type_1.code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap.code, + Diagnostics.This_condition_will_always_return_true_since_this_0_appears_to_always_be_defined.code, Diagnostics.Type_0_is_not_an_array_type.code, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type.code, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators.code, diff --git a/src/services/codefixes/fixMissingCallParentheses.ts b/src/services/codefixes/fixMissingCallParentheses.ts index a144bc40f50..042f7b506c7 100644 --- a/src/services/codefixes/fixMissingCallParentheses.ts +++ b/src/services/codefixes/fixMissingCallParentheses.ts @@ -2,7 +2,7 @@ namespace ts.codefix { const fixId = "fixMissingCallParentheses"; const errorCodes = [ - Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead.code, + Diagnostics.This_condition_will_always_return_true_since_this_function_appears_to_always_be_defined_Did_you_mean_to_call_it_instead.code, ]; registerCodeFix({ diff --git a/tests/baselines/reference/truthinessCallExpressionCoercion.errors.txt b/tests/baselines/reference/truthinessCallExpressionCoercion.errors.txt index 0e0b2c98404..132738e4ac1 100644 --- a/tests/baselines/reference/truthinessCallExpressionCoercion.errors.txt +++ b/tests/baselines/reference/truthinessCallExpressionCoercion.errors.txt @@ -1,17 +1,17 @@ -tests/cases/compiler/truthinessCallExpressionCoercion.ts(2,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion.ts(18,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion.ts(36,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion.ts(50,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion.ts(66,13): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion.ts(76,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(2,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(18,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(36,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(50,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(66,13): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(76,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? ==== tests/cases/compiler/truthinessCallExpressionCoercion.ts (7 errors) ==== function onlyErrorsWhenTestingNonNullableFunctionType(required: () => boolean, optional?: () => boolean) { if (required) { // error ~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } if (optional) { // ok @@ -29,7 +29,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: Th if (test) { // error ~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? console.log('test'); } @@ -49,7 +49,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: Th if (test) { // error ~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? [() => null].forEach(test => { test(); }); @@ -65,7 +65,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: Th if (x.foo.bar) { // error ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } if (x.foo.bar) { // ok @@ -83,7 +83,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: Th test() { if (this.isUser) { // error ~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } if (this.maybeIsUser) { // ok @@ -95,7 +95,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: Th function A(stats: StatsBase) { if (stats.isDirectory) { // err ~~~~~~~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? console.log(`[Directory] ${stats.ctime}`) } } @@ -103,7 +103,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion.ts(82,9): error TS2774: Th function B(a: Nested, b: Nested) { if (a.stats.isDirectory) { // err ~~~~~~~~~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? b.stats.isDirectory(); } if (a.stats.isDirectory) { // ok diff --git a/tests/baselines/reference/truthinessCallExpressionCoercion1.errors.txt b/tests/baselines/reference/truthinessCallExpressionCoercion1.errors.txt index ed7ba0a5709..4c041935cde 100644 --- a/tests/baselines/reference/truthinessCallExpressionCoercion1.errors.txt +++ b/tests/baselines/reference/truthinessCallExpressionCoercion1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/truthinessCallExpressionCoercion1.ts(3,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion1.ts(19,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion1.ts(33,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion1.ts(46,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion1.ts(3,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion1.ts(19,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion1.ts(33,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion1.ts(46,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? ==== tests/cases/compiler/truthinessCallExpressionCoercion1.ts (5 errors) ==== @@ -10,7 +10,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: T // error required ? console.log('required') : undefined; ~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok optional ? console.log('optional') : undefined; @@ -28,7 +28,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: T // error test ? console.log('test') : undefined; ~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok test ? console.log(test) : undefined; @@ -44,7 +44,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: T // error test ~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? ? [() => null].forEach(test => { test() }) : undefined; } @@ -59,7 +59,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: T // error x.foo.bar ? console.log('x.foo.bar') : undefined; ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok x.foo.bar ? x.foo.bar : undefined; @@ -91,7 +91,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion1.ts(76,9): error TS2774: T // error this.isUser ? console.log('this.isUser') : undefined; ~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok this.maybeIsUser ? console.log('this.maybeIsUser') : undefined; diff --git a/tests/baselines/reference/truthinessCallExpressionCoercion2.errors.txt b/tests/baselines/reference/truthinessCallExpressionCoercion2.errors.txt index 6582157de84..d744718a8de 100644 --- a/tests/baselines/reference/truthinessCallExpressionCoercion2.errors.txt +++ b/tests/baselines/reference/truthinessCallExpressionCoercion2.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(11,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(14,10): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(41,18): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(44,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(48,11): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(65,46): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(76,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(79,10): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(99,5): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(109,9): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? -tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(11,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(14,10): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(41,18): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(44,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(48,11): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(65,46): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(76,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(79,10): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(99,5): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(109,9): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? +tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? ==== tests/cases/compiler/truthinessCallExpressionCoercion2.ts (11 errors) ==== @@ -24,12 +24,12 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: // error required1 && console.log('required'); ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // error 1 && required1 && console.log('required'); ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok required1 && required1(); @@ -58,18 +58,18 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: // error required1 && required2 && required1() && console.log('foo'); ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // error if (required1 && b) { ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } // error if (((required1 && b))) { ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } // ok @@ -88,7 +88,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: typeof window !== 'undefined' && window.console && ((window.console as any).firebug || (window.console.exception && window.console.table)); ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } function checksPropertyAccess() { @@ -101,12 +101,12 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: // error x.foo.bar && console.log('x.foo.bar'); ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // error 1 && x.foo.bar && console.log('x.foo.bar'); ~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok x.foo.bar && x.foo.bar(); @@ -128,7 +128,7 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: // error x1.a.b.c && x2.a.b.c(); ~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? } class Foo { @@ -140,12 +140,12 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: // error this.required && console.log('required'); ~~~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // error 1 && this.required && console.log('required'); ~~~~~~~~~~~~~ -!!! error TS2774: This condition will always return true since the function is always defined. Did you mean to call it instead? +!!! error TS2774: This condition will always return true since this function appears to always be defined. Did you mean to call it instead? // ok this.required && this.required(); diff --git a/tests/baselines/reference/truthinessPromiseCoercion.errors.txt b/tests/baselines/reference/truthinessPromiseCoercion.errors.txt index a7b7afff1f6..aaba8031475 100644 --- a/tests/baselines/reference/truthinessPromiseCoercion.errors.txt +++ b/tests/baselines/reference/truthinessPromiseCoercion.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/truthinessPromiseCoercion.ts(5,9): error TS2367: This condition will always return 'true' since the types 'Promise' and 'false' have no overlap. -tests/cases/compiler/truthinessPromiseCoercion.ts(9,5): error TS2367: This condition will always return 'true' since the types 'Promise' and 'false' have no overlap. +tests/cases/compiler/truthinessPromiseCoercion.ts(5,9): error TS2801: This condition will always return true since this 'Promise' appears to always be defined. +tests/cases/compiler/truthinessPromiseCoercion.ts(9,5): error TS2801: This condition will always return true since this 'Promise' appears to always be defined. ==== tests/cases/compiler/truthinessPromiseCoercion.ts (2 errors) ==== @@ -9,14 +9,14 @@ tests/cases/compiler/truthinessPromiseCoercion.ts(9,5): error TS2367: This condi async function f() { if (p) {} // err ~ -!!! error TS2367: This condition will always return 'true' since the types 'Promise' and 'false' have no overlap. +!!! error TS2801: This condition will always return true since this 'Promise' appears to always be defined. !!! related TS2773 tests/cases/compiler/truthinessPromiseCoercion.ts:5:9: Did you forget to use 'await'? if (!!p) {} // no err if (p2) {} // no err p ? f.arguments : f.arguments; ~ -!!! error TS2367: This condition will always return 'true' since the types 'Promise' and 'false' have no overlap. +!!! error TS2801: This condition will always return true since this 'Promise' appears to always be defined. !!! related TS2773 tests/cases/compiler/truthinessPromiseCoercion.ts:9:5: Did you forget to use 'await'? !!p ? f.arguments : f.arguments; p2 ? f.arguments : f.arguments; From c34b252e1e0da144ba907b2375901bd54024abb5 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 26 Mar 2021 20:25:11 -0400 Subject: [PATCH 04/16] Fix length of `JSDocTypedefTag` (Accidentally broken in dcc27eb.) Fixes #43394 and microsoft/tsserverfuzzer#309. --- src/compiler/parser.ts | 2 +- ...arationsParameterTagReusesInputNodeInEmit1.errors.txt | 2 +- tests/baselines/reference/jsDocSignature-43394.baseline | 9 +++++++++ tests/cases/fourslash/findAllRefsJsDocTypeDef_js.ts | 2 +- tests/cases/fourslash/findAllRefsTypedef_importType.ts | 2 +- tests/cases/fourslash/jsDocSignature-43394.ts | 9 +++++++++ tests/cases/fourslash/jsdocTypedefTagSemanticMeaning0.ts | 2 +- tests/cases/fourslash/server/jsdocTypedefTagRename02.ts | 2 +- 8 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/jsDocSignature-43394.baseline create mode 100644 tests/cases/fourslash/jsDocSignature-43394.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 92d6848d8a9..244c7d44b5c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -8011,7 +8011,7 @@ namespace ts { } const typedefTag = factory.createJSDocTypedefTag(tagName, typeExpression, fullName, comment); - return finishNode(typedefTag, start); + return finishNode(typedefTag, start, end); } function parseJSDocTypeNameWithNamespace(nested?: boolean) { diff --git a/tests/baselines/reference/jsDeclarationsParameterTagReusesInputNodeInEmit1.errors.txt b/tests/baselines/reference/jsDeclarationsParameterTagReusesInputNodeInEmit1.errors.txt index 6d2f34fcc58..4a258fc96bd 100644 --- a/tests/baselines/reference/jsDeclarationsParameterTagReusesInputNodeInEmit1.errors.txt +++ b/tests/baselines/reference/jsDeclarationsParameterTagReusesInputNodeInEmit1.errors.txt @@ -18,7 +18,7 @@ tests/cases/conformance/jsdoc/declarations/file.js(6,5): error TS4084: Exported ==== tests/cases/conformance/jsdoc/declarations/file.js (3 errors) ==== /** @typedef {import('./base')} BaseFactory */ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS4084: Exported type alias 'BaseFactory' has or is using private name 'Base' from module "tests/cases/conformance/jsdoc/declarations/base". /** * @callback BaseFactoryFactory diff --git a/tests/baselines/reference/jsDocSignature-43394.baseline b/tests/baselines/reference/jsDocSignature-43394.baseline new file mode 100644 index 00000000000..905b7e8bccc --- /dev/null +++ b/tests/baselines/reference/jsDocSignature-43394.baseline @@ -0,0 +1,9 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/jsDocSignature-43394.ts", + "position": 58, + "name": "" + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsJsDocTypeDef_js.ts b/tests/cases/fourslash/findAllRefsJsDocTypeDef_js.ts index 844c2532775..fb3cdf5bc33 100644 --- a/tests/cases/fourslash/findAllRefsJsDocTypeDef_js.ts +++ b/tests/cases/fourslash/findAllRefsJsDocTypeDef_js.ts @@ -5,7 +5,7 @@ // @allowJs: true // @Filename: /a.js -/////** [|@typedef {number} [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}T|] |]*/ +/////** [|@typedef {number} [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}T|]|] */ //// /////** //// * @return {[|T|]} diff --git a/tests/cases/fourslash/findAllRefsTypedef_importType.ts b/tests/cases/fourslash/findAllRefsTypedef_importType.ts index f84632d729d..4816406d518 100644 --- a/tests/cases/fourslash/findAllRefsTypedef_importType.ts +++ b/tests/cases/fourslash/findAllRefsTypedef_importType.ts @@ -4,7 +4,7 @@ // @Filename: /a.js ////module.exports = 0; -/////** [|@typedef {number} [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}Foo|] |]*/ +/////** [|@typedef {number} [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}Foo|]|] */ ////const dummy = 0; // @Filename: /b.js diff --git a/tests/cases/fourslash/jsDocSignature-43394.ts b/tests/cases/fourslash/jsDocSignature-43394.ts new file mode 100644 index 00000000000..3091c8e5a4b --- /dev/null +++ b/tests/cases/fourslash/jsDocSignature-43394.ts @@ -0,0 +1,9 @@ +/// + +/////** +//// * @typedef {Object} Foo +//// * @property {number} ... +//// * /**/@typedef {number} Bar +//// */ + +verify.baselineSignatureHelp(); diff --git a/tests/cases/fourslash/jsdocTypedefTagSemanticMeaning0.ts b/tests/cases/fourslash/jsdocTypedefTagSemanticMeaning0.ts index 4d4bb63058f..44156116d2f 100644 --- a/tests/cases/fourslash/jsdocTypedefTagSemanticMeaning0.ts +++ b/tests/cases/fourslash/jsdocTypedefTagSemanticMeaning0.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: a.js -/////** [|@typedef {number} [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}T|] |]*/ +/////** [|@typedef {number} [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}T|]|] */ ////[|const [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 2 |}T|] = 1;|] diff --git a/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts b/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts index 45bfd871aea..30c99deb0a8 100644 --- a/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts +++ b/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts @@ -3,7 +3,7 @@ // @allowNonTsExtensions: true // @Filename: jsDocTypedef_form2.js //// -//// /** [|@typedef {(string | number)} [|{| "contextRangeIndex": 0 |}NumberLike|] |]*/ +//// /** [|@typedef {(string | number)} [|{| "contextRangeIndex": 0 |}NumberLike|]|] */ //// //// /** @type {[|NumberLike|]} */ //// var numberLike; From 57775ed405c67118ac221e47420f7c67c5fbcf41 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 29 Mar 2021 20:20:25 -0400 Subject: [PATCH 05/16] Consider class field properties to redeclare parent definitions (#43194) --- src/compiler/checker.ts | 2 +- .../reference/redeclaredProperty.errors.txt | 21 ++++++++++++++ .../baselines/reference/redeclaredProperty.js | 28 +++++++++++++++++++ .../redefinedPararameterProperty.errors.txt | 19 +++++++++++++ .../reference/redefinedPararameterProperty.js | 26 +++++++++++++++++ .../redefinedPararameterProperty.symbols | 3 ++ .../redefinedPararameterProperty.types | 3 ++ .../redeclaredProperty.ts | 17 +++++++++++ .../redefinedPararameterProperty.ts | 16 +++++++++++ 9 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/redeclaredProperty.errors.txt create mode 100644 tests/baselines/reference/redeclaredProperty.js create mode 100644 tests/baselines/reference/redefinedPararameterProperty.errors.txt create mode 100644 tests/baselines/reference/redefinedPararameterProperty.js create mode 100644 tests/baselines/reference/redefinedPararameterProperty.symbols create mode 100644 tests/baselines/reference/redefinedPararameterProperty.types create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 387d9187e6c..3bf84010e9f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27119,7 +27119,7 @@ namespace ts { if (isInPropertyInitializer(node) && !(isAccessExpression(node) && isAccessExpression(node.expression)) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) - && !isPropertyDeclaredInAncestorClass(prop)) { + && (compilerOptions.useDefineForClassFields || !isPropertyDeclaredInAncestorClass(prop))) { diagnosticMessage = error(right, Diagnostics.Property_0_is_used_before_its_initialization, declarationName); } else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration && diff --git a/tests/baselines/reference/redeclaredProperty.errors.txt b/tests/baselines/reference/redeclaredProperty.errors.txt new file mode 100644 index 00000000000..331e5610f8d --- /dev/null +++ b/tests/baselines/reference/redeclaredProperty.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts(7,12): error TS2729: Property 'b' is used before its initialization. + + +==== tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts (1 errors) ==== + class Base { + b = 1; + } + + class Derived extends Base { + b; + d = this.b; + ~ +!!! error TS2729: Property 'b' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts:6:3: 'b' is declared here. + + constructor() { + super(); + this.b = 2; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/redeclaredProperty.js b/tests/baselines/reference/redeclaredProperty.js new file mode 100644 index 00000000000..20af007d62e --- /dev/null +++ b/tests/baselines/reference/redeclaredProperty.js @@ -0,0 +1,28 @@ +//// [redeclaredProperty.ts] +class Base { + b = 1; +} + +class Derived extends Base { + b; + d = this.b; + + constructor() { + super(); + this.b = 2; + } +} + + +//// [redeclaredProperty.js] +class Base { + b = 1; +} +class Derived extends Base { + b; + d = this.b; + constructor() { + super(); + this.b = 2; + } +} diff --git a/tests/baselines/reference/redefinedPararameterProperty.errors.txt b/tests/baselines/reference/redefinedPararameterProperty.errors.txt new file mode 100644 index 00000000000..65763261152 --- /dev/null +++ b/tests/baselines/reference/redefinedPararameterProperty.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts(6,14): error TS2729: Property 'a' is used before its initialization. + + +==== tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts (1 errors) ==== + class Base { + a = 1; + } + + class Derived extends Base { + b = this.a /*undefined*/; + ~ +!!! error TS2729: Property 'a' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts:8:17: 'a' is declared here. + + constructor(public a: number) { + super(); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/redefinedPararameterProperty.js b/tests/baselines/reference/redefinedPararameterProperty.js new file mode 100644 index 00000000000..8ad9b5facc0 --- /dev/null +++ b/tests/baselines/reference/redefinedPararameterProperty.js @@ -0,0 +1,26 @@ +//// [redefinedPararameterProperty.ts] +class Base { + a = 1; + } + + class Derived extends Base { + b = this.a /*undefined*/; + + constructor(public a: number) { + super(); + } + } + + +//// [redefinedPararameterProperty.js] +class Base { + a = 1; +} +class Derived extends Base { + a; + b = this.a /*undefined*/; + constructor(a) { + super(); + this.a = a; + } +} diff --git a/tests/baselines/reference/redefinedPararameterProperty.symbols b/tests/baselines/reference/redefinedPararameterProperty.symbols new file mode 100644 index 00000000000..5e05041f539 --- /dev/null +++ b/tests/baselines/reference/redefinedPararameterProperty.symbols @@ -0,0 +1,3 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts === + +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/redefinedPararameterProperty.types b/tests/baselines/reference/redefinedPararameterProperty.types new file mode 100644 index 00000000000..5e05041f539 --- /dev/null +++ b/tests/baselines/reference/redefinedPararameterProperty.types @@ -0,0 +1,3 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts === + +No type information for this code. \ No newline at end of file diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts new file mode 100644 index 00000000000..4080146e028 --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/redeclaredProperty.ts @@ -0,0 +1,17 @@ +// @noTypesAndSymbols: true +// @strictNullChecks: true +// @target: esnext +// @useDefineForClassFields: true +class Base { + b = 1; +} + +class Derived extends Base { + b; + d = this.b; + + constructor() { + super(); + this.b = 2; + } +} diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts new file mode 100644 index 00000000000..02eabfbfcfa --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/redefinedPararameterProperty.ts @@ -0,0 +1,16 @@ +// @noTypesAndSymbols: true +// @strictNullChecks: true +// @target: esnext +// @useDefineForClassFields: true +class Base { + a = 1; + } + + class Derived extends Base { + b = this.a /*undefined*/; + + constructor(public a: number) { + super(); + } + } + \ No newline at end of file From 6fd676b8efdd21563af653667240efa35dc2915c Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 30 Mar 2021 03:22:41 +0300 Subject: [PATCH 06/16] fix(43215): disallow using never as an interface name (#43217) --- src/compiler/checker.ts | 1 + .../interfacesWithPredefinedTypesAsNames.errors.txt | 12 ++++++++++-- .../interfacesWithPredefinedTypesAsNames.js | 4 +++- .../interfacesWithPredefinedTypesAsNames.symbols | 6 ++++++ .../interfacesWithPredefinedTypesAsNames.types | 2 ++ .../interfacesWithPredefinedTypesAsNames.ts | 4 +++- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3bf84010e9f..c6a9f7e75a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36566,6 +36566,7 @@ namespace ts { switch (name.escapedText) { case "any": case "unknown": + case "never": case "number": case "bigint": case "boolean": diff --git a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.errors.txt b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.errors.txt index 1925079095a..d6ad166fb0f 100644 --- a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.errors.txt +++ b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.errors.txt @@ -4,9 +4,11 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefine tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts(4,11): error TS2427: Interface name cannot be 'boolean'. tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts(5,1): error TS2304: Cannot find name 'interface'. tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts(5,11): error TS1005: ';' expected. +tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts(6,11): error TS2427: Interface name cannot be 'unknown'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts(7,11): error TS2427: Interface name cannot be 'never'. -==== tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts (6 errors) ==== +==== tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts (8 errors) ==== interface any { } ~~~ !!! error TS2427: Interface name cannot be 'any'. @@ -23,4 +25,10 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefine ~~~~~~~~~ !!! error TS2304: Cannot find name 'interface'. ~~~~ -!!! error TS1005: ';' expected. \ No newline at end of file +!!! error TS1005: ';' expected. + interface unknown {} + ~~~~~~~ +!!! error TS2427: Interface name cannot be 'unknown'. + interface never {} + ~~~~~ +!!! error TS2427: Interface name cannot be 'never'. \ No newline at end of file diff --git a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.js b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.js index ca186b1cef1..2bb4f0be112 100644 --- a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.js +++ b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.js @@ -3,7 +3,9 @@ interface any { } interface number { } interface string { } interface boolean { } -interface void {} +interface void {} +interface unknown {} +interface never {} //// [interfacesWithPredefinedTypesAsNames.js] interface; diff --git a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.symbols b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.symbols index f469eaba590..c79493530ea 100644 --- a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.symbols +++ b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.symbols @@ -12,3 +12,9 @@ interface boolean { } >boolean : Symbol(boolean, Decl(interfacesWithPredefinedTypesAsNames.ts, 2, 20)) interface void {} +interface unknown {} +>unknown : Symbol(unknown, Decl(interfacesWithPredefinedTypesAsNames.ts, 4, 17)) + +interface never {} +>never : Symbol(never, Decl(interfacesWithPredefinedTypesAsNames.ts, 5, 20)) + diff --git a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.types b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.types index 9d6b22cfa48..492facdc845 100644 --- a/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.types +++ b/tests/baselines/reference/interfacesWithPredefinedTypesAsNames.types @@ -8,3 +8,5 @@ interface void {} >void {} : undefined >{} : {} +interface unknown {} +interface never {} diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts index 56bbaa62e36..edd53d2cdfc 100644 --- a/tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfacesWithPredefinedTypesAsNames.ts @@ -2,4 +2,6 @@ interface any { } interface number { } interface string { } interface boolean { } -interface void {} \ No newline at end of file +interface void {} +interface unknown {} +interface never {} \ No newline at end of file From 294a5a7d784a5a95a8048ee990400979a6bc3a1c Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 29 Mar 2021 21:30:45 -0700 Subject: [PATCH 07/16] Remote duplicated assignment (#43399) --- src/harness/compilerImpl.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/harness/compilerImpl.ts b/src/harness/compilerImpl.ts index 0d24ee4797f..badab5c6cbc 100644 --- a/src/harness/compilerImpl.ts +++ b/src/harness/compilerImpl.ts @@ -135,8 +135,6 @@ namespace compiler { } } } - - this.diagnostics = diagnostics; } public get vfs(): vfs.FileSystem { From 555ef73da88a9316a5769b9329eb01f7ac0fc92b Mon Sep 17 00:00:00 2001 From: keerthana1212 Date: Tue, 30 Mar 2021 13:13:57 -0700 Subject: [PATCH 08/16] Adding Diagnostic message for missing ']' and ')' in Array literal and conditional statements (#40884) * Adding Diagnostic message for missing ']' in Array literal * revert change on parseArrayBindingPattern * Adding diagnostic message for if, while, do and with statements * Extract parseExpectMatchingBrackets Co-authored-by: Keerthana Kanakaraju Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> --- src/compiler/diagnosticMessages.json | 2 +- src/compiler/parser.ts | 41 +++++++----- ...torWithIncompleteTypeAnnotation.errors.txt | 2 + ...tructuringParameterDeclaration2.errors.txt | 1 + .../missingCloseBracketInArray.errors.txt | 8 +++ .../reference/missingCloseBracketInArray.js | 5 ++ .../missingCloseBracketInArray.symbols | 5 ++ .../missingCloseBracketInArray.types | 11 +++ .../missingCloseParenStatements.errors.txt | 32 +++++++++ .../reference/missingCloseParenStatements.js | 28 ++++++++ .../missingCloseParenStatements.symbols | 37 ++++++++++ .../missingCloseParenStatements.types | 67 +++++++++++++++++++ ...RecoveryArrayLiteralExpression3.errors.txt | 1 + ...parserErrorRecoveryIfStatement2.errors.txt | 1 + ...parserErrorRecoveryIfStatement3.errors.txt | 1 + .../reference/reservedWords2.errors.txt | 3 + .../reference/typeAssertions.errors.txt | 2 + .../compiler/missingCloseBracketInArray.ts | 1 + .../compiler/missingCloseParenStatements.ts | 13 ++++ ...serErrorRecoveryArrayLiteralExpression3.ts | 1 - 20 files changed, 245 insertions(+), 17 deletions(-) create mode 100644 tests/baselines/reference/missingCloseBracketInArray.errors.txt create mode 100644 tests/baselines/reference/missingCloseBracketInArray.js create mode 100644 tests/baselines/reference/missingCloseBracketInArray.symbols create mode 100644 tests/baselines/reference/missingCloseBracketInArray.types create mode 100644 tests/baselines/reference/missingCloseParenStatements.errors.txt create mode 100644 tests/baselines/reference/missingCloseParenStatements.js create mode 100644 tests/baselines/reference/missingCloseParenStatements.symbols create mode 100644 tests/baselines/reference/missingCloseParenStatements.types create mode 100644 tests/cases/compiler/missingCloseBracketInArray.ts create mode 100644 tests/cases/compiler/missingCloseParenStatements.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 33e528fa6d9..9a275dd586b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -15,7 +15,7 @@ "category": "Error", "code": 1006 }, - "The parser expected to find a '}' to match the '{' token here.": { + "The parser expected to find a '{1}' to match the '{0}' token here.": { "category": "Error", "code": 1007 }, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 244c7d44b5c..de0bb9c4022 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1542,6 +1542,20 @@ namespace ts { return false; } + function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openPosition: number) { + if (!parseExpected(closeKind)) { + const lastError = lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === Diagnostics._0_expected.code) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind)) + ); + } + return false; + } + return true; + } + function parseOptional(t: SyntaxKind): boolean { if (token() === t) { nextToken(); @@ -5426,10 +5440,11 @@ namespace ts { function parseArrayLiteralExpression(): ArrayLiteralExpression { const pos = getNodePos(); + const openBracketPosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenBracketToken); const multiLine = scanner.hasPrecedingLineBreak(); const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); - parseExpected(SyntaxKind.CloseBracketToken); + parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketPosition); return finishNode(factory.createArrayLiteralExpression(elements, multiLine), pos); } @@ -5503,7 +5518,7 @@ namespace ts { if (lastError && lastError.code === Diagnostics._0_expected.code) { addRelatedInfo( lastError, - createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) + createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(SyntaxKind.OpenBraceToken), tokenToString(SyntaxKind.CloseBraceToken)) ); } } @@ -5591,15 +5606,7 @@ namespace ts { if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) { const multiLine = scanner.hasPrecedingLineBreak(); const statements = parseList(ParsingContext.BlockStatements, parseStatement); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) - ); - } - } + parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition); return finishNode(factory.createBlock(statements, multiLine), pos); } else { @@ -5647,9 +5654,10 @@ namespace ts { function parseIfStatement(): IfStatement { const pos = getNodePos(); parseExpected(SyntaxKind.IfKeyword); + const openParenPosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); const thenStatement = parseStatement(); const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; return finishNode(factory.createIfStatement(expression, thenStatement, elseStatement), pos); @@ -5660,9 +5668,10 @@ namespace ts { parseExpected(SyntaxKind.DoKeyword); const statement = parseStatement(); parseExpected(SyntaxKind.WhileKeyword); + const openParenPosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in @@ -5675,9 +5684,10 @@ namespace ts { function parseWhileStatement(): WhileStatement { const pos = getNodePos(); parseExpected(SyntaxKind.WhileKeyword); + const openParenPosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); const statement = parseStatement(); return finishNode(factory.createWhileStatement(expression, statement), pos); } @@ -5749,9 +5759,10 @@ namespace ts { function parseWithStatement(): WithStatement { const pos = getNodePos(); parseExpected(SyntaxKind.WithKeyword); + const openParenPosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenPosition); const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); return finishNode(factory.createWithStatement(expression, statement), pos); } diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt index c8af0683007..9a3e9d81368 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt @@ -121,6 +121,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS if (retValue != 0 ^= { ~~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:22:20: The parser expected to find a ')' to match the '(' token here. ~ @@ -504,6 +505,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS !!! error TS1135: Argument expression expected. ~ !!! error TS1005: '(' expected. +!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:257:33: The parser expected to find a ')' to match the '(' token here. ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. ~~~ diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index c1c79a2300d..02dde837f35 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -39,6 +39,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( !!! error TS2322: Type 'string' is not assignable to type 'number'. ~ !!! error TS1005: ',' expected. +!!! related TS1007 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:7:4: The parser expected to find a ']' to match the '[' token here. a0([1, 2, [["world"]], "string"]); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. diff --git a/tests/baselines/reference/missingCloseBracketInArray.errors.txt b/tests/baselines/reference/missingCloseBracketInArray.errors.txt new file mode 100644 index 00000000000..26801c02812 --- /dev/null +++ b/tests/baselines/reference/missingCloseBracketInArray.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/missingCloseBracketInArray.ts(1,48): error TS1005: ']' expected. + + +==== tests/cases/compiler/missingCloseBracketInArray.ts (1 errors) ==== + var alphas:string[] = alphas = ["1","2","3","4" + +!!! error TS1005: ']' expected. +!!! related TS1007 tests/cases/compiler/missingCloseBracketInArray.ts:1:32: The parser expected to find a ']' to match the '[' token here. \ No newline at end of file diff --git a/tests/baselines/reference/missingCloseBracketInArray.js b/tests/baselines/reference/missingCloseBracketInArray.js new file mode 100644 index 00000000000..cb842d1cc74 --- /dev/null +++ b/tests/baselines/reference/missingCloseBracketInArray.js @@ -0,0 +1,5 @@ +//// [missingCloseBracketInArray.ts] +var alphas:string[] = alphas = ["1","2","3","4" + +//// [missingCloseBracketInArray.js] +var alphas = alphas = ["1", "2", "3", "4"]; diff --git a/tests/baselines/reference/missingCloseBracketInArray.symbols b/tests/baselines/reference/missingCloseBracketInArray.symbols new file mode 100644 index 00000000000..4d28f8945fd --- /dev/null +++ b/tests/baselines/reference/missingCloseBracketInArray.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/missingCloseBracketInArray.ts === +var alphas:string[] = alphas = ["1","2","3","4" +>alphas : Symbol(alphas, Decl(missingCloseBracketInArray.ts, 0, 3)) +>alphas : Symbol(alphas, Decl(missingCloseBracketInArray.ts, 0, 3)) + diff --git a/tests/baselines/reference/missingCloseBracketInArray.types b/tests/baselines/reference/missingCloseBracketInArray.types new file mode 100644 index 00000000000..557a865827c --- /dev/null +++ b/tests/baselines/reference/missingCloseBracketInArray.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/missingCloseBracketInArray.ts === +var alphas:string[] = alphas = ["1","2","3","4" +>alphas : string[] +>alphas = ["1","2","3","4" : string[] +>alphas : string[] +>["1","2","3","4" : string[] +>"1" : "1" +>"2" : "2" +>"3" : "3" +>"4" : "4" + diff --git a/tests/baselines/reference/missingCloseParenStatements.errors.txt b/tests/baselines/reference/missingCloseParenStatements.errors.txt new file mode 100644 index 00000000000..3f49d5a0366 --- /dev/null +++ b/tests/baselines/reference/missingCloseParenStatements.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/missingCloseParenStatements.ts(2,26): error TS1005: ')' expected. +tests/cases/compiler/missingCloseParenStatements.ts(4,5): error TS1005: ')' expected. +tests/cases/compiler/missingCloseParenStatements.ts(8,39): error TS1005: ')' expected. +tests/cases/compiler/missingCloseParenStatements.ts(11,35): error TS1005: ')' expected. + + +==== tests/cases/compiler/missingCloseParenStatements.ts (4 errors) ==== + var a1, a2, a3 = 0; + if ( a1 && (a2 + a3 > 0) { + ~ +!!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:2:4: The parser expected to find a ')' to match the '(' token here. + while( (a2 > 0) && a1 + { + ~ +!!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:3:10: The parser expected to find a ')' to match the '(' token here. + do { + var i = i + 1; + a1 = a1 + i; + with ((a2 + a3 > 0) && a1 { + ~ +!!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:8:18: The parser expected to find a ')' to match the '(' token here. + console.log(x); + } + } while (i < 5 && (a1 > 5); + ~ +!!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/missingCloseParenStatements.ts:11:17: The parser expected to find a ')' to match the '(' token here. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/missingCloseParenStatements.js b/tests/baselines/reference/missingCloseParenStatements.js new file mode 100644 index 00000000000..8ba56b6b881 --- /dev/null +++ b/tests/baselines/reference/missingCloseParenStatements.js @@ -0,0 +1,28 @@ +//// [missingCloseParenStatements.ts] +var a1, a2, a3 = 0; +if ( a1 && (a2 + a3 > 0) { + while( (a2 > 0) && a1 + { + do { + var i = i + 1; + a1 = a1 + i; + with ((a2 + a3 > 0) && a1 { + console.log(x); + } + } while (i < 5 && (a1 > 5); + } +} + +//// [missingCloseParenStatements.js] +var a1, a2, a3 = 0; +if (a1 && (a2 + a3 > 0)) { + while ((a2 > 0) && a1) { + do { + var i = i + 1; + a1 = a1 + i; + with ((a2 + a3 > 0) && a1) { + console.log(x); + } + } while (i < 5 && (a1 > 5)); + } +} diff --git a/tests/baselines/reference/missingCloseParenStatements.symbols b/tests/baselines/reference/missingCloseParenStatements.symbols new file mode 100644 index 00000000000..e403570f8e8 --- /dev/null +++ b/tests/baselines/reference/missingCloseParenStatements.symbols @@ -0,0 +1,37 @@ +=== tests/cases/compiler/missingCloseParenStatements.ts === +var a1, a2, a3 = 0; +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) +>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7)) +>a3 : Symbol(a3, Decl(missingCloseParenStatements.ts, 0, 11)) + +if ( a1 && (a2 + a3 > 0) { +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) +>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7)) +>a3 : Symbol(a3, Decl(missingCloseParenStatements.ts, 0, 11)) + + while( (a2 > 0) && a1 +>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7)) +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) + { + do { + var i = i + 1; +>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15)) +>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15)) + + a1 = a1 + i; +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) +>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15)) + + with ((a2 + a3 > 0) && a1 { +>a2 : Symbol(a2, Decl(missingCloseParenStatements.ts, 0, 7)) +>a3 : Symbol(a3, Decl(missingCloseParenStatements.ts, 0, 11)) +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) + + console.log(x); + } + } while (i < 5 && (a1 > 5); +>i : Symbol(i, Decl(missingCloseParenStatements.ts, 5, 15)) +>a1 : Symbol(a1, Decl(missingCloseParenStatements.ts, 0, 3)) + } +} diff --git a/tests/baselines/reference/missingCloseParenStatements.types b/tests/baselines/reference/missingCloseParenStatements.types new file mode 100644 index 00000000000..0d1b7469f60 --- /dev/null +++ b/tests/baselines/reference/missingCloseParenStatements.types @@ -0,0 +1,67 @@ +=== tests/cases/compiler/missingCloseParenStatements.ts === +var a1, a2, a3 = 0; +>a1 : any +>a2 : any +>a3 : number +>0 : 0 + +if ( a1 && (a2 + a3 > 0) { +>a1 && (a2 + a3 > 0) : boolean +>a1 : any +>(a2 + a3 > 0) : boolean +>a2 + a3 > 0 : boolean +>a2 + a3 : any +>a2 : any +>a3 : number +>0 : 0 + + while( (a2 > 0) && a1 +>(a2 > 0) && a1 : any +>(a2 > 0) : boolean +>a2 > 0 : boolean +>a2 : any +>0 : 0 +>a1 : any + { + do { + var i = i + 1; +>i : any +>i + 1 : any +>i : any +>1 : 1 + + a1 = a1 + i; +>a1 = a1 + i : any +>a1 : any +>a1 + i : any +>a1 : any +>i : any + + with ((a2 + a3 > 0) && a1 { +>(a2 + a3 > 0) && a1 : any +>(a2 + a3 > 0) : boolean +>a2 + a3 > 0 : boolean +>a2 + a3 : any +>a2 : any +>a3 : number +>0 : 0 +>a1 : any + + console.log(x); +>console.log(x) : any +>console.log : any +>console : any +>log : any +>x : any + } + } while (i < 5 && (a1 > 5); +>i < 5 && (a1 > 5) : boolean +>i < 5 : boolean +>i : any +>5 : 5 +>(a1 > 5) : boolean +>a1 > 5 : boolean +>a1 : any +>5 : 5 + } +} diff --git a/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt b/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt index eb32618af4b..9de5aa8014c 100644 --- a/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt +++ b/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt @@ -8,6 +8,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions var texCoords = [2, 2, 0.5000001192092895, 0.8749999 ; 403953552, 0.5000001192092895, 0.8749999403953552]; ~ !!! error TS1005: ',' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts:1:17: The parser expected to find a ']' to match the '[' token here. ~~~~~~~~~ !!! error TS2695: Left side of comma operator is unused and has no side effects. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/parserErrorRecoveryIfStatement2.errors.txt b/tests/baselines/reference/parserErrorRecoveryIfStatement2.errors.txt index 45dd9935a62..b88c48182a2 100644 --- a/tests/baselines/reference/parserErrorRecoveryIfStatement2.errors.txt +++ b/tests/baselines/reference/parserErrorRecoveryIfStatement2.errors.txt @@ -11,6 +11,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErro } ~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErrorRecoveryIfStatement2.ts:3:8: The parser expected to find a ')' to match the '(' token here. f2() { } f3() { diff --git a/tests/baselines/reference/parserErrorRecoveryIfStatement3.errors.txt b/tests/baselines/reference/parserErrorRecoveryIfStatement3.errors.txt index 631cdb08a90..cfd645e5925 100644 --- a/tests/baselines/reference/parserErrorRecoveryIfStatement3.errors.txt +++ b/tests/baselines/reference/parserErrorRecoveryIfStatement3.errors.txt @@ -11,6 +11,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErro } ~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/IfStatements/parserErrorRecoveryIfStatement3.ts:3:8: The parser expected to find a ')' to match the '(' token here. f2() { } f3() { diff --git a/tests/baselines/reference/reservedWords2.errors.txt b/tests/baselines/reference/reservedWords2.errors.txt index 599010b4368..7c078493e8d 100644 --- a/tests/baselines/reference/reservedWords2.errors.txt +++ b/tests/baselines/reference/reservedWords2.errors.txt @@ -45,6 +45,7 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`. ~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/reservedWords2.ts:1:14: The parser expected to find a ')' to match the '(' token here. import * as while from "foo" !!! error TS2300: Duplicate identifier '(Missing)'. @@ -58,6 +59,7 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS2304: Cannot find name 'from'. ~~~~~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/compiler/reservedWords2.ts:2:20: The parser expected to find a ')' to match the '(' token here. var typeof = 10; ~~~~~~ @@ -103,6 +105,7 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS1005: ';' expected. ~ !!! error TS1005: '(' expected. +!!! related TS1007 tests/cases/compiler/reservedWords2.ts:9:18: The parser expected to find a ')' to match the '(' token here. ~ !!! error TS1128: Declaration or statement expected. enum void {} diff --git a/tests/baselines/reference/typeAssertions.errors.txt b/tests/baselines/reference/typeAssertions.errors.txt index 9d10ec17fe9..cf132a12d02 100644 --- a/tests/baselines/reference/typeAssertions.errors.txt +++ b/tests/baselines/reference/typeAssertions.errors.txt @@ -93,6 +93,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): err !!! error TS2304: Cannot find name 'is'. ~~~~~~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts:44:3: The parser expected to find a ')' to match the '(' token here. ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. ~ @@ -108,6 +109,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): err !!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. Did you mean 'typeof numOrStr'? ~~ !!! error TS1005: ')' expected. +!!! related TS1007 tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts:48:3: The parser expected to find a ')' to match the '(' token here. ~~ !!! error TS2304: Cannot find name 'is'. ~~~~~~ diff --git a/tests/cases/compiler/missingCloseBracketInArray.ts b/tests/cases/compiler/missingCloseBracketInArray.ts new file mode 100644 index 00000000000..cb99f0d2277 --- /dev/null +++ b/tests/cases/compiler/missingCloseBracketInArray.ts @@ -0,0 +1 @@ +var alphas:string[] = alphas = ["1","2","3","4" \ No newline at end of file diff --git a/tests/cases/compiler/missingCloseParenStatements.ts b/tests/cases/compiler/missingCloseParenStatements.ts new file mode 100644 index 00000000000..7ff34bdae6a --- /dev/null +++ b/tests/cases/compiler/missingCloseParenStatements.ts @@ -0,0 +1,13 @@ +var a1, a2, a3 = 0; +if ( a1 && (a2 + a3 > 0) { + while( (a2 > 0) && a1 + { + do { + var i = i + 1; + a1 = a1 + i; + with ((a2 + a3 > 0) && a1 { + console.log(x); + } + } while (i < 5 && (a1 > 5); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts index 58df0691d8e..18ed3b5ef5a 100644 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts +++ b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts @@ -1,2 +1 @@ - var texCoords = [2, 2, 0.5000001192092895, 0.8749999 ; 403953552, 0.5000001192092895, 0.8749999403953552]; From b549467368b5f3f794278c29162f6c1967d131dc Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 30 Mar 2021 13:18:38 -0700 Subject: [PATCH 09/16] Consider base types in isArrayLikeType (#43435) * Types that extend Array or ReadonlyArray are automatically array-like * Add React repro to test --- src/compiler/checker.ts | 8 +- .../excessiveStackDepthFlatArray.errors.txt | 48 +++++++ .../reference/excessiveStackDepthFlatArray.js | 58 ++++++++ .../excessiveStackDepthFlatArray.symbols | 128 ++++++++++++++++++ .../excessiveStackDepthFlatArray.types | 108 +++++++++++++++ .../compiler/excessiveStackDepthFlatArray.ts | 43 ++++++ 6 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.js create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.symbols create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.types create mode 100644 tests/cases/compiler/excessiveStackDepthFlatArray.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6a9f7e75a6..abd441ca76b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19789,7 +19789,13 @@ namespace ts { function isArrayLikeType(type: Type): boolean { // A type is array-like if it is a reference to the global Array or global ReadonlyArray type, // or if it is not the undefined or null type and if it is assignable to ReadonlyArray - return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); + return isArrayType(type) || hasArrayOrReadonlyArrayBaseType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); + } + + function hasArrayOrReadonlyArrayBaseType(type: Type): boolean { + return !!(getObjectFlags(type) & ObjectFlags.Reference) + && !!(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface) + && some(getBaseTypes((type as TypeReference).target as InterfaceType), isArrayType); } function isEmptyArrayLiteralType(type: Type): boolean { diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt b/tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt new file mode 100644 index 00000000000..825a402ca02 --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt @@ -0,0 +1,48 @@ +tests/cases/compiler/index.tsx(35,13): error TS2322: Type '{ key: string; }' is not assignable to type 'HTMLAttributes'. + Property 'key' does not exist on type 'HTMLAttributes'. + + +==== tests/cases/compiler/index.tsx (1 errors) ==== + interface MiddlewareArray extends Array {} + declare function configureStore(options: { middleware: MiddlewareArray }): void; + + declare const defaultMiddleware: MiddlewareArray; + configureStore({ + middleware: [...defaultMiddleware], // Should not error + }); + + declare namespace React { + type DetailedHTMLProps, T> = E; + interface HTMLAttributes { + children?: ReactNode; + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactText = string | number; + type ReactChild = ReactText; + type ReactFragment = {} | ReactNodeArray; + interface ReactNodeArray extends Array {} + } + declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; + li: React.DetailedHTMLProps, HTMLLIElement>; + } + } + declare var React: any; + + const Component = () => { + const categories = ['Fruit', 'Vegetables']; + + return ( +
    +
  • All
  • + {categories.map((category) => ( +
  • {category}
  • // Error about 'key' only + ~~~ +!!! error TS2322: Type '{ key: string; }' is not assignable to type 'HTMLAttributes'. +!!! error TS2322: Property 'key' does not exist on type 'HTMLAttributes'. + ))} +
+ ); + }; + \ No newline at end of file diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.js b/tests/baselines/reference/excessiveStackDepthFlatArray.js new file mode 100644 index 00000000000..4578612b4a6 --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.js @@ -0,0 +1,58 @@ +//// [index.tsx] +interface MiddlewareArray extends Array {} +declare function configureStore(options: { middleware: MiddlewareArray }): void; + +declare const defaultMiddleware: MiddlewareArray; +configureStore({ + middleware: [...defaultMiddleware], // Should not error +}); + +declare namespace React { + type DetailedHTMLProps, T> = E; + interface HTMLAttributes { + children?: ReactNode; + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactText = string | number; + type ReactChild = ReactText; + type ReactFragment = {} | ReactNodeArray; + interface ReactNodeArray extends Array {} +} +declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; + li: React.DetailedHTMLProps, HTMLLIElement>; + } +} +declare var React: any; + +const Component = () => { + const categories = ['Fruit', 'Vegetables']; + + return ( +
    +
  • All
  • + {categories.map((category) => ( +
  • {category}
  • // Error about 'key' only + ))} +
+ ); +}; + + +//// [index.js] +var __spreadArray = (this && this.__spreadArray) || function (to, from) { + for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) + to[j] = from[i]; + return to; +}; +configureStore({ + middleware: __spreadArray([], defaultMiddleware) +}); +var Component = function () { + var categories = ['Fruit', 'Vegetables']; + return (React.createElement("ul", null, + React.createElement("li", null, "All"), + categories.map(function (category) { return (React.createElement("li", { key: category }, category) // Error about 'key' only + ); }))); +}; diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.symbols b/tests/baselines/reference/excessiveStackDepthFlatArray.symbols new file mode 100644 index 00000000000..08fe546e6da --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.symbols @@ -0,0 +1,128 @@ +=== tests/cases/compiler/index.tsx === +interface MiddlewareArray extends Array {} +>MiddlewareArray : Symbol(MiddlewareArray, Decl(index.tsx, 0, 0)) +>T : Symbol(T, Decl(index.tsx, 0, 26)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>T : Symbol(T, Decl(index.tsx, 0, 26)) + +declare function configureStore(options: { middleware: MiddlewareArray }): void; +>configureStore : Symbol(configureStore, Decl(index.tsx, 0, 48)) +>options : Symbol(options, Decl(index.tsx, 1, 32)) +>middleware : Symbol(middleware, Decl(index.tsx, 1, 42)) +>MiddlewareArray : Symbol(MiddlewareArray, Decl(index.tsx, 0, 0)) + +declare const defaultMiddleware: MiddlewareArray; +>defaultMiddleware : Symbol(defaultMiddleware, Decl(index.tsx, 3, 13)) +>MiddlewareArray : Symbol(MiddlewareArray, Decl(index.tsx, 0, 0)) + +configureStore({ +>configureStore : Symbol(configureStore, Decl(index.tsx, 0, 48)) + + middleware: [...defaultMiddleware], // Should not error +>middleware : Symbol(middleware, Decl(index.tsx, 4, 16)) +>defaultMiddleware : Symbol(defaultMiddleware, Decl(index.tsx, 3, 13)) + +}); + +declare namespace React { +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) + + type DetailedHTMLProps, T> = E; +>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.tsx, 8, 25)) +>E : Symbol(E, Decl(index.tsx, 9, 25)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.tsx, 9, 61)) +>T : Symbol(T, Decl(index.tsx, 9, 53)) +>T : Symbol(T, Decl(index.tsx, 9, 53)) +>E : Symbol(E, Decl(index.tsx, 9, 25)) + + interface HTMLAttributes { +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.tsx, 9, 61)) +>T : Symbol(T, Decl(index.tsx, 10, 27)) + + children?: ReactNode; +>children : Symbol(HTMLAttributes.children, Decl(index.tsx, 10, 31)) +>ReactNode : Symbol(ReactNode, Decl(index.tsx, 12, 3)) + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : Symbol(ReactNode, Decl(index.tsx, 12, 3)) +>ReactChild : Symbol(ReactChild, Decl(index.tsx, 14, 35)) +>ReactFragment : Symbol(ReactFragment, Decl(index.tsx, 15, 30)) + + type ReactText = string | number; +>ReactText : Symbol(ReactText, Decl(index.tsx, 13, 75)) + + type ReactChild = ReactText; +>ReactChild : Symbol(ReactChild, Decl(index.tsx, 14, 35)) +>ReactText : Symbol(ReactText, Decl(index.tsx, 13, 75)) + + type ReactFragment = {} | ReactNodeArray; +>ReactFragment : Symbol(ReactFragment, Decl(index.tsx, 15, 30)) +>ReactNodeArray : Symbol(ReactNodeArray, Decl(index.tsx, 16, 43)) + + interface ReactNodeArray extends Array {} +>ReactNodeArray : Symbol(ReactNodeArray, Decl(index.tsx, 16, 43)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>ReactNode : Symbol(ReactNode, Decl(index.tsx, 12, 3)) +} +declare namespace JSX { +>JSX : Symbol(JSX, Decl(index.tsx, 18, 1)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.tsx, 19, 23)) + + ul: React.DetailedHTMLProps, HTMLUListElement>; +>ul : Symbol(IntrinsicElements.ul, Decl(index.tsx, 20, 31)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.tsx, 8, 25)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>HTMLAttributes : Symbol(React.HTMLAttributes, Decl(index.tsx, 9, 61)) +>HTMLUListElement : Symbol(HTMLUListElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLUListElement : Symbol(HTMLUListElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + li: React.DetailedHTMLProps, HTMLLIElement>; +>li : Symbol(IntrinsicElements.li, Decl(index.tsx, 21, 90)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.tsx, 8, 25)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>HTMLAttributes : Symbol(React.HTMLAttributes, Decl(index.tsx, 9, 61)) +>HTMLLIElement : Symbol(HTMLLIElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLLIElement : Symbol(HTMLLIElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + } +} +declare var React: any; +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) + +const Component = () => { +>Component : Symbol(Component, Decl(index.tsx, 27, 5)) + + const categories = ['Fruit', 'Vegetables']; +>categories : Symbol(categories, Decl(index.tsx, 28, 7)) + + return ( +
    +>ul : Symbol(JSX.IntrinsicElements.ul, Decl(index.tsx, 20, 31)) + +
  • All
  • +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) + + {categories.map((category) => ( +>categories.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>categories : Symbol(categories, Decl(index.tsx, 28, 7)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>category : Symbol(category, Decl(index.tsx, 33, 23)) + +
  • {category}
  • // Error about 'key' only +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) +>key : Symbol(key, Decl(index.tsx, 34, 11)) +>category : Symbol(category, Decl(index.tsx, 33, 23)) +>category : Symbol(category, Decl(index.tsx, 33, 23)) +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) + + ))} +
+>ul : Symbol(JSX.IntrinsicElements.ul, Decl(index.tsx, 20, 31)) + + ); +}; + diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.types b/tests/baselines/reference/excessiveStackDepthFlatArray.types new file mode 100644 index 00000000000..ae346a034fa --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.types @@ -0,0 +1,108 @@ +=== tests/cases/compiler/index.tsx === +interface MiddlewareArray extends Array {} +declare function configureStore(options: { middleware: MiddlewareArray }): void; +>configureStore : (options: { middleware: MiddlewareArray;}) => void +>options : { middleware: MiddlewareArray; } +>middleware : MiddlewareArray + +declare const defaultMiddleware: MiddlewareArray; +>defaultMiddleware : MiddlewareArray + +configureStore({ +>configureStore({ middleware: [...defaultMiddleware], // Should not error}) : void +>configureStore : (options: { middleware: MiddlewareArray; }) => void +>{ middleware: [...defaultMiddleware], // Should not error} : { middleware: any[]; } + + middleware: [...defaultMiddleware], // Should not error +>middleware : any[] +>[...defaultMiddleware] : any[] +>...defaultMiddleware : any +>defaultMiddleware : MiddlewareArray + +}); + +declare namespace React { + type DetailedHTMLProps, T> = E; +>DetailedHTMLProps : E + + interface HTMLAttributes { + children?: ReactNode; +>children : ReactNode + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : ReactNode +>null : null + + type ReactText = string | number; +>ReactText : ReactText + + type ReactChild = ReactText; +>ReactChild : ReactText + + type ReactFragment = {} | ReactNodeArray; +>ReactFragment : ReactFragment + + interface ReactNodeArray extends Array {} +} +declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; +>ul : React.HTMLAttributes +>React : any +>React : any + + li: React.DetailedHTMLProps, HTMLLIElement>; +>li : React.HTMLAttributes +>React : any +>React : any + } +} +declare var React: any; +>React : any + +const Component = () => { +>Component : () => any +>() => { const categories = ['Fruit', 'Vegetables']; return (
  • All
  • {categories.map((category) => (
  • {category}
  • // Error about 'key' only ))}
);} : () => any + + const categories = ['Fruit', 'Vegetables']; +>categories : string[] +>['Fruit', 'Vegetables'] : string[] +>'Fruit' : "Fruit" +>'Vegetables' : "Vegetables" + + return ( +>(
  • All
  • {categories.map((category) => (
  • {category}
  • // Error about 'key' only ))}
) : any + +
    +>
    • All
    • {categories.map((category) => (
    • {category}
    • // Error about 'key' only ))}
    : any +>ul : any + +
  • All
  • +>
  • All
  • : any +>li : any +>li : any + + {categories.map((category) => ( +>categories.map((category) => (
  • {category}
  • // Error about 'key' only )) : any[] +>categories.map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>categories : string[] +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>(category) => (
  • {category}
  • // Error about 'key' only ) : (category: string) => any +>category : string +>(
  • {category}
  • // Error about 'key' only ) : any + +
  • {category}
  • // Error about 'key' only +>
  • {category}
  • : any +>li : any +>key : string +>category : string +>category : string +>li : any + + ))} +
+>ul : any + + ); +}; + diff --git a/tests/cases/compiler/excessiveStackDepthFlatArray.ts b/tests/cases/compiler/excessiveStackDepthFlatArray.ts new file mode 100644 index 00000000000..b8ad99e287d --- /dev/null +++ b/tests/cases/compiler/excessiveStackDepthFlatArray.ts @@ -0,0 +1,43 @@ +// @lib: es2019,dom +// @jsx: react + +// @Filename: index.tsx +interface MiddlewareArray extends Array {} +declare function configureStore(options: { middleware: MiddlewareArray }): void; + +declare const defaultMiddleware: MiddlewareArray; +configureStore({ + middleware: [...defaultMiddleware], // Should not error +}); + +declare namespace React { + type DetailedHTMLProps, T> = E; + interface HTMLAttributes { + children?: ReactNode; + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactText = string | number; + type ReactChild = ReactText; + type ReactFragment = {} | ReactNodeArray; + interface ReactNodeArray extends Array {} +} +declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; + li: React.DetailedHTMLProps, HTMLLIElement>; + } +} +declare var React: any; + +const Component = () => { + const categories = ['Fruit', 'Vegetables']; + + return ( +
    +
  • All
  • + {categories.map((category) => ( +
  • {category}
  • // Error about 'key' only + ))} +
+ ); +}; From a8ee22f73dc25ef75b592143ab98b255c112b331 Mon Sep 17 00:00:00 2001 From: Sang <11912225+hantatsang@users.noreply.github.com> Date: Wed, 31 Mar 2021 09:24:31 +1100 Subject: [PATCH 10/16] "fix(services): convert to es6 module generate invalid code with .default" (#43309) --- src/services/codefixes/convertToEs6Module.ts | 28 +++++++++++++------ ...vertToEs6Module_import_es6DefaultImport.ts | 19 +++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 963f8923ee6..e15c507a4ef 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -436,7 +436,9 @@ namespace ts.codefix { /** * Convert `import x = require("x").` - * Also converts uses like `x.y()` to `y()` and uses a named import. + * Also: + * - Convert `x.default()` to `x()` to handle ES6 default export + * - Converts uses like `x.y()` to `y()` and uses a named import. */ function convertSingleIdentifierImport(name: Identifier, moduleSpecifier: StringLiteralLike, checker: TypeChecker, identifiers: Identifiers, quotePreference: QuotePreference): ConvertedImports { const nameSymbol = checker.getSymbolAtLocation(name); @@ -454,15 +456,23 @@ namespace ts.codefix { const { parent } = use; if (isPropertyAccessExpression(parent)) { - const { expression, name: { text: propertyName } } = parent; - Debug.assert(expression === use, "Didn't expect expression === use"); // Else shouldn't have been in `collectIdentifiers` - let idName = namedBindingsNames.get(propertyName); - if (idName === undefined) { - idName = makeUniqueName(propertyName, identifiers); - namedBindingsNames.set(propertyName, idName); - } + const { name: { text: propertyName } } = parent; + if (propertyName === "default") { + needDefaultImport = true; - (useSitesToUnqualify ??= new Map()).set(parent, factory.createIdentifier(idName)); + const importDefaultName = use.getText(); + (useSitesToUnqualify ??= new Map()).set(parent, factory.createIdentifier(importDefaultName)); + } + else { + Debug.assert(parent.expression === use, "Didn't expect expression === use"); // Else shouldn't have been in `collectIdentifiers` + let idName = namedBindingsNames.get(propertyName); + if (idName === undefined) { + idName = makeUniqueName(propertyName, identifiers); + namedBindingsNames.set(propertyName, idName); + } + + (useSitesToUnqualify ??= new Map()).set(parent, factory.createIdentifier(idName)); + } } else { needDefaultImport = true; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts new file mode 100644 index 00000000000..9fe26a24010 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts @@ -0,0 +1,19 @@ +/// + +// @allowJs: true +// @target: esnext + +// @Filename: /a.js +////const x = require('x'); +////x.default(); +////const y = require('y').default; +////y(); + +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import x from 'x'; +x(); +import y from 'y'; +y();`, +}); From 819651eb5f99fbfbba9b714a23cd0c86b1167e0d Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 31 Mar 2021 01:29:02 +0300 Subject: [PATCH 11/16] fix(43313): add parentheses to a type assertions (#43315) --- src/services/utilities.ts | 6 ++++-- .../refactorAddOrRemoveBracesToArrowFunction29.ts | 13 +++++++++++++ .../refactorAddOrRemoveBracesToArrowFunction30.ts | 13 +++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction29.ts create mode 100644 tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction30.ts diff --git a/src/services/utilities.ts b/src/services/utilities.ts index d4662783d87..f398afc46c0 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2516,8 +2516,10 @@ namespace ts { } /* @internal */ - export function needsParentheses(expression: Expression) { - return isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.CommaToken || isObjectLiteralExpression(expression); + export function needsParentheses(expression: Expression): boolean { + return isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.CommaToken + || isObjectLiteralExpression(expression) + || isAsExpression(expression) && isObjectLiteralExpression(expression.expression); } export function getContextualTypeFromParent(node: Expression, checker: TypeChecker): Type | undefined { diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction29.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction29.ts new file mode 100644 index 00000000000..b189082832e --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction29.ts @@ -0,0 +1,13 @@ +/// + +////const a = /*a*/()/*b*/ => { +//// return {} as {} +////}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const a = () => ({} as {});`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction30.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction30.ts new file mode 100644 index 00000000000..0cef0c3c7fe --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction30.ts @@ -0,0 +1,13 @@ +/// + +////const a = /*a*/()/*b*/ => { +//// return {} as object +////}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const a = () => ({} as object);`, +}); From 3dd68b878ae5c7c0e7beea20b5f5687df73db5f2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 30 Mar 2021 15:53:15 -0700 Subject: [PATCH 12/16] Fix template literal type relations (#43440) * Fix template literal relationships * Accept new baselines * Add regression test --- src/compiler/checker.ts | 19 +++++------------ .../templateLiteralTypes2.errors.txt | 20 +++++++----------- .../reference/templateLiteralTypes2.js | 14 +++++++++++++ .../reference/templateLiteralTypes2.symbols | 16 ++++++++++++++ .../reference/templateLiteralTypes2.types | 21 +++++++++++++++++++ .../types/literal/templateLiteralTypes2.ts | 6 ++++++ 6 files changed, 69 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index abd441ca76b..726690dd48f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18274,6 +18274,11 @@ namespace ts { } } else if (target.flags & TypeFlags.TemplateLiteral) { + if (source.flags & TypeFlags.TemplateLiteral) { + // Report unreliable variance for type variables referenced in template literal type placeholders. + // For example, `foo-${number}` is related to `foo-${string}` even though number isn't related to string. + instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); + } const result = inferTypesFromTemplateLiteralType(source, target as TemplateLiteralType); if (result && every(result, (r, i) => isValidTypeForTemplateLiteralPlaceholder(r, (target as TemplateLiteralType).types[i]))) { return Ternary.True; @@ -18318,20 +18323,6 @@ namespace ts { return result; } } - else if (source.flags & TypeFlags.TemplateLiteral) { - if (target.flags & TypeFlags.TemplateLiteral && - (source as TemplateLiteralType).texts.length === (target as TemplateLiteralType).texts.length && - (source as TemplateLiteralType).types.length === (target as TemplateLiteralType).types.length && - every((source as TemplateLiteralType).texts, (t, i) => t === (target as TemplateLiteralType).texts[i]) && - every((instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)) as TemplateLiteralType).types, (t, i) => !!((target as TemplateLiteralType).types[i].flags & (TypeFlags.Any | TypeFlags.String)) || !!isRelatedTo(t, (target as TemplateLiteralType).types[i], /*reportErrors*/ false))) { - return Ternary.True; - } - const constraint = getBaseConstraintOfType(source); - if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, reportErrors))) { - resetErrorInfo(saveErrorInfo); - return result; - } - } else if (source.flags & TypeFlags.StringMapping) { if (target.flags & TypeFlags.StringMapping && (source).symbol === (target).symbol) { if (result = isRelatedTo((source).type, (target).type, reportErrors)) { diff --git a/tests/baselines/reference/templateLiteralTypes2.errors.txt b/tests/baselines/reference/templateLiteralTypes2.errors.txt index 662b6704d63..7e9308d47e6 100644 --- a/tests/baselines/reference/templateLiteralTypes2.errors.txt +++ b/tests/baselines/reference/templateLiteralTypes2.errors.txt @@ -1,13 +1,9 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(23,11): error TS2322: Type 'string' is not assignable to type '`abc${string}`'. tests/cases/conformance/types/literal/templateLiteralTypes2.ts(29,11): error TS2322: Type 'string' is not assignable to type '`foo${string}` | `bar${string}`'. tests/cases/conformance/types/literal/templateLiteralTypes2.ts(32,11): error TS2322: Type 'string' is not assignable to type '`foo${string}` | `bar${string}` | `baz${string}`'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(67,9): error TS2322: Type '`foo${number}`' is not assignable to type 'String'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(68,9): error TS2322: Type '`foo${number}`' is not assignable to type 'Object'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(69,9): error TS2322: Type '`foo${number}`' is not assignable to type '{}'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(70,9): error TS2322: Type '`foo${number}`' is not assignable to type '{ length: number; }'. -==== tests/cases/conformance/types/literal/templateLiteralTypes2.ts (7 errors) ==== +==== tests/cases/conformance/types/literal/templateLiteralTypes2.ts (3 errors) ==== function ft1(s: string, n: number, u: 'foo' | 'bar' | 'baz', t: T) { const c1 = `abc${s}`; // `abc${string}` const c2 = `abc${n}`; // `abc${number}` @@ -81,17 +77,9 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(70,9): error TS23 function ft14(t: `foo${number}`) { let x1: string = t; let x2: String = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type 'String'. let x3: Object = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type 'Object'. let x4: {} = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type '{}'. let x6: { length: number } = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type '{ length: number; }'. } declare function g1(x: T): T; @@ -134,4 +122,10 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(70,9): error TS23 function getCardTitle(title: string): `test-${string}` { return `test-${title}`; } + + // Repro from #43424 + + const interpolatedStyle = { rotate: 12 }; + function C2(transform: "-moz-initial" | (string & {})) { return 12; } + C2(`rotate(${interpolatedStyle.rotate}dig)`); \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralTypes2.js b/tests/baselines/reference/templateLiteralTypes2.js index 87be2dbe4fa..37c101be269 100644 --- a/tests/baselines/reference/templateLiteralTypes2.js +++ b/tests/baselines/reference/templateLiteralTypes2.js @@ -111,6 +111,12 @@ const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`; function getCardTitle(title: string): `test-${string}` { return `test-${title}`; } + +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +C2(`rotate(${interpolatedStyle.rotate}dig)`); //// [templateLiteralTypes2.js] @@ -194,6 +200,10 @@ var pixelStringWithTemplate = pixelValue + "px"; function getCardTitle(title) { return "test-" + title; } +// Repro from #43424 +var interpolatedStyle = { rotate: 12 }; +function C2(transform) { return 12; } +C2("rotate(" + interpolatedStyle.rotate + "dig)"); //// [templateLiteralTypes2.d.ts] @@ -225,3 +235,7 @@ declare type PixelValueType = `${number}px`; declare const pixelString: PixelValueType; declare const pixelStringWithTemplate: PixelValueType; declare function getCardTitle(title: string): `test-${string}`; +declare const interpolatedStyle: { + rotate: number; +}; +declare function C2(transform: "-moz-initial" | (string & {})): number; diff --git a/tests/baselines/reference/templateLiteralTypes2.symbols b/tests/baselines/reference/templateLiteralTypes2.symbols index 6348ebce7f9..4ac9d428a06 100644 --- a/tests/baselines/reference/templateLiteralTypes2.symbols +++ b/tests/baselines/reference/templateLiteralTypes2.symbols @@ -361,3 +361,19 @@ function getCardTitle(title: string): `test-${string}` { >title : Symbol(title, Decl(templateLiteralTypes2.ts, 109, 22)) } +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +>interpolatedStyle : Symbol(interpolatedStyle, Decl(templateLiteralTypes2.ts, 115, 5)) +>rotate : Symbol(rotate, Decl(templateLiteralTypes2.ts, 115, 27)) + +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +>C2 : Symbol(C2, Decl(templateLiteralTypes2.ts, 115, 41)) +>transform : Symbol(transform, Decl(templateLiteralTypes2.ts, 116, 12)) + +C2(`rotate(${interpolatedStyle.rotate}dig)`); +>C2 : Symbol(C2, Decl(templateLiteralTypes2.ts, 115, 41)) +>interpolatedStyle.rotate : Symbol(rotate, Decl(templateLiteralTypes2.ts, 115, 27)) +>interpolatedStyle : Symbol(interpolatedStyle, Decl(templateLiteralTypes2.ts, 115, 5)) +>rotate : Symbol(rotate, Decl(templateLiteralTypes2.ts, 115, 27)) + diff --git a/tests/baselines/reference/templateLiteralTypes2.types b/tests/baselines/reference/templateLiteralTypes2.types index 274e3eb4f0b..24096c9d782 100644 --- a/tests/baselines/reference/templateLiteralTypes2.types +++ b/tests/baselines/reference/templateLiteralTypes2.types @@ -392,3 +392,24 @@ function getCardTitle(title: string): `test-${string}` { >title : string } +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +>interpolatedStyle : { rotate: number; } +>{ rotate: 12 } : { rotate: number; } +>rotate : number +>12 : 12 + +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +>C2 : (transform: "-moz-initial" | (string & {})) => number +>transform : (string & {}) | "-moz-initial" +>12 : 12 + +C2(`rotate(${interpolatedStyle.rotate}dig)`); +>C2(`rotate(${interpolatedStyle.rotate}dig)`) : number +>C2 : (transform: (string & {}) | "-moz-initial") => number +>`rotate(${interpolatedStyle.rotate}dig)` : `rotate(${number}dig)` +>interpolatedStyle.rotate : number +>interpolatedStyle : { rotate: number; } +>rotate : number + diff --git a/tests/cases/conformance/types/literal/templateLiteralTypes2.ts b/tests/cases/conformance/types/literal/templateLiteralTypes2.ts index 75ab1485a05..5e51c5b30b2 100644 --- a/tests/cases/conformance/types/literal/templateLiteralTypes2.ts +++ b/tests/cases/conformance/types/literal/templateLiteralTypes2.ts @@ -113,3 +113,9 @@ const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`; function getCardTitle(title: string): `test-${string}` { return `test-${title}`; } + +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +C2(`rotate(${interpolatedStyle.rotate}dig)`); From d51b8cff6acb5630d38c34df6b79802aefab1a9a Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 30 Mar 2021 16:04:25 -0700 Subject: [PATCH 13/16] Do not delete output file names that are same as input file name (#43448) * Add failing test case * Do not delete output file names that are same as input file name Fixes #43116 --- src/compiler/tsbuildPublic.ts | 4 ++++ src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/tsbuild/clean.ts | 16 +++++++++++++++ .../file-name-and-output-name-clashing.js | 20 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 src/testRunner/unittests/tsbuild/clean.ts create mode 100644 tests/baselines/reference/tsbuild/clean/initial-build/file-name-and-output-name-clashing.js diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index ddebecc2e55..d642f79a124 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -1717,7 +1717,11 @@ namespace ts { continue; } const outputs = getAllProjectOutputs(parsed, !host.useCaseSensitiveFileNames()); + if (!outputs.length) continue; + const inputFileNames = new Set(parsed.fileNames.map(f => toPath(state, f))); for (const output of outputs) { + // If output name is same as input file name, do not delete and ignore the error + if (inputFileNames.has(toPath(state, output))) continue; if (host.fileExists(output)) { if (filesToDelete) { filesToDelete.push(output); diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 34c55d0d5da..bf372efb81c 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -113,6 +113,7 @@ "unittests/services/textChanges.ts", "unittests/services/transpile.ts", "unittests/tsbuild/amdModulesWithOut.ts", + "unittests/tsbuild/clean.ts", "unittests/tsbuild/configFileErrors.ts", "unittests/tsbuild/configFileExtends.ts", "unittests/tsbuild/containerOnlyReferenced.ts", diff --git a/src/testRunner/unittests/tsbuild/clean.ts b/src/testRunner/unittests/tsbuild/clean.ts new file mode 100644 index 00000000000..90bb2985290 --- /dev/null +++ b/src/testRunner/unittests/tsbuild/clean.ts @@ -0,0 +1,16 @@ +namespace ts { + describe("unittests:: tsbuild - clean", () => { + verifyTsc({ + scenario: "clean", + subScenario: `file name and output name clashing`, + commandLineArgs: ["--b", "/src/tsconfig.json", "-clean"], + fs: () => loadProjectFromFiles({ + "/src/index.js": "", + "/src/bar.ts": "", + "/src/tsconfig.json": JSON.stringify({ + compilerOptions: { allowJs: true }, + }), + }), + }); + }); +} \ No newline at end of file diff --git a/tests/baselines/reference/tsbuild/clean/initial-build/file-name-and-output-name-clashing.js b/tests/baselines/reference/tsbuild/clean/initial-build/file-name-and-output-name-clashing.js new file mode 100644 index 00000000000..e8cecc75d8c --- /dev/null +++ b/tests/baselines/reference/tsbuild/clean/initial-build/file-name-and-output-name-clashing.js @@ -0,0 +1,20 @@ +Input:: +//// [/lib/lib.d.ts] + + +//// [/src/bar.ts] + + +//// [/src/index.js] + + +//// [/src/tsconfig.json] +{"compilerOptions":{"allowJs":true}} + + + +Output:: +/lib/tsc --b /src/tsconfig.json -clean +exitCode:: ExitStatus.Success + + From 5b7838e6faaa9590cef80747a35a1d0ae99004e1 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 31 Mar 2021 06:08:04 +0000 Subject: [PATCH 14/16] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50123efe16c..9f76a7acd9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -288,9 +288,9 @@ } }, "@octokit/core": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.3.1.tgz", - "integrity": "sha512-Dc5NNQOYjgZU5S1goN6A/E500yXOfDUFRGQB8/2Tl16AcfvS3H9PudyOe3ZNE/MaVyHPIfC0htReHMJb1tMrvw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.3.2.tgz", + "integrity": "sha512-Jx83n4tuX/z7QtxnPsAKxXPzH3vANtKmlCB3W3vt18JbkEaBYm+C8dgAlA1FNtqNk3L21pxsKNbWkUQAhiV7ng==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.4", From 76a2ae3d69e7eba33890d65159ee66719c69b916 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 31 Mar 2021 13:54:53 -0700 Subject: [PATCH 15/16] Only issue matching token errors on non-dupe locations (#43460) * Only issue matching token errors on non-dupe locations Intead of unconditionally retrieving the last error and attaching a related span, `parseErrorAt` and friends now return the last error and return `false` when there is none. Also make one more place use parseExpectedMatchingBrackets that I missed last time. * Inline parseTokenForError, return undefined not false * skip redundant undefined assignment * address PR comments --- src/compiler/parser.ts | 53 ++++++++----------- ...torWithIncompleteTypeAnnotation.errors.txt | 1 - ...tructuringParameterDeclaration2.errors.txt | 1 - ...thDotFollowedByNamespaceKeyword.errors.txt | 3 +- .../nestedClassDeclaration.errors.txt | 1 - .../objectLiteralWithSemicolons4.errors.txt | 3 +- .../objectSpreadNegativeParse.errors.txt | 1 - .../parseErrorIncorrectReturnToken.errors.txt | 1 - ...RecoveryArrayLiteralExpression3.errors.txt | 1 - .../reference/parserFuzz1.errors.txt | 3 +- .../reference/reservedWords2.errors.txt | 1 - .../syntax-errors-with-incremental.js | 10 ---- .../initial-build/syntax-errors.js | 10 ---- ...mit-any-files-on-error-with-incremental.js | 10 ---- .../does-not-emit-any-files-on-error.js | 10 ---- .../with-noEmitOnError-syntax-errors.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../default/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../defaultAndD/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../incremental/default/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../defaultAndD/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../isolatedModules/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../isolatedModulesAndD/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../isolatedModules/with-noEmitOnError.js | 10 ---- .../with-noEmitOnError-with-incremental.js | 10 ---- .../isolatedModulesAndD/with-noEmitOnError.js | 10 ---- 40 files changed, 25 insertions(+), 334 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index de0bb9c4022..e951178c1a8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1335,24 +1335,27 @@ namespace ts { return inContext(NodeFlags.AwaitContext); } - function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void { - parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0); + function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { + return parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0); } - function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): void { + function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { // Don't report another error if it would just be at the same position as the last error. const lastError = lastOrUndefined(parseDiagnostics); + let result: DiagnosticWithDetachedLocation | undefined; if (!lastError || start !== lastError.start) { - parseDiagnostics.push(createDetachedDiagnostic(fileName, start, length, message, arg0)); + result = createDetachedDiagnostic(fileName, start, length, message, arg0); + parseDiagnostics.push(result); } // Mark that we've encountered an error. We'll set an appropriate bit on the next // node we finish so that it can't be reused incrementally. parseErrorBeforeNextFinishedNode = true; + return result; } - function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): void { - parseErrorAtPosition(start, end - start, message, arg0); + function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { + return parseErrorAtPosition(start, end - start, message, arg0); } function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, arg0?: any): void { @@ -1543,17 +1546,17 @@ namespace ts { } function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openPosition: number) { - if (!parseExpected(closeKind)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind)) - ); - } - return false; + if (token() === closeKind) { + nextToken(); + return; + } + const lastError = parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(closeKind)); + if (lastError) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind)) + ); } - return true; } function parseOptional(t: SyntaxKind): boolean { @@ -5513,15 +5516,7 @@ namespace ts { parseExpected(SyntaxKind.OpenBraceToken); const multiLine = scanner.hasPrecedingLineBreak(); const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(SyntaxKind.OpenBraceToken), tokenToString(SyntaxKind.CloseBraceToken)) - ); - } - } + parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition); return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos); } @@ -7984,13 +7979,9 @@ namespace ts { hasChildren = true; if (child.kind === SyntaxKind.JSDocTypeTag) { if (childTypeTag) { - parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); - const lastError = lastOrUndefined(parseDiagnostics); + const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); if (lastError) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here) - ); + addRelatedInfo(lastError, createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here)); } break; } diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt index 9a3e9d81368..4e866e9e9e8 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt @@ -505,7 +505,6 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS !!! error TS1135: Argument expression expected. ~ !!! error TS1005: '(' expected. -!!! related TS1007 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:257:33: The parser expected to find a ')' to match the '(' token here. ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. ~~~ diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 02dde837f35..c1c79a2300d 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -39,7 +39,6 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( !!! error TS2322: Type 'string' is not assignable to type 'number'. ~ !!! error TS1005: ',' expected. -!!! related TS1007 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:7:4: The parser expected to find a ']' to match the '[' token here. a0([1, 2, [["world"]], "string"]); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. diff --git a/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt b/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt index 3a7c89e2f41..6bac6729147 100644 --- a/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt +++ b/tests/baselines/reference/errorRecoveryWithDotFollowedByNamespaceKeyword.errors.txt @@ -16,5 +16,4 @@ tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts(9,2): err } !!! error TS1005: '}' expected. -!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:3:19: The parser expected to find a '}' to match the '{' token here. -!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:2:20: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file +!!! related TS1007 tests/cases/compiler/errorRecoveryWithDotFollowedByNamespaceKeyword.ts:3:19: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/nestedClassDeclaration.errors.txt b/tests/baselines/reference/nestedClassDeclaration.errors.txt index 5540ee02437..f897c38d681 100644 --- a/tests/baselines/reference/nestedClassDeclaration.errors.txt +++ b/tests/baselines/reference/nestedClassDeclaration.errors.txt @@ -32,7 +32,6 @@ tests/cases/conformance/classes/nestedClassDeclaration.ts(17,1): error TS1128: D !!! error TS2304: Cannot find name 'C4'. ~ !!! error TS1005: ',' expected. -!!! related TS1007 tests/cases/conformance/classes/nestedClassDeclaration.ts:14:9: The parser expected to find a '}' to match the '{' token here. } } ~ diff --git a/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt b/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt index 651c0b66df7..544bddafff2 100644 --- a/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt +++ b/tests/baselines/reference/objectLiteralWithSemicolons4.errors.txt @@ -9,5 +9,4 @@ tests/cases/compiler/objectLiteralWithSemicolons4.ts(3,1): error TS1005: ',' exp !!! error TS18004: No value exists in scope for the shorthand property 'a'. Either declare one or provide an initializer. ; ~ -!!! error TS1005: ',' expected. -!!! related TS1007 tests/cases/compiler/objectLiteralWithSemicolons4.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegativeParse.errors.txt b/tests/baselines/reference/objectSpreadNegativeParse.errors.txt index 692fb7617da..b37200c4f02 100644 --- a/tests/baselines/reference/objectSpreadNegativeParse.errors.txt +++ b/tests/baselines/reference/objectSpreadNegativeParse.errors.txt @@ -28,7 +28,6 @@ tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(4,20): error T !!! error TS2304: Cannot find name 'matchMedia'. ~ !!! error TS1005: ',' expected. -!!! related TS1007 tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts:3:10: The parser expected to find a '}' to match the '{' token here. ~ !!! error TS1128: Declaration or statement expected. let o10 = { ...get x() { return 12; }}; diff --git a/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt b/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt index bc43cd5b776..2cf728848e4 100644 --- a/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt +++ b/tests/baselines/reference/parseErrorIncorrectReturnToken.errors.txt @@ -25,7 +25,6 @@ tests/cases/compiler/parseErrorIncorrectReturnToken.ts(12,1): error TS1128: Decl m(n: number) => string { ~~ !!! error TS1005: '{' expected. -!!! related TS1007 tests/cases/compiler/parseErrorIncorrectReturnToken.ts:8:9: The parser expected to find a '}' to match the '{' token here. ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. ~ diff --git a/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt b/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt index 9de5aa8014c..eb32618af4b 100644 --- a/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt +++ b/tests/baselines/reference/parserErrorRecoveryArrayLiteralExpression3.errors.txt @@ -8,7 +8,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions var texCoords = [2, 2, 0.5000001192092895, 0.8749999 ; 403953552, 0.5000001192092895, 0.8749999403953552]; ~ !!! error TS1005: ',' expected. -!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrayLiteralExpressions/parserErrorRecoveryArrayLiteralExpression3.ts:1:17: The parser expected to find a ']' to match the '[' token here. ~~~~~~~~~ !!! error TS2695: Left side of comma operator is unused and has no side effects. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/parserFuzz1.errors.txt b/tests/baselines/reference/parserFuzz1.errors.txt index e11d25c48fa..e90dda55244 100644 --- a/tests/baselines/reference/parserFuzz1.errors.txt +++ b/tests/baselines/reference/parserFuzz1.errors.txt @@ -20,5 +20,4 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserFuzz1.ts(2,15): e ~~~~~~ !!! error TS1005: ';' expected. -!!! error TS1005: '{' expected. -!!! related TS1007 tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserFuzz1.ts:1:9: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file +!!! error TS1005: '{' expected. \ No newline at end of file diff --git a/tests/baselines/reference/reservedWords2.errors.txt b/tests/baselines/reference/reservedWords2.errors.txt index 7c078493e8d..6ecb9471631 100644 --- a/tests/baselines/reference/reservedWords2.errors.txt +++ b/tests/baselines/reference/reservedWords2.errors.txt @@ -105,7 +105,6 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS1005: ';' expected. ~ !!! error TS1005: '(' expected. -!!! related TS1007 tests/cases/compiler/reservedWords2.ts:9:18: The parser expected to find a ')' to match the '(' token here. ~ !!! error TS1128: Declaration or statement expected. enum void {} diff --git a/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors-with-incremental.js b/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors-with-incremental.js index e6fd723a287..43e04e41056 100644 --- a/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors-with-incremental.js +++ b/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors-with-incremental.js @@ -47,11 +47,6 @@ Output:: 4 ;   ~ - src/src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - Found 1 error. @@ -81,11 +76,6 @@ Output:: 4 ;   ~ - src/src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - Found 1 error. diff --git a/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors.js b/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors.js index 4c55b9ce60f..e9ea12ea0d3 100644 --- a/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors.js +++ b/tests/baselines/reference/tsbuild/noEmitOnError/initial-build/syntax-errors.js @@ -47,11 +47,6 @@ Output:: 4 ;   ~ - src/src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - Found 1 error. @@ -81,11 +76,6 @@ Output:: 4 ;   ~ - src/src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - Found 1 error. diff --git a/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error-with-incremental.js b/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error-with-incremental.js index a05c649643c..8ad612bca9b 100644 --- a/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error-with-incremental.js +++ b/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error-with-incremental.js @@ -56,11 +56,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:35 AM] Found 1 error. Watching for file changes. @@ -113,11 +108,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:42 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error.js b/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error.js index 3e563e8f609..6af8477219c 100644 --- a/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error.js +++ b/tests/baselines/reference/tsbuild/watchMode/noEmitOnError/does-not-emit-any-files-on-error.js @@ -56,11 +56,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:35 AM] Found 1 error. Watching for file changes. @@ -113,11 +108,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:42 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tsc/incremental/initial-build/with-noEmitOnError-syntax-errors.js b/tests/baselines/reference/tsc/incremental/initial-build/with-noEmitOnError-syntax-errors.js index c539e3763b4..61a42c07f86 100644 --- a/tests/baselines/reference/tsc/incremental/initial-build/with-noEmitOnError-syntax-errors.js +++ b/tests/baselines/reference/tsc/incremental/initial-build/with-noEmitOnError-syntax-errors.js @@ -47,11 +47,6 @@ Output:: 4 ;   ~ - src/src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - Found 1 error. @@ -166,11 +161,6 @@ Output:: 4 ;   ~ - src/src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - Found 1 error. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js index 682a68af31e..97c07812515 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js index 17c877f6ac1..16681988e8f 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:32 AM] Found 1 error. Watching for file changes. @@ -104,11 +99,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js index 0e63864873c..9b41d9d0913 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -187,11 +182,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js index 9c9b6f756c1..bae815eebeb 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:32 AM] Found 1 error. Watching for file changes. @@ -104,11 +99,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError-with-incremental.js index 46b48bf4ce5..3994e240983 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError-with-incremental.js @@ -49,11 +49,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -191,11 +186,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError.js index fbb7a7ed574..da78efc9fba 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/default/with-noEmitOnError.js @@ -49,11 +49,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:32 AM] Found 1 error. Watching for file changes. @@ -110,11 +105,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError-with-incremental.js index ba168ab833f..95da55bc583 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError.js index 442f3d18610..3c0a5fcd89b 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/defaultAndD/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:32 AM] Found 1 error. Watching for file changes. @@ -104,11 +99,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js index 13cfbf7708d..eaea5f602e6 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js index 4a82b0f24e5..105964812e7 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js index 101a14226d2..874eff425a3 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -187,11 +182,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js index c90e071624b..bc6607b8d53 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/assumeChangesOnlyAffectDirectDependenciesAndD/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -187,11 +182,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError-with-incremental.js index 73fb8a3f99e..1f04fa2e666 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError-with-incremental.js @@ -49,11 +49,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -191,11 +186,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError.js index 928db04fad6..8d6647dbc4d 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/default/with-noEmitOnError.js @@ -49,11 +49,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -191,11 +186,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError-with-incremental.js index e2394ec3152..29b3348f4df 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError.js index accbfbc36e4..0a5da71c0d0 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/defaultAndD/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError-with-incremental.js index 22e73f151f5..ea636a1de95 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError.js index 59fc6a820f0..62bccd4b4e1 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModules/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError-with-incremental.js index ea3425d143d..ebda20c91cd 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -187,11 +182,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError.js index ddff239e3c9..81d203d04cd 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/incremental/isolatedModulesAndD/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -187,11 +182,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError-with-incremental.js index daf7e2b9e0f..18759a8a9c6 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -186,11 +181,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError.js index 4093ad48302..48c8bcb5bd3 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModules/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:32 AM] Found 1 error. Watching for file changes. @@ -104,11 +99,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError-with-incremental.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError-with-incremental.js index b6323d2ed80..27bfca04dbd 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError-with-incremental.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError-with-incremental.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. @@ -187,11 +182,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:44 AM] Found 1 error. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError.js b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError.js index 659ad657153..0969d50832b 100644 --- a/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError.js +++ b/tests/baselines/reference/tscWatch/emitAndErrorUpdates/isolatedModulesAndD/with-noEmitOnError.js @@ -43,11 +43,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:32 AM] Found 1 error. Watching for file changes. @@ -104,11 +99,6 @@ Output:: 4 ;   ~ - src/main.ts:2:11 - 2 const a = { -    ~ - The parser expected to find a '}' to match the '{' token here. - [12:00:37 AM] Found 1 error. Watching for file changes. From 62f3ccd9c00f2da4cc995ef0e66c4dfb91eec8bf Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Thu, 1 Apr 2021 06:57:25 +0800 Subject: [PATCH 16/16] Error if assignment after block (#41115) * Error if assignment after block * Update src/compiler/diagnosticMessages.json Co-authored-by: Daniel Rosenwasser * Fix diags * Error after block Co-authored-by: Daniel Rosenwasser Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> --- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/parser.ts | 11 +++-- .../reference/assignmentLHSIsValue.errors.txt | 15 +++--- .../reference/assignmentLHSIsValue.types | 2 +- .../destructionAssignmentError.errors.txt | 27 +++++++++++ .../reference/destructionAssignmentError.js | 28 +++++++++++ .../destructionAssignmentError.symbols | 36 ++++++++++++++ .../destructionAssignmentError.types | 48 +++++++++++++++++++ .../compiler/destructionAssignmentError.ts | 12 +++++ 9 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 tests/baselines/reference/destructionAssignmentError.errors.txt create mode 100644 tests/baselines/reference/destructionAssignmentError.js create mode 100644 tests/baselines/reference/destructionAssignmentError.symbols create mode 100644 tests/baselines/reference/destructionAssignmentError.types create mode 100644 tests/cases/compiler/destructionAssignmentError.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9a275dd586b..b0d3edd52bd 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3308,6 +3308,10 @@ "category": "Error", "code": 2808 }, + "Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.": { + "category": "Error", + "code": 2809 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e951178c1a8..1d42346123b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2109,8 +2109,7 @@ namespace ts { while (!isListTerminator(kind)) { if (isListElement(kind, /*inErrorRecovery*/ false)) { - const element = parseListElement(kind, parseElement); - list.push(element); + list.push(parseListElement(kind, parseElement)); continue; } @@ -5602,7 +5601,13 @@ namespace ts { const multiLine = scanner.hasPrecedingLineBreak(); const statements = parseList(ParsingContext.BlockStatements, parseStatement); parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBracePosition); - return finishNode(factory.createBlock(statements, multiLine), pos); + const result = finishNode(factory.createBlock(statements, multiLine), pos); + if (token() === SyntaxKind.EqualsToken) { + parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_the_whole_assignment_in_parentheses); + nextToken(); + } + + return result; } else { const statements = createMissingList(); diff --git a/tests/baselines/reference/assignmentLHSIsValue.errors.txt b/tests/baselines/reference/assignmentLHSIsValue.errors.txt index 1cf07b81622..71809b4605f 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/assignmentLHSIsValue.errors.txt @@ -13,14 +13,15 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(2 tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(30,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(31,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(32,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. -tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS1128: Declaration or statement expected. +tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,2): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,6): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(42,36): error TS1034: 'super' must be followed by an argument list or member access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(44,19): error TS1034: 'super' must be followed by an argument list or member access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(46,27): error TS1034: 'super' must be followed by an argument list or member access. -tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(50,20): error TS1128: Declaration or statement expected. -tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,11): error TS1005: ';' expected. +tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(50,20): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. +tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,11): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. +tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(51,13): error TS1005: ';' expected. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(54,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(57,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(58,2): error TS2631: Cannot assign to 'M' because it is a namespace. @@ -38,7 +39,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(6 tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(70,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. -==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (38 errors) ==== +==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (39 errors) ==== // expected error for all the LHS of assignments var value: any; @@ -105,7 +106,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7 // object literals { a: 0} = value; ~ -!!! error TS1128: Declaration or statement expected. +!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. // array literals ['', ''] = value; @@ -132,9 +133,11 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7 // function expression function bar() { } = value; ~ -!!! error TS1128: Declaration or statement expected. +!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. () => { } = value; ~ +!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. + ~~~~~ !!! error TS1005: ';' expected. // function calls diff --git a/tests/baselines/reference/assignmentLHSIsValue.types b/tests/baselines/reference/assignmentLHSIsValue.types index 82dd7f026ad..ad4905acc94 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.types +++ b/tests/baselines/reference/assignmentLHSIsValue.types @@ -146,7 +146,7 @@ function bar() { } = value; >value : any () => { } = value; ->() => { } : () => void +>() => { } = : () => void >value : any // function calls diff --git a/tests/baselines/reference/destructionAssignmentError.errors.txt b/tests/baselines/reference/destructionAssignmentError.errors.txt new file mode 100644 index 00000000000..831f9a5fc6c --- /dev/null +++ b/tests/baselines/reference/destructionAssignmentError.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/destructionAssignmentError.ts(6,3): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/compiler/destructionAssignmentError.ts(6,10): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. +tests/cases/compiler/destructionAssignmentError.ts(11,3): error TS2695: Left side of comma operator is unused and has no side effects. +tests/cases/compiler/destructionAssignmentError.ts(12,1): error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. + + +==== tests/cases/compiler/destructionAssignmentError.ts (4 errors) ==== + declare function fn(): { a: 1, b: 2 } + let a: number; + let b: number; + + ({ a, b } = fn()); + { a, b } = fn(); + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + ~ +!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. + + ({ a, b } = + fn()); + + { a, b } + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. + = fn(); + ~ +!!! error TS2809: Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses. \ No newline at end of file diff --git a/tests/baselines/reference/destructionAssignmentError.js b/tests/baselines/reference/destructionAssignmentError.js new file mode 100644 index 00000000000..f188ccc1daa --- /dev/null +++ b/tests/baselines/reference/destructionAssignmentError.js @@ -0,0 +1,28 @@ +//// [destructionAssignmentError.ts] +declare function fn(): { a: 1, b: 2 } +let a: number; +let b: number; + +({ a, b } = fn()); +{ a, b } = fn(); + +({ a, b } = +fn()); + +{ a, b } += fn(); + +//// [destructionAssignmentError.js] +var _a, _b; +var a; +var b; +(_a = fn(), a = _a.a, b = _a.b); +{ + a, b; +} +fn(); +(_b = fn(), a = _b.a, b = _b.b); +{ + a, b; +} +fn(); diff --git a/tests/baselines/reference/destructionAssignmentError.symbols b/tests/baselines/reference/destructionAssignmentError.symbols new file mode 100644 index 00000000000..82650703289 --- /dev/null +++ b/tests/baselines/reference/destructionAssignmentError.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/destructionAssignmentError.ts === +declare function fn(): { a: 1, b: 2 } +>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0)) +>a : Symbol(a, Decl(destructionAssignmentError.ts, 0, 24)) +>b : Symbol(b, Decl(destructionAssignmentError.ts, 0, 30)) + +let a: number; +>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3)) + +let b: number; +>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3)) + +({ a, b } = fn()); +>a : Symbol(a, Decl(destructionAssignmentError.ts, 4, 2)) +>b : Symbol(b, Decl(destructionAssignmentError.ts, 4, 5)) +>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0)) + +{ a, b } = fn(); +>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3)) +>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3)) +>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0)) + +({ a, b } = +>a : Symbol(a, Decl(destructionAssignmentError.ts, 7, 2)) +>b : Symbol(b, Decl(destructionAssignmentError.ts, 7, 5)) + +fn()); +>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0)) + +{ a, b } +>a : Symbol(a, Decl(destructionAssignmentError.ts, 1, 3)) +>b : Symbol(b, Decl(destructionAssignmentError.ts, 2, 3)) + += fn(); +>fn : Symbol(fn, Decl(destructionAssignmentError.ts, 0, 0)) + diff --git a/tests/baselines/reference/destructionAssignmentError.types b/tests/baselines/reference/destructionAssignmentError.types new file mode 100644 index 00000000000..94cbd3f792f --- /dev/null +++ b/tests/baselines/reference/destructionAssignmentError.types @@ -0,0 +1,48 @@ +=== tests/cases/compiler/destructionAssignmentError.ts === +declare function fn(): { a: 1, b: 2 } +>fn : () => { a: 1; b: 2;} +>a : 1 +>b : 2 + +let a: number; +>a : number + +let b: number; +>b : number + +({ a, b } = fn()); +>({ a, b } = fn()) : { a: 1; b: 2; } +>{ a, b } = fn() : { a: 1; b: 2; } +>{ a, b } : { a: number; b: number; } +>a : number +>b : number +>fn() : { a: 1; b: 2; } +>fn : () => { a: 1; b: 2; } + +{ a, b } = fn(); +>a, b : number +>a : number +>b : number +>fn() : { a: 1; b: 2; } +>fn : () => { a: 1; b: 2; } + +({ a, b } = +>({ a, b } =fn()) : { a: 1; b: 2; } +>{ a, b } =fn() : { a: 1; b: 2; } +>{ a, b } : { a: number; b: number; } +>a : number +>b : number + +fn()); +>fn() : { a: 1; b: 2; } +>fn : () => { a: 1; b: 2; } + +{ a, b } +>a, b : number +>a : number +>b : number + += fn(); +>fn() : { a: 1; b: 2; } +>fn : () => { a: 1; b: 2; } + diff --git a/tests/cases/compiler/destructionAssignmentError.ts b/tests/cases/compiler/destructionAssignmentError.ts new file mode 100644 index 00000000000..6845391d659 --- /dev/null +++ b/tests/cases/compiler/destructionAssignmentError.ts @@ -0,0 +1,12 @@ +declare function fn(): { a: 1, b: 2 } +let a: number; +let b: number; + +({ a, b } = fn()); +{ a, b } = fn(); + +({ a, b } = +fn()); + +{ a, b } += fn(); \ No newline at end of file