From 45ac06a0f217e19e9d86c78cdf5abd455b9d3eb6 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 16 Jan 2015 12:02:12 -0800 Subject: [PATCH] move line map related function out of SourceFile --- src/compiler/emitter.ts | 10 +++++----- src/compiler/parser.ts | 17 ----------------- src/compiler/scanner.ts | 17 ++++++++++++----- src/compiler/tsc.ts | 4 ++-- src/compiler/types.ts | 7 +++---- src/compiler/utilities.ts | 2 +- src/harness/fourslash.ts | 2 +- src/harness/harnessLanguageService.ts | 4 ++-- src/services/services.ts | 21 +++++++++++++++++---- 9 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d82e577971d..a0c0dc45b15 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -134,7 +134,7 @@ module ts { } function getLineOfLocalPosition(currentSourceFile: SourceFile, pos: number) { - return currentSourceFile.getLineAndCharacterFromPosition(pos).line; + return getLineAndCharacterOfPosition(currentSourceFile, pos).line; } function emitNewLineBeforeLeadingComments(currentSourceFile: SourceFile, writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) { @@ -169,15 +169,15 @@ module ts { function writeCommentRange(currentSourceFile: SourceFile, writer: EmitTextWriter, comment: CommentRange, newLine: string){ if (currentSourceFile.text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk) { - var firstCommentLineAndCharacter = currentSourceFile.getLineAndCharacterFromPosition(comment.pos); + var firstCommentLineAndCharacter = getLineAndCharacterOfPosition(currentSourceFile, comment.pos); var firstCommentLineIndent: number; for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) { - var nextLineStart = currentSourceFile.getPositionFromLineAndCharacter(currentLine + 1, /*character*/1); + var nextLineStart = getPositionFromLineAndCharacter(currentSourceFile, currentLine + 1, /*character*/1); if (pos !== comment.pos) { // If we are not emitting first line, we need to write the spaces to adjust the alignment if (firstCommentLineIndent === undefined) { - firstCommentLineIndent = calculateIndent(currentSourceFile.getPositionFromLineAndCharacter(firstCommentLineAndCharacter.line, /*character*/1), + firstCommentLineIndent = calculateIndent(getPositionFromLineAndCharacter(currentSourceFile, firstCommentLineAndCharacter.line, /*character*/1), comment.pos); } @@ -1644,7 +1644,7 @@ module ts { } function recordSourceMapSpan(pos: number) { - var sourceLinePos = currentSourceFile.getLineAndCharacterFromPosition(pos); + var sourceLinePos = getLineAndCharacterOfPosition(currentSourceFile, pos); var emittedLine = writer.getLine(); var emittedColumn = writer.getColumn(); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5ae44e5ff39..19efe77a278 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -501,7 +501,6 @@ module ts { var identifiers: Map; var identifierCount = 0; var nodeCount = 0; - var lineStarts: number[]; var syntacticDiagnostics: Diagnostic[]; var scanner: Scanner; var token: SyntaxKind; @@ -593,7 +592,6 @@ module ts { sourceText = text; parsingContext = 0; identifiers = {}; - lineStarts = undefined; syntacticDiagnostics = undefined; contextFlags = 0; parseErrorBeforeNextFinishedNode = false; @@ -612,9 +610,6 @@ module ts { sourceFile.filename = normalizePath(filename); sourceFile.text = sourceText; - sourceFile.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition; - sourceFile.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter; - sourceFile.getLineStarts = getLineStarts; sourceFile.getSyntacticDiagnostics = getSyntacticDiagnostics; sourceFile.update = update; @@ -1072,18 +1067,6 @@ module ts { return (contextFlags & ParserContextFlags.DisallowIn) !== 0; } - function getLineStarts(): number[] { - return lineStarts || (lineStarts = computeLineStarts(sourceText)); - } - - function getLineAndCharacterFromSourcePosition(position: number) { - return getLineAndCharacterOfPosition(getLineStarts(), position); - } - - function getPositionFromSourceLineAndCharacter(line: number, character: number): number { - return getPositionFromLineAndCharacter(getLineStarts(), line, character); - } - function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void { var start = scanner.getTokenPos(); var length = scanner.getTextPos() - start; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 2a0363f7f78..2f475cb6768 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -278,12 +278,20 @@ module ts { return result; } - export function getPositionFromLineAndCharacter(lineStarts: number[], line: number, character: number): number { + export function getPositionFromLineAndCharacter(sourceFile: SourceFile, line: number, character: number): number { + return computePositionFromLineAndCharacter(getLineStarts(sourceFile), line, character); + } + + export function computePositionFromLineAndCharacter(lineStarts: number[], line: number, character: number): number { Debug.assert(line > 0); return lineStarts[line - 1] + character - 1; } - export function getLineAndCharacterOfPosition(lineStarts: number[], position: number) { + export function getLineStarts(sourceFile: SourceFile): number[] { + return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text)); + } + + export function computeLineAndCharacterOfPosition(lineStarts: number[], position: number) { var lineNumber = binarySearch(lineStarts, position); if (lineNumber < 0) { // If the actual position was not found, @@ -298,9 +306,8 @@ module ts { }; } - export function positionToLineAndCharacter(text: string, pos: number) { - var lineStarts = computeLineStarts(text); - return getLineAndCharacterOfPosition(lineStarts, pos); + export function getLineAndCharacterOfPosition(sourceFile: SourceFile, position: number): LineAndCharacter { + return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } var hasOwnProperty = Object.prototype.hasOwnProperty; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 9d038920693..443abf5e57c 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -68,7 +68,7 @@ module ts { function countLines(program: Program): number { var count = 0; forEach(program.getSourceFiles(), file => { - count += file.getLineAndCharacterFromPosition(file.end).line; + count += getLineAndCharacterOfPosition(file, file.end).line; }); return count; } @@ -82,7 +82,7 @@ module ts { var output = ""; if (diagnostic.file) { - var loc = diagnostic.file.getLineAndCharacterFromPosition(diagnostic.start); + var loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); output += diagnostic.file.filename + "(" + loc.line + "," + loc.character + "): "; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9ebab8dc220..9d899ccd21d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -881,10 +881,6 @@ module ts { filename: string; text: string; - getLineAndCharacterFromPosition(position: number): LineAndCharacter; - getPositionFromLineAndCharacter(line: number, character: number): number; - getLineStarts(): number[]; - // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter // indicates what changed between the 'text' that this SourceFile has and the 'newText'. // The SourceFile will be created with the compiler attempting to reuse as many nodes from @@ -920,6 +916,9 @@ module ts { symbolCount: number; languageVersion: ScriptTarget; identifiers: Map; + + // Stores a line map for the file. This field should never be used directly to obtain line map, use getLineMap function instead. + lineMap: number[]; } export interface ScriptReferenceHost { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7494ec9f6cb..b451cac5423 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -109,7 +109,7 @@ module ts { // This is a useful function for debugging purposes. export function nodePosToString(node: Node): string { var file = getSourceFileOfNode(node); - var loc = file.getLineAndCharacterFromPosition(node.pos); + var loc = getLineAndCharacterOfPosition(file, node.pos); return file.filename + "(" + loc.line + "," + loc.character + ")"; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index cfc83af76e5..d320ceb0d98 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -391,7 +391,7 @@ module FourSlash { this.currentCaretPosition = pos; var lineStarts = ts.computeLineStarts(this.getCurrentFileContent()); - var lineCharPos = ts.getLineAndCharacterOfPosition(lineStarts, pos); + var lineCharPos = ts.computeLineAndCharacterOfPosition(lineStarts, pos); this.scenarioActions.push(''); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 97885bdd20e..9cebfb2078b 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -292,7 +292,7 @@ module Harness.LanguageService { assert.isTrue(line >= 1); assert.isTrue(col >= 1); - return ts.getPositionFromLineAndCharacter(script.lineMap, line, col); + return ts.computePositionFromLineAndCharacter(script.lineMap, line, col); } /** @@ -303,7 +303,7 @@ module Harness.LanguageService { var script: ScriptInfo = this.fileNameToScript[fileName]; assert.isNotNull(script); - var result = ts.getLineAndCharacterOfPosition(script.lineMap, position); + var result = ts.computeLineAndCharacterOfPosition(script.lineMap, position); assert.isTrue(result.line >= 1); assert.isTrue(result.character >= 1); diff --git a/src/services/services.ts b/src/services/services.ts index 1618fb6e276..62d55bb1d61 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -61,6 +61,9 @@ module ts { scriptSnapshot: IScriptSnapshot; getNamedDeclarations(): Declaration[]; + getLineAndCharacterFromPosition(pos: number): LineAndCharacter; + getLineStarts(): number[]; + getPositionFromLineAndCharacter(line: number, character: number): number; } /** @@ -721,18 +724,16 @@ module ts { public filename: string; public text: string; public scriptSnapshot: IScriptSnapshot; + public lineMap: number[]; public statements: NodeArray; public endOfFileToken: Node; // These methods will have their implementation provided by the implementation the // compiler actually exports off of SourceFile. - public getLineAndCharacterFromPosition: (position: number) => LineAndCharacter; - public getPositionFromLineAndCharacter: (line: number, character: number) => number; - public getLineStarts: () => number[]; public getSyntacticDiagnostics: () => Diagnostic[]; public update: (newText: string, textChangeRange: TextChangeRange) => SourceFile; - + public amdDependencies: string[]; public amdModuleName: string; public referencedFiles: FileReference[]; @@ -753,6 +754,18 @@ module ts { private namedDeclarations: Declaration[]; + public getLineAndCharacterFromPosition(position: number): LineAndCharacter { + return getLineAndCharacterOfPosition(this, position); + } + + public getLineStarts(): number[] { + return getLineStarts(this); + } + + public getPositionFromLineAndCharacter(line: number, character: number): number { + return getPositionFromLineAndCharacter(this, line, character); + } + public getNamedDeclarations() { if (!this.namedDeclarations) { var sourceFile = this;