getFormattingScanner: Ensure scanner is closed, and avoid global variables (#18293)

This commit is contained in:
Andy
2017-09-07 07:23:53 -07:00
committed by GitHub
parent 23f793fc3e
commit 817c329667
2 changed files with 14 additions and 25 deletions

View File

@@ -339,17 +339,17 @@ namespace ts.formatting {
/* @internal */
export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, rulesProvider: RulesProvider): TextChange[] {
const range = { pos: 0, end: sourceFileLike.text.length };
return formatSpanWorker(
return getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, scanner => formatSpanWorker(
range,
node,
initialIndentation,
delta,
getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end),
scanner,
rulesProvider.getFormatOptions(),
rulesProvider,
FormattingRequestKind.FormatSelection,
_ => false, // assume that node does not have any errors
sourceFileLike);
sourceFileLike));
}
function formatNodeLines(node: Node, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] {
@@ -372,17 +372,17 @@ namespace ts.formatting {
requestKind: FormattingRequestKind): TextChange[] {
// find the smallest node that fully wraps the range and compute the initial indentation for the node
const enclosingNode = findEnclosingNode(originalRange, sourceFile);
return formatSpanWorker(
return getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, scanner => formatSpanWorker(
originalRange,
enclosingNode,
SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options),
getOwnOrInheritedDelta(enclosingNode, options, sourceFile),
getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end),
scanner,
options,
rulesProvider,
requestKind,
prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange),
sourceFile);
sourceFile));
}
function formatSpanWorker(originalRange: TextRange,
@@ -427,8 +427,6 @@ namespace ts.formatting {
}
}
formattingScanner.close();
return edits;
// local functions

View File

@@ -6,11 +6,6 @@ namespace ts.formatting {
const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard);
const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX);
/**
* Scanner that is currently used for formatting
*/
let scanner: Scanner;
export interface FormattingScanner {
advance(): void;
isOnToken(): boolean;
@@ -18,7 +13,6 @@ namespace ts.formatting {
getCurrentLeadingTrivia(): TextRangeWithKind[];
lastTrailingTriviaWasNewLine(): boolean;
skipToEndOf(node: Node): void;
close(): void;
}
const enum ScanAction {
@@ -30,9 +24,8 @@ namespace ts.formatting {
RescanJsxText,
}
export function getFormattingScanner(text: string, languageVariant: LanguageVariant, startPos: number, endPos: number): FormattingScanner {
Debug.assert(scanner === undefined, "Scanner should be undefined");
scanner = languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
export function getFormattingScanner<T>(text: string, languageVariant: LanguageVariant, startPos: number, endPos: number, cb: (scanner: FormattingScanner) => T): T {
const scanner = languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
scanner.setText(text);
scanner.setTextPos(startPos);
@@ -45,21 +38,19 @@ namespace ts.formatting {
let lastScanAction: ScanAction | undefined;
let lastTokenInfo: TokenInfo | undefined;
return {
const res = cb({
advance,
readTokenInfo,
isOnToken,
getCurrentLeadingTrivia: () => leadingTrivia,
lastTrailingTriviaWasNewLine: () => wasNewLine,
skipToEndOf,
close: () => {
Debug.assert(scanner !== undefined);
});
lastTokenInfo = undefined;
scanner.setText(undefined);
scanner = undefined;
}
};
lastTokenInfo = undefined;
scanner.setText(undefined);
return res;
function advance(): void {
Debug.assert(scanner !== undefined, "Scanner should be present");