diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index c60fd92787275..23ed944b32bf6 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -5815,14 +5815,36 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
}
+ function shouldSkipJsxLeadingComments(node: Node) {
+ switch (node.kind) {
+ case SyntaxKind.JsxText:
+ case SyntaxKind.JsxExpression:
+ case SyntaxKind.JsxClosingElement:
+ case SyntaxKind.JsxClosingFragment:
+ return true;
+ }
+ return false;
+ }
+
+ function shouldSkipJsxTrailingComments(node: Node) {
+ switch (node.kind) {
+ case SyntaxKind.JsxText:
+ case SyntaxKind.JsxExpression:
+ case SyntaxKind.JsxOpeningElement:
+ case SyntaxKind.JsxOpeningFragment:
+ return true;
+ }
+ return false;
+ }
+
function emitLeadingCommentsOfNode(node: Node, emitFlags: EmitFlags, pos: number, end: number) {
enterComment();
hasWrittenComment = false;
// We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
// It is expensive to walk entire tree just to set one kind of node to have no comments.
- const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0 || node.kind === SyntaxKind.JsxText;
- const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText;
+ const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments !== 0) || shouldSkipJsxLeadingComments(node);
+ const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || shouldSkipJsxTrailingComments(node);
// Save current container state on the stack.
if ((pos > 0 || end > 0) && pos !== end) {
@@ -5854,7 +5876,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
function emitTrailingCommentsOfNode(node: Node, emitFlags: EmitFlags, pos: number, end: number, savedContainerPos: number, savedContainerEnd: number, savedDeclarationListContainerEnd: number) {
enterComment();
- const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText;
+ const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || shouldSkipJsxTrailingComments(node);
forEach(getSyntheticTrailingComments(node), emitTrailingSynthesizedComment);
if ((pos > 0 || end > 0) && pos !== end) {
// Restore previous container state.
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).js b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).js
new file mode 100644
index 0000000000000..520b4359cc3fb
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).js
@@ -0,0 +1,18 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+//// [file.tsx]
+let x = "hi";
+const eg1 =
{x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
+
+//// [file.jsx]
+var x = "hi";
+var eg1 = {x}/*mid*/{x}
;
+var eg2 = /*pre*/{x}/*post*/
;
+var eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+var eg4 = /*pre*/*post*/
;
+var eg5 = /*pre*/{/*keep me*/}/*post*/
;
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).symbols b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).symbols
new file mode 100644
index 0000000000000..7325ba45dfad6
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).symbols
@@ -0,0 +1,26 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : Symbol(eg1, Decl(file.tsx, 1, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : Symbol(eg3, Decl(file.tsx, 3, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).types b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).types
new file mode 100644
index 0000000000000..d00fca53c49cb
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=false).types
@@ -0,0 +1,62 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : string
+> : ^^^^^^
+>"hi" : "hi"
+> : ^^^^
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : error
+>{x}/*mid*/{x}
: error
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : error
+>/*pre*/{x}/*post*/
: error
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : error
+>/*pre*/{x}/*mid*/{x}/*post*/
: error
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : error
+>/*pre*/*post*/
: error
+>div : any
+> : ^^^
+> : error
+>span : any
+> : ^^^
+>div : any
+> : ^^^
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : error
+>/*pre*/{/*keep me*/}/*post*/
: error
+>div : any
+> : ^^^
+>div : any
+> : ^^^
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).js b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).js
new file mode 100644
index 0000000000000..17e3ae2cfff51
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).js
@@ -0,0 +1,18 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+//// [file.tsx]
+let x = "hi";
+const eg1 = {x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
+
+//// [file.jsx]
+var x = "hi";
+var eg1 = {x}/*mid*/{x}
;
+var eg2 = /*pre*/{x}/*post*/
;
+var eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+var eg4 = /*pre*/*post*/
;
+var eg5 = /*pre*//*post*/
;
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).symbols b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).symbols
new file mode 100644
index 0000000000000..7325ba45dfad6
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).symbols
@@ -0,0 +1,26 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : Symbol(eg1, Decl(file.tsx, 1, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : Symbol(eg3, Decl(file.tsx, 3, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).types b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).types
new file mode 100644
index 0000000000000..d00fca53c49cb
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=preserve,removecomments=true).types
@@ -0,0 +1,62 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : string
+> : ^^^^^^
+>"hi" : "hi"
+> : ^^^^
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : error
+>{x}/*mid*/{x}
: error
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : error
+>/*pre*/{x}/*post*/
: error
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : error
+>/*pre*/{x}/*mid*/{x}/*post*/
: error
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : error
+>/*pre*/*post*/
: error
+>div : any
+> : ^^^
+> : error
+>span : any
+> : ^^^
+>div : any
+> : ^^^
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : error
+>/*pre*/{/*keep me*/}/*post*/
: error
+>div : any
+> : ^^^
+>div : any
+> : ^^^
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).errors.txt b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).errors.txt
new file mode 100644
index 0000000000000..c189f3bb6b677
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).errors.txt
@@ -0,0 +1,28 @@
+file.tsx(2,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(3,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(4,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(5,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(5,26): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(6,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+
+
+==== file.tsx (6 errors) ====
+ let x = "hi";
+ const eg1 = {x}/*mid*/{x}
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg2 = /*pre*/{x}/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg4 = /*pre*/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ ~~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).js b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).js
new file mode 100644
index 0000000000000..de11d1372afcc
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).js
@@ -0,0 +1,34 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+//// [file.tsx]
+let x = "hi";
+const eg1 = {x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
+
+//// [file.js]
+var x = "hi";
+var eg1 = React.createElement("div", null,
+ x,
+ "/*mid*/",
+ x);
+var eg2 = React.createElement("div", null,
+ "/*pre*/",
+ x,
+ "/*post*/");
+var eg3 = React.createElement("div", null,
+ "/*pre*/",
+ x,
+ "/*mid*/",
+ x,
+ "/*post*/");
+var eg4 = React.createElement("div", null,
+ "/*pre*/",
+ React.createElement("span", null),
+ "*post*/");
+var eg5 = React.createElement("div", null,
+ "/*pre*/",
+ "/*post*/");
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).symbols b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).symbols
new file mode 100644
index 0000000000000..7325ba45dfad6
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).symbols
@@ -0,0 +1,26 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : Symbol(eg1, Decl(file.tsx, 1, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : Symbol(eg3, Decl(file.tsx, 3, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).types b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).types
new file mode 100644
index 0000000000000..8130eb018ca5c
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=false).types
@@ -0,0 +1,73 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : string
+> : ^^^^^^
+>"hi" : "hi"
+> : ^^^^
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : any
+> : ^^^
+>{x}/*mid*/{x}
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : any
+> : ^^^
+>/*pre*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : any
+> : ^^^
+>/*pre*/{x}/*mid*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : any
+> : ^^^
+>/*pre*/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+> : any
+> : ^^^
+>span : any
+> : ^^^
+>div : any
+> : ^^^
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : any
+> : ^^^
+>/*pre*/{/*keep me*/}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>div : any
+> : ^^^
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).errors.txt b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).errors.txt
new file mode 100644
index 0000000000000..c189f3bb6b677
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).errors.txt
@@ -0,0 +1,28 @@
+file.tsx(2,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(3,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(4,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(5,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(5,26): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+file.tsx(6,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+
+
+==== file.tsx (6 errors) ====
+ let x = "hi";
+ const eg1 = {x}/*mid*/{x}
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg2 = /*pre*/{x}/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg4 = /*pre*/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ ~~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+ const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+ ~~~
+!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).js b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).js
new file mode 100644
index 0000000000000..de11d1372afcc
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).js
@@ -0,0 +1,34 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+//// [file.tsx]
+let x = "hi";
+const eg1 = {x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
+
+//// [file.js]
+var x = "hi";
+var eg1 = React.createElement("div", null,
+ x,
+ "/*mid*/",
+ x);
+var eg2 = React.createElement("div", null,
+ "/*pre*/",
+ x,
+ "/*post*/");
+var eg3 = React.createElement("div", null,
+ "/*pre*/",
+ x,
+ "/*mid*/",
+ x,
+ "/*post*/");
+var eg4 = React.createElement("div", null,
+ "/*pre*/",
+ React.createElement("span", null),
+ "*post*/");
+var eg5 = React.createElement("div", null,
+ "/*pre*/",
+ "/*post*/");
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).symbols b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).symbols
new file mode 100644
index 0000000000000..7325ba45dfad6
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).symbols
@@ -0,0 +1,26 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : Symbol(eg1, Decl(file.tsx, 1, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : Symbol(eg3, Decl(file.tsx, 3, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).types b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).types
new file mode 100644
index 0000000000000..8130eb018ca5c
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react,removecomments=true).types
@@ -0,0 +1,73 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : string
+> : ^^^^^^
+>"hi" : "hi"
+> : ^^^^
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : any
+> : ^^^
+>{x}/*mid*/{x}
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : any
+> : ^^^
+>/*pre*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : any
+> : ^^^
+>/*pre*/{x}/*mid*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : any
+> : ^^^
+>/*pre*/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+> : any
+> : ^^^
+>span : any
+> : ^^^
+>div : any
+> : ^^^
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : any
+> : ^^^
+>/*pre*/{/*keep me*/}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>div : any
+> : ^^^
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).errors.txt b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).errors.txt
new file mode 100644
index 0000000000000..e2d8932d8e3a8
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).errors.txt
@@ -0,0 +1,13 @@
+file.tsx(2,13): error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
+
+
+==== file.tsx (1 errors) ====
+ let x = "hi";
+ const eg1 = {x}/*mid*/{x}
;
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
+ const eg2 = /*pre*/{x}/*post*/
;
+ const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+ const eg4 = /*pre*/*post*/
;
+ const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
\ No newline at end of file
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).js b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).js
new file mode 100644
index 0000000000000..752ba7c71bb11
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).js
@@ -0,0 +1,21 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+//// [file.tsx]
+let x = "hi";
+const eg1 = {x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
+
+//// [file.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var jsx_runtime_1 = require("react/jsx-runtime");
+var x = "hi";
+var eg1 = (0, jsx_runtime_1.jsxs)("div", { children: [x, "/*mid*/", x] });
+var eg2 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", x, "/*post*/"] });
+var eg3 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", x, "/*mid*/", x, "/*post*/"] });
+var eg4 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", (0, jsx_runtime_1.jsx)("span", {}), "*post*/"] });
+var eg5 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", "/*post*/"] });
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).symbols b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).symbols
new file mode 100644
index 0000000000000..7325ba45dfad6
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).symbols
@@ -0,0 +1,26 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : Symbol(eg1, Decl(file.tsx, 1, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : Symbol(eg3, Decl(file.tsx, 3, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).types b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).types
new file mode 100644
index 0000000000000..8130eb018ca5c
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=false).types
@@ -0,0 +1,73 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : string
+> : ^^^^^^
+>"hi" : "hi"
+> : ^^^^
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : any
+> : ^^^
+>{x}/*mid*/{x}
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : any
+> : ^^^
+>/*pre*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : any
+> : ^^^
+>/*pre*/{x}/*mid*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : any
+> : ^^^
+>/*pre*/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+> : any
+> : ^^^
+>span : any
+> : ^^^
+>div : any
+> : ^^^
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : any
+> : ^^^
+>/*pre*/{/*keep me*/}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>div : any
+> : ^^^
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).errors.txt b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).errors.txt
new file mode 100644
index 0000000000000..e2d8932d8e3a8
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).errors.txt
@@ -0,0 +1,13 @@
+file.tsx(2,13): error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
+
+
+==== file.tsx (1 errors) ====
+ let x = "hi";
+ const eg1 = {x}/*mid*/{x}
;
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed.
+ const eg2 = /*pre*/{x}/*post*/
;
+ const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+ const eg4 = /*pre*/*post*/
;
+ const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
\ No newline at end of file
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).js b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).js
new file mode 100644
index 0000000000000..752ba7c71bb11
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).js
@@ -0,0 +1,21 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+//// [file.tsx]
+let x = "hi";
+const eg1 = {x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+
+
+//// [file.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var jsx_runtime_1 = require("react/jsx-runtime");
+var x = "hi";
+var eg1 = (0, jsx_runtime_1.jsxs)("div", { children: [x, "/*mid*/", x] });
+var eg2 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", x, "/*post*/"] });
+var eg3 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", x, "/*mid*/", x, "/*post*/"] });
+var eg4 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", (0, jsx_runtime_1.jsx)("span", {}), "*post*/"] });
+var eg5 = (0, jsx_runtime_1.jsxs)("div", { children: ["/*pre*/", "/*post*/"] });
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).symbols b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).symbols
new file mode 100644
index 0000000000000..7325ba45dfad6
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).symbols
@@ -0,0 +1,26 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : Symbol(eg1, Decl(file.tsx, 1, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : Symbol(eg3, Decl(file.tsx, 3, 5))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+>x : Symbol(x, Decl(file.tsx, 0, 3))
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))
+
diff --git a/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).types b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).types
new file mode 100644
index 0000000000000..8130eb018ca5c
--- /dev/null
+++ b/tests/baselines/reference/jsxCommentEmit(jsx=react-jsx,removecomments=true).types
@@ -0,0 +1,73 @@
+//// [tests/cases/compiler/jsxCommentEmit.ts] ////
+
+=== file.tsx ===
+let x = "hi";
+>x : string
+> : ^^^^^^
+>"hi" : "hi"
+> : ^^^^
+
+const eg1 = {x}/*mid*/{x}
;
+>eg1 : any
+> : ^^^
+>{x}/*mid*/{x}
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg2 = /*pre*/{x}/*post*/
;
+>eg2 : any
+> : ^^^
+>/*pre*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+>eg3 : any
+> : ^^^
+>/*pre*/{x}/*mid*/{x}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>x : string
+> : ^^^^^^
+>x : string
+> : ^^^^^^
+>div : any
+> : ^^^
+
+const eg4 = /*pre*/*post*/
;
+>eg4 : any
+> : ^^^
+>/*pre*/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+> : any
+> : ^^^
+>span : any
+> : ^^^
+>div : any
+> : ^^^
+
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;
+>eg5 : any
+> : ^^^
+>/*pre*/{/*keep me*/}/*post*/
: any
+> : ^^^
+>div : any
+> : ^^^
+>div : any
+> : ^^^
+
diff --git a/tests/cases/compiler/jsxCommentEmit.ts b/tests/cases/compiler/jsxCommentEmit.ts
new file mode 100644
index 0000000000000..6be6e9bce4083
--- /dev/null
+++ b/tests/cases/compiler/jsxCommentEmit.ts
@@ -0,0 +1,10 @@
+// @removeComments: true, false
+// @jsx: react, react-jsx, preserve
+
+// @filename: file.tsx
+let x = "hi";
+const eg1 = {x}/*mid*/{x}
;
+const eg2 = /*pre*/{x}/*post*/
;
+const eg3 = /*pre*/{x}/*mid*/{x}/*post*/
;
+const eg4 = /*pre*/*post*/
;
+const eg5 = /*pre*/{/*keep me*/}/*post*/
;