mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Error on replacement character only in top-level scanning (#58227)
This commit is contained in:
+4
-12
@@ -1768,18 +1768,6 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
|
||||
|
||||
const ch = codePointAt(text, pos);
|
||||
if (pos === 0) {
|
||||
// If a file isn't valid text at all, it will usually be apparent
|
||||
// in the first few characters because UTF-8 decode will fail and produce U+FFFD.
|
||||
// If that happens, just issue one error and refuse to try to scan further;
|
||||
// this is likely a binary file that cannot be parsed.
|
||||
//
|
||||
// It's safe to slice the text; U+FFFD can only be produced by an invalid decode,
|
||||
// so even if we cut a surrogate pair in half, they wouldn't be U+FFFD.
|
||||
if (text.slice(0, 256).includes("\uFFFD")) {
|
||||
error(Diagnostics.File_appears_to_be_binary);
|
||||
pos = end;
|
||||
return token = SyntaxKind.NonTextFileMarkerTrivia;
|
||||
}
|
||||
// Special handling for shebang
|
||||
if (ch === CharacterCodes.hash && isShebangTrivia(text, pos)) {
|
||||
pos = scanShebangTrivia(text, pos);
|
||||
@@ -2242,6 +2230,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
|
||||
error(Diagnostics.Invalid_character, pos++, charSize(ch));
|
||||
}
|
||||
return token = SyntaxKind.PrivateIdentifier;
|
||||
case CharacterCodes.replacementCharacter:
|
||||
error(Diagnostics.File_appears_to_be_binary, 0, 0);
|
||||
pos = end;
|
||||
return token = SyntaxKind.NonTextFileMarkerTrivia;
|
||||
default:
|
||||
const identifierKind = scanIdentifier(ch, languageVersion);
|
||||
if (identifierKind) {
|
||||
|
||||
@@ -7612,6 +7612,9 @@ export const enum CharacterCodes {
|
||||
mathematicalSpace = 0x205F,
|
||||
ogham = 0x1680,
|
||||
|
||||
// Unicode replacement character produced when a byte sequence is invalid
|
||||
replacementCharacter = 0xFFFD,
|
||||
|
||||
_ = 0x5F,
|
||||
$ = 0x24,
|
||||
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
TransportStream.ts(1,1): error TS1490: File appears to be binary.
|
||||
TransportStream.ts(1,1): error TS1434: Unexpected keyword or identifier.
|
||||
TransportStream.ts(1,1): error TS2304: Cannot find name 'G'.
|
||||
TransportStream.ts(1,3): error TS1127: Invalid character.
|
||||
TransportStream.ts(1,4): error TS1128: Declaration or statement expected.
|
||||
|
||||
|
||||
==== TransportStream.ts (1 errors) ====
|
||||
==== TransportStream.ts (5 errors) ====
|
||||
G@�G@�G@�
|
||||
|
||||
!!! error TS1490: File appears to be binary.
|
||||
!!! error TS1490: File appears to be binary.
|
||||
~
|
||||
!!! error TS1434: Unexpected keyword or identifier.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'G'.
|
||||
~
|
||||
!!! error TS1127: Invalid character.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
@@ -4,3 +4,4 @@
|
||||
G@�G@�G@�
|
||||
|
||||
//// [TransportStream.js]
|
||||
G;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
//// [tests/cases/compiler/TransportStream.ts] ////
|
||||
|
||||
=== TransportStream.ts ===
|
||||
|
||||
G@�G@�G@�
|
||||
>G : any
|
||||
> : ^^^
|
||||
> : any
|
||||
> : ^^^
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/parseReplacementCharacter.ts] ////
|
||||
|
||||
//// [parseReplacementCharacter.ts]
|
||||
"oops �� oops";
|
||||
'oops �� oops';
|
||||
`oops �� oops`;
|
||||
`${"oops �� oops"}`;
|
||||
// oops �� oops
|
||||
/* oops �� oops */
|
||||
/** oops �� oops */
|
||||
|
||||
//// [parseReplacementCharacter.js]
|
||||
"oops �� oops";
|
||||
'oops �� oops';
|
||||
"oops \uFFFD\uFFFD oops";
|
||||
"".concat("oops �� oops");
|
||||
@@ -0,0 +1,11 @@
|
||||
//// [tests/cases/compiler/parseReplacementCharacter.ts] ////
|
||||
|
||||
=== parseReplacementCharacter.ts ===
|
||||
|
||||
"oops �� oops";
|
||||
'oops �� oops';
|
||||
`oops �� oops`;
|
||||
`${"oops �� oops"}`;
|
||||
// oops �� oops
|
||||
/* oops �� oops */
|
||||
/** oops �� oops */
|
||||
@@ -0,0 +1,24 @@
|
||||
//// [tests/cases/compiler/parseReplacementCharacter.ts] ////
|
||||
|
||||
=== parseReplacementCharacter.ts ===
|
||||
"oops �� oops";
|
||||
>"oops �� oops" : "oops �� oops"
|
||||
> : ^^^^^^^^^^^^^^
|
||||
|
||||
'oops �� oops';
|
||||
>'oops �� oops' : "oops �� oops"
|
||||
> : ^^^^^^^^^^^^^^
|
||||
|
||||
`oops �� oops`;
|
||||
>`oops �� oops` : "oops �� oops"
|
||||
> : ^^^^^^^^^^^^^^
|
||||
|
||||
`${"oops �� oops"}`;
|
||||
>`${"oops �� oops"}` : "oops �� oops"
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>"oops �� oops" : "oops �� oops"
|
||||
> : ^^^^^^^^^^^^^^
|
||||
|
||||
// oops �� oops
|
||||
/* oops �� oops */
|
||||
/** oops �� oops */
|
||||
@@ -0,0 +1,7 @@
|
||||
"oops �� oops";
|
||||
'oops �� oops';
|
||||
`oops �� oops`;
|
||||
`${"oops �� oops"}`;
|
||||
// oops �� oops
|
||||
/* oops �� oops */
|
||||
/** oops �� oops */
|
||||
Reference in New Issue
Block a user