mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Use a single scanner for all parsing tasks.
This commit is contained in:
parent
96995e705a
commit
61951e5d94
@ -1,6 +1,5 @@
|
||||
// <auto-generated />
|
||||
/// <reference path="types.ts" />
|
||||
/* @internal */
|
||||
module ts {
|
||||
export var Diagnostics = {
|
||||
Unterminated_string_literal: { code: 1002, category: DiagnosticCategory.Error, key: "Unterminated string literal." },
|
||||
|
||||
@ -1006,6 +1006,10 @@ module ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Share a single scanner across all calls to parse a source file. This helps speed things
|
||||
// up by avoiding the cost of creating/compiling scanners over and over again.
|
||||
let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ true);
|
||||
|
||||
function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: SyntaxCursor, setParentNodes = false): SourceFile {
|
||||
const disallowInAndDecoratorContext = ParserContextFlags.DisallowIn | ParserContextFlags.Decorator;
|
||||
|
||||
@ -1105,7 +1109,10 @@ module ts {
|
||||
let parseErrorBeforeNextFinishedNode: boolean = false;
|
||||
|
||||
// Create and prime the scanner before parsing the source elements.
|
||||
let scanner = createScanner(languageVersion, /*skipTrivia*/ true, sourceText, scanError);
|
||||
|
||||
scanner.setText(sourceText);
|
||||
scanner.setOnError(scanError);
|
||||
scanner.setScriptTarget(languageVersion);
|
||||
token = nextToken();
|
||||
|
||||
processReferenceComments(sourceFile);
|
||||
@ -1125,6 +1132,10 @@ module ts {
|
||||
}
|
||||
|
||||
syntaxCursor = undefined;
|
||||
|
||||
// Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
|
||||
scanner.setText("");
|
||||
scanner.setOnError(undefined);
|
||||
return sourceFile;
|
||||
|
||||
function setContextFlag(val: Boolean, flag: ParserContextFlags) {
|
||||
|
||||
@ -54,6 +54,7 @@ module ts {
|
||||
}
|
||||
text = "";
|
||||
}
|
||||
|
||||
return text !== undefined ? createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@ module ts {
|
||||
reScanTemplateToken(): SyntaxKind;
|
||||
scan(): SyntaxKind;
|
||||
setText(text: string): void;
|
||||
setOnError(onError: ErrorCallback): void;
|
||||
setScriptTarget(scriptTarget: ScriptTarget): void;
|
||||
setTextPos(textPos: number): void;
|
||||
// Invokes the provided callback then unconditionally restores the scanner to the state it
|
||||
// was in immediately prior to invoking the callback. The result of invoking the callback
|
||||
@ -599,6 +601,7 @@ module ts {
|
||||
export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback): Scanner {
|
||||
let pos: number; // Current position (end position of text of current token)
|
||||
let len: number; // Length of text
|
||||
|
||||
let startPos: number; // Start position of whitespace before current token
|
||||
let tokenPos: number; // Start position of text of current token
|
||||
let token: SyntaxKind;
|
||||
@ -607,6 +610,32 @@ module ts {
|
||||
let hasExtendedUnicodeEscape: boolean;
|
||||
let tokenIsUnterminated: boolean;
|
||||
|
||||
setText(text);
|
||||
|
||||
return {
|
||||
getStartPos: () => startPos,
|
||||
getTextPos: () => pos,
|
||||
getToken: () => token,
|
||||
getTokenPos: () => tokenPos,
|
||||
getTokenText: () => text.substring(tokenPos, pos),
|
||||
getTokenValue: () => tokenValue,
|
||||
hasExtendedUnicodeEscape: () => hasExtendedUnicodeEscape,
|
||||
hasPrecedingLineBreak: () => precedingLineBreak,
|
||||
isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord,
|
||||
isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord,
|
||||
isUnterminated: () => tokenIsUnterminated,
|
||||
reScanGreaterToken,
|
||||
reScanSlashToken,
|
||||
reScanTemplateToken,
|
||||
scan,
|
||||
setText,
|
||||
setScriptTarget,
|
||||
setOnError,
|
||||
setTextPos,
|
||||
tryScan,
|
||||
lookAhead,
|
||||
};
|
||||
|
||||
function error(message: DiagnosticMessage, length?: number): void {
|
||||
if (onError) {
|
||||
onError(message, length || 0);
|
||||
@ -1450,37 +1479,24 @@ module ts {
|
||||
setTextPos(0);
|
||||
}
|
||||
|
||||
function setOnError(errorCallback: ErrorCallback) {
|
||||
onError = errorCallback;
|
||||
}
|
||||
|
||||
function setScriptTarget(scriptTarget: ScriptTarget) {
|
||||
languageVersion = scriptTarget;
|
||||
}
|
||||
|
||||
function setTextPos(textPos: number) {
|
||||
pos = textPos;
|
||||
startPos = textPos;
|
||||
tokenPos = textPos;
|
||||
token = SyntaxKind.Unknown;
|
||||
precedingLineBreak = false;
|
||||
|
||||
tokenValue = undefined;
|
||||
hasExtendedUnicodeEscape = false;
|
||||
tokenIsUnterminated = false;
|
||||
}
|
||||
|
||||
setText(text);
|
||||
|
||||
|
||||
return {
|
||||
getStartPos: () => startPos,
|
||||
getTextPos: () => pos,
|
||||
getToken: () => token,
|
||||
getTokenPos: () => tokenPos,
|
||||
getTokenText: () => text.substring(tokenPos, pos),
|
||||
getTokenValue: () => tokenValue,
|
||||
hasExtendedUnicodeEscape: () => hasExtendedUnicodeEscape,
|
||||
hasPrecedingLineBreak: () => precedingLineBreak,
|
||||
isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord,
|
||||
isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord,
|
||||
isUnterminated: () => tokenIsUnterminated,
|
||||
reScanGreaterToken,
|
||||
reScanSlashToken,
|
||||
reScanTemplateToken,
|
||||
scan,
|
||||
setText,
|
||||
setTextPos,
|
||||
tryScan,
|
||||
lookAhead,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user