diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 343df39ad9cbc..5b283b7929b21 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -3720,6 +3720,9 @@ export function createScanner( // These initial values are special because the first line is: // firstNonWhitespace = 0 to indicate that we want leading whitespace, + // Build the text content excluding comments + let textContent = ""; + while (pos < end) { char = charCodeUnchecked(pos); if (char === CharacterCodes.openBrace) { @@ -3739,6 +3742,21 @@ export function createScanner( error(Diagnostics.Unexpected_token_Did_you_mean_or_rbrace, pos, 1); } + // Handle comments - skip /* ... */ style comments + if (char === CharacterCodes.slash && charCodeUnchecked(pos + 1) === CharacterCodes.asterisk) { + pos += 2; // Skip /* + // Find the end of the comment + while (pos < end) { + if (charCodeUnchecked(pos) === CharacterCodes.asterisk && charCodeUnchecked(pos + 1) === CharacterCodes.slash) { + pos += 2; // Skip */ + break; + } + pos++; + } + // Continue without adding comment content to textContent + continue; + } + // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces. // i.e (- : whitespace) //
---- @@ -3754,13 +3772,16 @@ export function createScanner( break; } else if (!isWhiteSpaceLike(char)) { - firstNonWhitespace = pos; + if (firstNonWhitespace === 0) { + firstNonWhitespace = textContent.length; + } } + textContent += String.fromCharCode(char); pos++; } - tokenValue = text.substring(fullStartPos, pos); + tokenValue = textContent; return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText; } diff --git a/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).js b/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).js new file mode 100644 index 0000000000000..e28a8263a5c52 --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).js @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/jsxCommentDuplication.tsx] //// + +//// [jsxCommentDuplication.tsx] +function App() {} +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; + +//// [jsxCommentDuplication.jsx] +function App() { } +var jsx = /* no */{/* 1 */123 /* 2 */} /* no */; diff --git a/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).symbols b/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).symbols new file mode 100644 index 0000000000000..328bd5542845d --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).symbols @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/jsxCommentDuplication.tsx] //// + +=== jsxCommentDuplication.tsx === +function App() {} +>App : Symbol(App, Decl(jsxCommentDuplication.tsx, 0, 0)) + +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; +>jsx : Symbol(jsx, Decl(jsxCommentDuplication.tsx, 1, 5)) +>App : Symbol(App, Decl(jsxCommentDuplication.tsx, 0, 0)) +>App : Symbol(App, Decl(jsxCommentDuplication.tsx, 0, 0)) + diff --git a/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).types b/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).types new file mode 100644 index 0000000000000..5a4fbfe5078c4 --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=preserve).types @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/jsxCommentDuplication.tsx] //// + +=== jsxCommentDuplication.tsx === +function App() {} +>App : () => void +> : ^^^^^^^^^^ + +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; +>jsx : error +>/* no */{/* 1 */ 123 /* 2 */}/* no */ : error +>App : () => void +> : ^^^^^^^^^^ +>123 : 123 +> : ^^^ +>App : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/jsxCommentDuplication(jsx=react).errors.txt b/tests/baselines/reference/jsxCommentDuplication(jsx=react).errors.txt new file mode 100644 index 0000000000000..5902bb8f12f9e --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=react).errors.txt @@ -0,0 +1,8 @@ +jsxCommentDuplication.tsx(2,14): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. + + +==== jsxCommentDuplication.tsx (1 errors) ==== + function App() {} + const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; + ~~~ +!!! 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/jsxCommentDuplication(jsx=react).js b/tests/baselines/reference/jsxCommentDuplication(jsx=react).js new file mode 100644 index 0000000000000..c2706df39d2cf --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=react).js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/jsxCommentDuplication.tsx] //// + +//// [jsxCommentDuplication.tsx] +function App() {} +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; + +//// [jsxCommentDuplication.js] +function App() { } +var jsx = React.createElement(App, null, + "", /* 1 */ + 123 /* 2 */, + ""); diff --git a/tests/baselines/reference/jsxCommentDuplication(jsx=react).symbols b/tests/baselines/reference/jsxCommentDuplication(jsx=react).symbols new file mode 100644 index 0000000000000..328bd5542845d --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=react).symbols @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/jsxCommentDuplication.tsx] //// + +=== jsxCommentDuplication.tsx === +function App() {} +>App : Symbol(App, Decl(jsxCommentDuplication.tsx, 0, 0)) + +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; +>jsx : Symbol(jsx, Decl(jsxCommentDuplication.tsx, 1, 5)) +>App : Symbol(App, Decl(jsxCommentDuplication.tsx, 0, 0)) +>App : Symbol(App, Decl(jsxCommentDuplication.tsx, 0, 0)) + diff --git a/tests/baselines/reference/jsxCommentDuplication(jsx=react).types b/tests/baselines/reference/jsxCommentDuplication(jsx=react).types new file mode 100644 index 0000000000000..d0333134fdd1c --- /dev/null +++ b/tests/baselines/reference/jsxCommentDuplication(jsx=react).types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/jsxCommentDuplication.tsx] //// + +=== jsxCommentDuplication.tsx === +function App() {} +>App : () => void +> : ^^^^^^^^^^ + +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; +>jsx : any +> : ^^^ +>/* no */{/* 1 */ 123 /* 2 */}/* no */ : any +> : ^^^ +>App : () => void +> : ^^^^^^^^^^ +>123 : 123 +> : ^^^ +>App : () => void +> : ^^^^^^^^^^ + diff --git a/tests/cases/compiler/jsxCommentDuplication.tsx b/tests/cases/compiler/jsxCommentDuplication.tsx new file mode 100644 index 0000000000000..217e4e29ebd0e --- /dev/null +++ b/tests/cases/compiler/jsxCommentDuplication.tsx @@ -0,0 +1,5 @@ +// @jsx: react,preserve +// @module: commonjs + +function App() {} +const jsx = /* no */{/* 1 */ 123 /* 2 */}/* no */; \ No newline at end of file