mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 19:59:23 -05:00
Don’t create missing nodes for identifiers that would be valid in a newer script target (#42520)
* Add test * Don’t create missing nodes for identifiers that would be valid in a newer script target * Add to test * Remove unnecessary assignment
This commit is contained in:
@@ -1637,8 +1637,8 @@ namespace ts {
|
||||
// with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for
|
||||
// each identifier in order to reduce memory consumption.
|
||||
function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier {
|
||||
identifierCount++;
|
||||
if (isIdentifier) {
|
||||
identifierCount++;
|
||||
const pos = getNodePos();
|
||||
// Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
|
||||
const originalKeywordKind = token();
|
||||
@@ -1652,6 +1652,12 @@ namespace ts {
|
||||
return createIdentifier(/*isIdentifier*/ true);
|
||||
}
|
||||
|
||||
if (token() === SyntaxKind.Unknown && scanner.tryScan(() => scanner.reScanInvalidIdentifier() === SyntaxKind.Identifier)) {
|
||||
// Scanner has already recorded an 'Invalid character' error, so no need to add another from the parser.
|
||||
return createIdentifier(/*isIdentifier*/ true);
|
||||
}
|
||||
|
||||
identifierCount++;
|
||||
// Only for end of file because the error gets reported incorrectly on embedded script tags.
|
||||
const reportAtCurrentPosition = token() === SyntaxKind.EndOfFileToken;
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace ts {
|
||||
reScanJsxToken(): JsxTokenSyntaxKind;
|
||||
reScanLessThanToken(): SyntaxKind;
|
||||
reScanQuestionToken(): SyntaxKind;
|
||||
reScanInvalidIdentifier(): SyntaxKind;
|
||||
scanJsxToken(): JsxTokenSyntaxKind;
|
||||
scanJsDocToken(): JSDocSyntaxKind;
|
||||
scan(): SyntaxKind;
|
||||
@@ -966,6 +967,7 @@ namespace ts {
|
||||
reScanJsxToken,
|
||||
reScanLessThanToken,
|
||||
reScanQuestionToken,
|
||||
reScanInvalidIdentifier,
|
||||
scanJsxToken,
|
||||
scanJsDocToken,
|
||||
scan,
|
||||
@@ -2041,14 +2043,9 @@ namespace ts {
|
||||
}
|
||||
return token = SyntaxKind.PrivateIdentifier;
|
||||
default:
|
||||
if (isIdentifierStart(ch, languageVersion)) {
|
||||
pos += charSize(ch);
|
||||
while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion)) pos += charSize(ch);
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
if (ch === CharacterCodes.backslash) {
|
||||
tokenValue += scanIdentifierParts();
|
||||
}
|
||||
return token = getIdentifierToken();
|
||||
const identifierKind = scanIdentifier(ch, languageVersion);
|
||||
if (identifierKind) {
|
||||
return token = identifierKind;
|
||||
}
|
||||
else if (isWhiteSpaceSingleLine(ch)) {
|
||||
pos += charSize(ch);
|
||||
@@ -2066,6 +2063,32 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function reScanInvalidIdentifier(): SyntaxKind {
|
||||
Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'.");
|
||||
pos = tokenPos = startPos;
|
||||
tokenFlags = 0;
|
||||
const ch = codePointAt(text, pos);
|
||||
const identifierKind = scanIdentifier(ch, ScriptTarget.ESNext);
|
||||
if (identifierKind) {
|
||||
return token = identifierKind;
|
||||
}
|
||||
pos += charSize(ch);
|
||||
return token; // Still `SyntaKind.Unknown`
|
||||
}
|
||||
|
||||
function scanIdentifier(startCharacter: number, languageVersion: ScriptTarget) {
|
||||
let ch = startCharacter;
|
||||
if (isIdentifierStart(ch, languageVersion)) {
|
||||
pos += charSize(ch);
|
||||
while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion)) pos += charSize(ch);
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
if (ch === CharacterCodes.backslash) {
|
||||
tokenValue += scanIdentifierParts();
|
||||
}
|
||||
return getIdentifierToken();
|
||||
}
|
||||
}
|
||||
|
||||
function reScanGreaterToken(): SyntaxKind {
|
||||
if (token === SyntaxKind.GreaterThanToken) {
|
||||
if (text.charCodeAt(pos) === CharacterCodes.greaterThan) {
|
||||
|
||||
@@ -1453,9 +1453,9 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public baselineRename(marker: string, options: FourSlashInterface.RenameOptions) {
|
||||
const position = this.getMarkerByName(marker).position;
|
||||
const { fileName, position } = this.getMarkerByName(marker);
|
||||
const locations = this.languageService.findRenameLocations(
|
||||
this.activeFile.fileName,
|
||||
fileName,
|
||||
position,
|
||||
options.findInStrings ?? false,
|
||||
options.findInComments ?? false,
|
||||
|
||||
Reference in New Issue
Block a user