Added initial source map position tracking for tokens.

This commit is contained in:
Ron Buckton 2015-10-28 17:43:48 -07:00
parent 21574cd8a6
commit 6db601a921
4 changed files with 27 additions and 17 deletions

View file

@ -2165,13 +2165,25 @@ function __export(m) {
}
}
function writeToken(token: SyntaxKind) {
write(tokenToString(token));
function writeToken(token: SyntaxKind, pos?: number) {
let tokenStartPos = skipTrivia(currentSourceFile.text, pos);
emitPos(tokenStartPos);
let tokenEndPos = writeTokenText(token, pos);
emitPos(tokenEndPos);
return tokenEndPos;
}
function writeTokenText(token: SyntaxKind, pos?: number) {
let tokenString = tokenToString(token);
write(tokenString);
return positionIsSynthesized(pos) ? -1 : pos + tokenString.length;
}
function writeTokenNode(node: Node) {
if (node) {
writeToken(node.kind);
emitStart(node);
writeTokenText(node.kind);
emitEnd(node);
}
}

View file

@ -425,10 +425,10 @@ namespace ts {
/* @internal */
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
if (pos < 0) {
if (positionIsSynthesized(pos)) {
return pos;
}
// Keep in sync with couldStartTrivia
while (true) {
let ch = text.charCodeAt(pos);
@ -571,12 +571,12 @@ namespace ts {
}
/**
* Extract comments from text prefixing the token closest following `pos`.
* Extract comments from text prefixing the token closest following `pos`.
* The return value is an array containing a TextRange for each comment.
* Single-line comment ranges include the beginning '//' characters but not the ending line break.
* Multi - line comment ranges include the beginning '/* and ending '<asterisk>/' characters.
* The return value is undefined if no comments were found.
* @param trailing
* @param trailing
* If false, whitespace is skipped until the first line break and comments between that location
* and the next token are returned.
* If true, comments occurring between the given position and the next line break are returned.

View file

@ -7,7 +7,7 @@ namespace ts {
export interface SourceMapWriter {
sourceMapData?: SourceMapData;
setSourceFile(sourceFile: SourceFile): void;
emitPos(pos: number, skipTrivia?: boolean): void;
emitPos(pos: number): void;
emitStart(range: TextRange): void;
emitEnd(range: TextRange): void;
pushScope(scopeDeclaration: Node, scopeName?: string): void;
@ -167,15 +167,11 @@ namespace ts {
sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
}
function recordSourceMapSpan(pos: number, skipTrivia?: boolean) {
function recordSourceMapSpan(pos: number) {
if (pos === -1) {
return;
}
if (skipTrivia) {
pos = ts.skipTrivia(currentSourceFile.text, pos);
}
let sourceLinePos = getLineAndCharacterOfPosition(currentSourceFile, pos);
// Convert the location to be one-based.
@ -215,11 +211,11 @@ namespace ts {
}
function recordEmitNodeStartSpan(range: TextRange) {
recordSourceMapSpan(range.pos, /*skipTrivia*/ true);
recordSourceMapSpan(range.pos !== -1 ? skipTrivia(currentSourceFile.text, range.pos) : -1);
}
function recordEmitNodeEndSpan(range: TextRange) {
recordSourceMapSpan(range.end, /*skipTrivia*/ false);
recordSourceMapSpan(range.end);
}
function recordNewSourceFileStart(sourceFile: SourceFile) {

View file

@ -1827,11 +1827,13 @@ namespace ts {
}
export function nodeIsSynthesized(node: Node): boolean {
return node && node.pos === -1;
return node && positionIsSynthesized(node.pos);
}
export function positionIsSynthesized(pos: number): boolean {
return pos === -1;
// Using ! with a greater than test is a fast way of testing the following conditions:
// pos === undefined || pos === null || isNaN(pos) || pos <= 0;
return !(pos > 0);
}
export function childNodeStartPositionIsOnSameLine(sourceFile: SourceFile, parent: Node, child: Node) {