Skip to content

Commit 5ef0439

Browse files
hi-ogawasandersn
andauthored
fix(45802): keep children of mismatched jsx element (#45839)
* fix(45802): keep children of mismatched jsx element * Apply suggestions from code review Co-authored-by: Nathan Shively-Sanders <[email protected]> Co-authored-by: Nathan Shively-Sanders <[email protected]>
1 parent 78472ec commit 5ef0439

File tree

5 files changed

+47
-19
lines changed

5 files changed

+47
-19
lines changed

src/compiler/parser.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5042,12 +5042,12 @@ namespace ts {
50425042
&& !tagNamesAreEquivalent(lastChild.openingElement.tagName, lastChild.closingElement.tagName)
50435043
&& tagNamesAreEquivalent(opening.tagName, lastChild.closingElement.tagName)) {
50445044
// when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement,
5045-
// restructure (<div>(...<span></div>)) --> (<div>(...<span></span>)</div>)
5045+
// restructure (<div>(...<span>...</div>)) --> (<div>(...<span>...</>)</div>)
50465046
// (no need to error; the parent will error)
5047-
const end = lastChild.openingElement.end; // newly-created children and closing are both zero-width end/end
5047+
const end = lastChild.children.end;
50485048
const newLast = finishNode(factory.createJsxElement(
50495049
lastChild.openingElement,
5050-
createNodeArray([], end, end),
5050+
lastChild.children,
50515051
finishNode(factory.createJsxClosingElement(finishNode(factory.createIdentifier(""), end, end)), end, end)),
50525052
lastChild.openingElement.pos,
50535053
end);

tests/baselines/reference/jsxUnclosedParserRecovery.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,12 @@ var donkey = <div>
195195
</div>;
196196
function noCloseBracketTypeArgAttrs() { }
197197
var donkey = <div>
198-
<diddy></></div>;
198+
<diddy>
199+
</></div>;
199200
function noSelfclose() { }
200201
var donkey = <div>
201-
<diddy bananas="please"></></div>;
202+
<diddy bananas="please">
203+
</></div>;
202204
function noSelfcloseTypeArgAttrs() { }
203205
var donkey = <div>
204206
< />
@@ -234,10 +236,14 @@ var donkey = <div>
234236
</div>;
235237
function noCloseBracketTypeArgAttrsTrailingTag() { }
236238
var donkey = <div>
237-
<diddy></></div>;
239+
<diddy>
240+
<diddy />
241+
</></div>;
238242
function noSelfcloseTrailingTag() { }
239243
var donkey = <div>
240-
<diddy bananas="please"></></div>;
244+
<diddy bananas="please">
245+
<diddy />
246+
</></div>;
241247
function noSelfcloseTypeArgAttrsTrailingTag() { }
242248
var donkey = <div>
243249
<Cranky Wrinkly Funky/>
@@ -270,8 +276,12 @@ var donkey = <div>
270276
</div>;
271277
function noCloseBracketTypeArgAttrsTrailingText() { }
272278
var donkey = <div>
273-
<diddy></></div>;
279+
<diddy>
280+
Cranky Wrinkly Funky
281+
</></div>;
274282
function noSelfcloseTrailingText() { }
275283
var donkey = <div>
276-
<diddy bananas="please"></></div>;
284+
<diddy bananas="please">
285+
Cranky Wrinkly Funky
286+
</></div>;
277287
function noSelfcloseTypeArgAttrsTrailingText() { }

tests/baselines/reference/jsxUnclosedParserRecovery.types

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,15 @@ var donkey = <div>
337337
>div : any
338338

339339
<diddy>
340-
><diddy> : any
340+
><diddy> <diddy/> : any
341341
>diddy : () => any
342342

343343
<diddy/>
344-
> : any
344+
><diddy/> : any
345+
>diddy : () => any
345346

346347
</div>;
348+
> : any
347349
>div : any
348350

349351
function noSelfcloseTrailingTag() { }
@@ -355,14 +357,16 @@ var donkey = <div>
355357
>div : any
356358

357359
<diddy<boolean> bananas="please">
358-
><diddy<boolean> bananas="please"> : any
360+
><diddy<boolean> bananas="please"> <diddy/> : any
359361
>diddy : () => any
360362
>bananas : string
361363

362364
<diddy/>
363-
> : any
365+
><diddy/> : any
366+
>diddy : () => any
364367

365368
</div>;
369+
> : any
366370
>div : any
367371

368372
function noSelfcloseTypeArgAttrsTrailingTag() { }
@@ -508,13 +512,12 @@ var donkey = <div>
508512
>div : any
509513

510514
<diddy>
511-
><diddy> : any
515+
><diddy> Cranky Wrinkly Funky : any
512516
>diddy : () => any
513517

514518
Cranky Wrinkly Funky
515-
> : any
516-
517519
</div>;
520+
> : any
518521
>div : any
519522

520523
function noSelfcloseTrailingText() { }
@@ -526,14 +529,13 @@ var donkey = <div>
526529
>div : any
527530

528531
<diddy<boolean> bananas="please">
529-
><diddy<boolean> bananas="please"> : any
532+
><diddy<boolean> bananas="please"> Cranky Wrinkly Funky : any
530533
>diddy : () => any
531534
>bananas : string
532535

533536
Cranky Wrinkly Funky
534-
> : any
535-
536537
</div>;
538+
> : any
537539
>div : any
538540

539541
function noSelfcloseTypeArgAttrsTrailingText() { }

tests/cases/fourslash/autoCloseFragment.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
//// <>/*8*/</>
3939
////</div>;
4040

41+
// @Filename: /9.tsx
42+
////const x = <p>
43+
//// <>
44+
//// <>/*9*/
45+
//// </>
46+
////</p>
47+
4148
verify.jsxClosingTag({
4249
0: { newText: "</>" },
4350
1: undefined,
@@ -48,4 +55,5 @@ verify.jsxClosingTag({
4855
6: { newText: "</>" },
4956
7: { newText: "</>" },
5057
8: undefined,
58+
9: { newText: "</>" },
5159
});

tests/cases/fourslash/autoCloseTag.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
//// <div>/*8*/</div>
3939
////</div>;
4040

41+
// @Filename: /9.tsx
42+
////const x = <p>
43+
//// <div>
44+
//// <div>/*9*/
45+
//// </div>
46+
////</p>
47+
4148
verify.jsxClosingTag({
4249
0: { newText: "</div>" },
4350
1: undefined,
@@ -48,4 +55,5 @@ verify.jsxClosingTag({
4855
6: { newText: "</div>" },
4956
7: { newText: "</p>" },
5057
8: undefined,
58+
9: { newText: "</div>" },
5159
});

0 commit comments

Comments
 (0)