Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5815,14 +5815,36 @@
}
}

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);

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / self-check

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / self-check

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / typecheck

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / typecheck

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / smoke

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / smoke

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 20 on ubuntu-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 20 on ubuntu-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 22 on ubuntu-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 22 on ubuntu-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 18 on ubuntu-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 18 on ubuntu-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node lts/* on ubuntu-latest with --no-bundle

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node lts/* on ubuntu-latest with --no-bundle

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 16 on ubuntu-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 16 on ubuntu-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 14 on ubuntu-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 14 on ubuntu-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 20 on windows-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 20 on windows-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 18 on windows-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 18 on windows-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 22 on windows-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 22 on windows-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 14 on windows-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 14 on windows-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 16 on windows-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 16 on windows-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / browser-integration

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / browser-integration

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / coverage

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / coverage

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 20 on macos-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 20 on macos-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 22 on macos-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 22 on macos-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 16 on macos-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 16 on macos-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 18 on macos-latest

This comparison appears to be unintentional because the types 'EmitFlags.NoLeadingComments' and '0' have no overlap.

Check failure on line 5846 in src/compiler/emitter.ts

View workflow job for this annotation

GitHub Actions / Test Node 18 on macos-latest

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || shouldSkipJsxTrailingComments(node);

// Save current container state on the stack.
if ((pos > 0 || end > 0) && pos !== end) {
Expand Down Expand Up @@ -5854,7 +5876,7 @@

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.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

//// [file.tsx]
let x = "hi";
const eg1 = <div>{x}/*mid*/{x}</div>;
const eg2 = <div>/*pre*/{x}/*post*/</div>;
const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
const eg4 = <div>/*pre*/<span/>*post*/</div>;
const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;


//// [file.jsx]
var x = "hi";
var eg1 = <div>{x}/*mid*/{x}</div>;
var eg2 = <div>/*pre*/{x}/*post*/</div>;
var eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
var eg4 = <div>/*pre*/<span />*post*/</div>;
var eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

=== file.tsx ===
let x = "hi";
>x : Symbol(x, Decl(file.tsx, 0, 3))

const eg1 = <div>{x}/*mid*/{x}</div>;
>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 = <div>/*pre*/{x}/*post*/</div>;
>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
>x : Symbol(x, Decl(file.tsx, 0, 3))

const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
>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 = <div>/*pre*/<span/>*post*/</div>;
>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))

const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

=== file.tsx ===
let x = "hi";
>x : string
> : ^^^^^^
>"hi" : "hi"
> : ^^^^

const eg1 = <div>{x}/*mid*/{x}</div>;
>eg1 : error
><div>{x}/*mid*/{x}</div> : error
>div : any
> : ^^^
>x : string
> : ^^^^^^
>x : string
> : ^^^^^^
>div : any
> : ^^^

const eg2 = <div>/*pre*/{x}/*post*/</div>;
>eg2 : error
><div>/*pre*/{x}/*post*/</div> : error
>div : any
> : ^^^
>x : string
> : ^^^^^^
>div : any
> : ^^^

const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
>eg3 : error
><div>/*pre*/{x}/*mid*/{x}/*post*/</div> : error
>div : any
> : ^^^
>x : string
> : ^^^^^^
>x : string
> : ^^^^^^
>div : any
> : ^^^

const eg4 = <div>/*pre*/<span/>*post*/</div>;
>eg4 : error
><div>/*pre*/<span/>*post*/</div> : error
>div : any
> : ^^^
><span/> : error
>span : any
> : ^^^
>div : any
> : ^^^

const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
>eg5 : error
><div>/*pre*/{/*keep me*/}/*post*/</div> : error
>div : any
> : ^^^
>div : any
> : ^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

//// [file.tsx]
let x = "hi";
const eg1 = <div>{x}/*mid*/{x}</div>;
const eg2 = <div>/*pre*/{x}/*post*/</div>;
const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
const eg4 = <div>/*pre*/<span/>*post*/</div>;
const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;


//// [file.jsx]
var x = "hi";
var eg1 = <div>{x}/*mid*/{x}</div>;
var eg2 = <div>/*pre*/{x}/*post*/</div>;
var eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
var eg4 = <div>/*pre*/<span />*post*/</div>;
var eg5 = <div>/*pre*//*post*/</div>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

=== file.tsx ===
let x = "hi";
>x : Symbol(x, Decl(file.tsx, 0, 3))

const eg1 = <div>{x}/*mid*/{x}</div>;
>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 = <div>/*pre*/{x}/*post*/</div>;
>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
>x : Symbol(x, Decl(file.tsx, 0, 3))

const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
>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 = <div>/*pre*/<span/>*post*/</div>;
>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))

const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

=== file.tsx ===
let x = "hi";
>x : string
> : ^^^^^^
>"hi" : "hi"
> : ^^^^

const eg1 = <div>{x}/*mid*/{x}</div>;
>eg1 : error
><div>{x}/*mid*/{x}</div> : error
>div : any
> : ^^^
>x : string
> : ^^^^^^
>x : string
> : ^^^^^^
>div : any
> : ^^^

const eg2 = <div>/*pre*/{x}/*post*/</div>;
>eg2 : error
><div>/*pre*/{x}/*post*/</div> : error
>div : any
> : ^^^
>x : string
> : ^^^^^^
>div : any
> : ^^^

const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
>eg3 : error
><div>/*pre*/{x}/*mid*/{x}/*post*/</div> : error
>div : any
> : ^^^
>x : string
> : ^^^^^^
>x : string
> : ^^^^^^
>div : any
> : ^^^

const eg4 = <div>/*pre*/<span/>*post*/</div>;
>eg4 : error
><div>/*pre*/<span/>*post*/</div> : error
>div : any
> : ^^^
><span/> : error
>span : any
> : ^^^
>div : any
> : ^^^

const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
>eg5 : error
><div>/*pre*/{/*keep me*/}/*post*/</div> : error
>div : any
> : ^^^
>div : any
> : ^^^

Original file line number Diff line number Diff line change
@@ -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 = <div>{x}/*mid*/{x}</div>;
~~~
!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
const eg2 = <div>/*pre*/{x}/*post*/</div>;
~~~
!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
~~~
!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.
const eg4 = <div>/*pre*/<span/>*post*/</div>;
~~~
!!! 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 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
~~~
!!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

//// [file.tsx]
let x = "hi";
const eg1 = <div>{x}/*mid*/{x}</div>;
const eg2 = <div>/*pre*/{x}/*post*/</div>;
const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
const eg4 = <div>/*pre*/<span/>*post*/</div>;
const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;


//// [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*/");
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/jsxCommentEmit.ts] ////

=== file.tsx ===
let x = "hi";
>x : Symbol(x, Decl(file.tsx, 0, 3))

const eg1 = <div>{x}/*mid*/{x}</div>;
>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 = <div>/*pre*/{x}/*post*/</div>;
>eg2 : Symbol(eg2, Decl(file.tsx, 2, 5))
>x : Symbol(x, Decl(file.tsx, 0, 3))

const eg3 = <div>/*pre*/{x}/*mid*/{x}/*post*/</div>;
>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 = <div>/*pre*/<span/>*post*/</div>;
>eg4 : Symbol(eg4, Decl(file.tsx, 4, 5))

const eg5 = <div>/*pre*/{/*keep me*/}/*post*/</div>;
>eg5 : Symbol(eg5, Decl(file.tsx, 5, 5))

Loading
Loading