From 2623fe7049cfd837552c1dfab0b3c4687f0ec8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 20 Jul 2023 21:13:44 +0200 Subject: [PATCH] Fixed false positive syntax errors with in inside for (#54801) Co-authored-by: Evan Wallace --- src/compiler/parser.ts | 4 +- .../parserForInStatement8.errors.txt | 20 +++++++++ .../reference/parserForInStatement8.js | 15 +++++++ .../reference/parserForInStatement8.symbols | 21 ++++++++++ .../reference/parserForInStatement8.types | 33 +++++++++++++++ .../parserForOfStatement25.errors.txt | 11 +++++ .../reference/parserForOfStatement25.js | 15 +++++++ .../reference/parserForOfStatement25.symbols | 19 +++++++++ .../reference/parserForOfStatement25.types | 31 ++++++++++++++ .../reference/parserForStatement9.js | 15 +++++++ .../reference/parserForStatement9.symbols | 25 +++++++++++ .../reference/parserForStatement9.types | 41 +++++++++++++++++++ .../Statements/parserForInStatement8.ts | 4 ++ .../Statements/parserForStatement9.ts | 4 ++ .../Iterators/parserForOfStatement25.ts | 6 +++ 15 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/parserForInStatement8.errors.txt create mode 100644 tests/baselines/reference/parserForInStatement8.js create mode 100644 tests/baselines/reference/parserForInStatement8.symbols create mode 100644 tests/baselines/reference/parserForInStatement8.types create mode 100644 tests/baselines/reference/parserForOfStatement25.errors.txt create mode 100644 tests/baselines/reference/parserForOfStatement25.js create mode 100644 tests/baselines/reference/parserForOfStatement25.symbols create mode 100644 tests/baselines/reference/parserForOfStatement25.types create mode 100644 tests/baselines/reference/parserForStatement9.js create mode 100644 tests/baselines/reference/parserForStatement9.symbols create mode 100644 tests/baselines/reference/parserForStatement9.types create mode 100644 tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts create mode 100644 tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts create mode 100644 tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9890a18fa5d..82e4d8d006a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -7487,7 +7487,7 @@ namespace Parser { function parseObjectBindingPattern(): ObjectBindingPattern { const pos = getNodePos(); parseExpected(SyntaxKind.OpenBraceToken); - const elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement); + const elements = allowInAnd(() => parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement)); parseExpected(SyntaxKind.CloseBraceToken); return finishNode(factory.createObjectBindingPattern(elements), pos); } @@ -7495,7 +7495,7 @@ namespace Parser { function parseArrayBindingPattern(): ArrayBindingPattern { const pos = getNodePos(); parseExpected(SyntaxKind.OpenBracketToken); - const elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement); + const elements = allowInAnd(() => parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement)); parseExpected(SyntaxKind.CloseBracketToken); return finishNode(factory.createArrayBindingPattern(elements), pos); } diff --git a/tests/baselines/reference/parserForInStatement8.errors.txt b/tests/baselines/reference/parserForInStatement8.errors.txt new file mode 100644 index 00000000000..e7e518d42ee --- /dev/null +++ b/tests/baselines/reference/parserForInStatement8.errors.txt @@ -0,0 +1,20 @@ +parserForInStatement8.ts(3,10): error TS2461: Type 'string' is not an array type. +parserForInStatement8.ts(3,10): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern. +parserForInStatement8.ts(4,10): error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern. +parserForInStatement8.ts(4,11): error TS2339: Property 'x' does not exist on type 'String'. + + +==== parserForInStatement8.ts (4 errors) ==== + // repro from https://github.com/microsoft/TypeScript/issues/54769 + + for (let [x = 'a' in {}] in { '': 0 }) console.log(x) + ~~~~~~~~~~~~~~~ +!!! error TS2461: Type 'string' is not an array type. + ~~~~~~~~~~~~~~~ +!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern. + for (let {x = 'a' in {}} in { '': 0 }) console.log(x) + ~~~~~~~~~~~~~~~ +!!! error TS2491: The left-hand side of a 'for...in' statement cannot be a destructuring pattern. + ~ +!!! error TS2339: Property 'x' does not exist on type 'String'. + \ No newline at end of file diff --git a/tests/baselines/reference/parserForInStatement8.js b/tests/baselines/reference/parserForInStatement8.js new file mode 100644 index 00000000000..c1d737ec26e --- /dev/null +++ b/tests/baselines/reference/parserForInStatement8.js @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts] //// + +//// [parserForInStatement8.ts] +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] in { '': 0 }) console.log(x) +for (let {x = 'a' in {}} in { '': 0 }) console.log(x) + + +//// [parserForInStatement8.js] +// repro from https://github.com/microsoft/TypeScript/issues/54769 +for (var _a = (void 0)[0], x = _a === void 0 ? 'a' in {} : _a in { '': 0 }) + console.log(x); +for (var _b = (void 0).x, x = _b === void 0 ? 'a' in {} : _b in { '': 0 }) + console.log(x); diff --git a/tests/baselines/reference/parserForInStatement8.symbols b/tests/baselines/reference/parserForInStatement8.symbols new file mode 100644 index 00000000000..59ef3e5dccb --- /dev/null +++ b/tests/baselines/reference/parserForInStatement8.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts] //// + +=== parserForInStatement8.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] in { '': 0 }) console.log(x) +>x : Symbol(x, Decl(parserForInStatement8.ts, 2, 10)) +>'' : Symbol('', Decl(parserForInStatement8.ts, 2, 29)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(parserForInStatement8.ts, 2, 10)) + +for (let {x = 'a' in {}} in { '': 0 }) console.log(x) +>x : Symbol(x, Decl(parserForInStatement8.ts, 3, 10)) +>'' : Symbol('', Decl(parserForInStatement8.ts, 3, 29)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(parserForInStatement8.ts, 3, 10)) + diff --git a/tests/baselines/reference/parserForInStatement8.types b/tests/baselines/reference/parserForInStatement8.types new file mode 100644 index 00000000000..fd37c48a1f4 --- /dev/null +++ b/tests/baselines/reference/parserForInStatement8.types @@ -0,0 +1,33 @@ +//// [tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts] //// + +=== parserForInStatement8.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] in { '': 0 }) console.log(x) +>x : any +>'a' in {} : boolean +>'a' : "a" +>{} : {} +>{ '': 0 } : { '': number; } +>'' : number +>0 : 0 +>console.log(x) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>x : any + +for (let {x = 'a' in {}} in { '': 0 }) console.log(x) +>x : any +>'a' in {} : boolean +>'a' : "a" +>{} : {} +>{ '': 0 } : { '': number; } +>'' : number +>0 : 0 +>console.log(x) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>x : any + diff --git a/tests/baselines/reference/parserForOfStatement25.errors.txt b/tests/baselines/reference/parserForOfStatement25.errors.txt new file mode 100644 index 00000000000..68a6589ca56 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement25.errors.txt @@ -0,0 +1,11 @@ +parserForOfStatement25.ts(4,11): error TS2339: Property 'x' does not exist on type '{}'. + + +==== parserForOfStatement25.ts (1 errors) ==== + // repro from https://github.com/microsoft/TypeScript/issues/54769 + + for (let [x = 'a' in {}] of [[]]) console.log(x) + for (let {x = 'a' in {}} of [{}]) console.log(x) + ~ +!!! error TS2339: Property 'x' does not exist on type '{}'. + \ No newline at end of file diff --git a/tests/baselines/reference/parserForOfStatement25.js b/tests/baselines/reference/parserForOfStatement25.js new file mode 100644 index 00000000000..3261eb14cf3 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement25.js @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts] //// + +//// [parserForOfStatement25.ts] +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] of [[]]) console.log(x) +for (let {x = 'a' in {}} of [{}]) console.log(x) + + +//// [parserForOfStatement25.js] +// repro from https://github.com/microsoft/TypeScript/issues/54769 +for (let [x = 'a' in {}] of [[]]) + console.log(x); +for (let { x = 'a' in {} } of [{}]) + console.log(x); diff --git a/tests/baselines/reference/parserForOfStatement25.symbols b/tests/baselines/reference/parserForOfStatement25.symbols new file mode 100644 index 00000000000..abb0637ea83 --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement25.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts] //// + +=== parserForOfStatement25.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] of [[]]) console.log(x) +>x : Symbol(x, Decl(parserForOfStatement25.ts, 2, 10)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(parserForOfStatement25.ts, 2, 10)) + +for (let {x = 'a' in {}} of [{}]) console.log(x) +>x : Symbol(x, Decl(parserForOfStatement25.ts, 3, 10)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(parserForOfStatement25.ts, 3, 10)) + diff --git a/tests/baselines/reference/parserForOfStatement25.types b/tests/baselines/reference/parserForOfStatement25.types new file mode 100644 index 00000000000..c57332203eb --- /dev/null +++ b/tests/baselines/reference/parserForOfStatement25.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts] //// + +=== parserForOfStatement25.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] of [[]]) console.log(x) +>x : boolean +>'a' in {} : boolean +>'a' : "a" +>{} : {} +>[[]] : undefined[][] +>[] : undefined[] +>console.log(x) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>x : boolean + +for (let {x = 'a' in {}} of [{}]) console.log(x) +>x : any +>'a' in {} : boolean +>'a' : "a" +>{} : {} +>[{}] : {}[] +>{} : {} +>console.log(x) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>x : any + diff --git a/tests/baselines/reference/parserForStatement9.js b/tests/baselines/reference/parserForStatement9.js new file mode 100644 index 00000000000..714af52a02f --- /dev/null +++ b/tests/baselines/reference/parserForStatement9.js @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts] //// + +//// [parserForStatement9.ts] +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] = []; !x; x = !x) console.log(x) +for (let {x = 'a' in {}} = {}; !x; x = !x) console.log(x) + + +//// [parserForStatement9.js] +// repro from https://github.com/microsoft/TypeScript/issues/54769 +for (var _a = [][0], x = _a === void 0 ? 'a' in {} : _a; !x; x = !x) + console.log(x); +for (var _b = {}.x, x = _b === void 0 ? 'a' in {} : _b; !x; x = !x) + console.log(x); diff --git a/tests/baselines/reference/parserForStatement9.symbols b/tests/baselines/reference/parserForStatement9.symbols new file mode 100644 index 00000000000..0185da616e3 --- /dev/null +++ b/tests/baselines/reference/parserForStatement9.symbols @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts] //// + +=== parserForStatement9.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] = []; !x; x = !x) console.log(x) +>x : Symbol(x, Decl(parserForStatement9.ts, 2, 10)) +>x : Symbol(x, Decl(parserForStatement9.ts, 2, 10)) +>x : Symbol(x, Decl(parserForStatement9.ts, 2, 10)) +>x : Symbol(x, Decl(parserForStatement9.ts, 2, 10)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(parserForStatement9.ts, 2, 10)) + +for (let {x = 'a' in {}} = {}; !x; x = !x) console.log(x) +>x : Symbol(x, Decl(parserForStatement9.ts, 3, 10)) +>x : Symbol(x, Decl(parserForStatement9.ts, 3, 10)) +>x : Symbol(x, Decl(parserForStatement9.ts, 3, 10)) +>x : Symbol(x, Decl(parserForStatement9.ts, 3, 10)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(parserForStatement9.ts, 3, 10)) + diff --git a/tests/baselines/reference/parserForStatement9.types b/tests/baselines/reference/parserForStatement9.types new file mode 100644 index 00000000000..359955ac632 --- /dev/null +++ b/tests/baselines/reference/parserForStatement9.types @@ -0,0 +1,41 @@ +//// [tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts] //// + +=== parserForStatement9.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] = []; !x; x = !x) console.log(x) +>x : boolean +>'a' in {} : boolean +>'a' : "a" +>{} : {} +>[] : [] +>!x : boolean +>x : boolean +>x = !x : boolean +>x : boolean +>!x : boolean +>x : boolean +>console.log(x) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>x : boolean + +for (let {x = 'a' in {}} = {}; !x; x = !x) console.log(x) +>x : boolean +>'a' in {} : boolean +>'a' : "a" +>{} : {} +>{} : { x?: boolean; } +>!x : boolean +>x : boolean +>x = !x : boolean +>x : boolean +>!x : boolean +>x : boolean +>console.log(x) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>x : boolean + diff --git a/tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts b/tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts new file mode 100644 index 00000000000..99610bc6e49 --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/Statements/parserForInStatement8.ts @@ -0,0 +1,4 @@ +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] in { '': 0 }) console.log(x) +for (let {x = 'a' in {}} in { '': 0 }) console.log(x) diff --git a/tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts b/tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts new file mode 100644 index 00000000000..a082ca4f21f --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/Statements/parserForStatement9.ts @@ -0,0 +1,4 @@ +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] = []; !x; x = !x) console.log(x) +for (let {x = 'a' in {}} = {}; !x; x = !x) console.log(x) diff --git a/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts new file mode 100644 index 00000000000..8abd119e170 --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement25.ts @@ -0,0 +1,6 @@ +// @target: esnext + +// repro from https://github.com/microsoft/TypeScript/issues/54769 + +for (let [x = 'a' in {}] of [[]]) console.log(x) +for (let {x = 'a' in {}} of [{}]) console.log(x)