diff --git a/src/services/formatting/format.ts b/src/services/format.ts
similarity index 97%
rename from src/services/formatting/format.ts
rename to src/services/format.ts
index 0adc2cb00fb..6e53fa26541 100644
--- a/src/services/formatting/format.ts
+++ b/src/services/format.ts
@@ -1,8 +1,7 @@
-///
-///
-///
-///
-///
+///
+///
+///
+///
module ts.formatting {
@@ -25,10 +24,10 @@ module ts.formatting {
getEffectiveCommentIndentation(commentLine: number): number;
getDelta(): number;
getIndentation(): number;
+ setDelta(delta: number): number;
getCommentIndentation(): number;
increaseCommentIndentation(delta: number): void;
recomputeIndentation(lineAddedByFormatting: boolean): void;
- setDelta(delta: number): number;
}
export function formatOnEnter(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[] {
diff --git a/src/services/formatting/new/formatting.ts b/src/services/format/formatting.ts
similarity index 90%
rename from src/services/formatting/new/formatting.ts
rename to src/services/format/formatting.ts
index c61f1bce8af..3d19b33d821 100644
--- a/src/services/formatting/new/formatting.ts
+++ b/src/services/format/formatting.ts
@@ -13,7 +13,7 @@
// limitations under the License.
//
-///
+///
///
///
///
diff --git a/src/services/formatting/new/formattingContext.ts b/src/services/format/formattingContext.ts
similarity index 100%
rename from src/services/formatting/new/formattingContext.ts
rename to src/services/format/formattingContext.ts
diff --git a/src/services/formatting/new/formattingRequestKind.ts b/src/services/format/formattingRequestKind.ts
similarity index 100%
rename from src/services/formatting/new/formattingRequestKind.ts
rename to src/services/format/formattingRequestKind.ts
diff --git a/src/services/formatting/formattingScanner.ts b/src/services/format/formattingScanner.ts
similarity index 96%
rename from src/services/formatting/formattingScanner.ts
rename to src/services/format/formattingScanner.ts
index c9dc2949d17..e7f6b019057 100644
--- a/src/services/formatting/formattingScanner.ts
+++ b/src/services/format/formattingScanner.ts
@@ -1,3 +1,5 @@
+///
+
module ts.formatting {
var scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ false);
diff --git a/src/services/formatting/stringUtilities.ts b/src/services/format/indentation.ts
similarity index 100%
rename from src/services/formatting/stringUtilities.ts
rename to src/services/format/indentation.ts
diff --git a/src/services/formatting/new/rule.ts b/src/services/format/rule.ts
similarity index 100%
rename from src/services/formatting/new/rule.ts
rename to src/services/format/rule.ts
diff --git a/src/services/formatting/new/ruleAction.ts b/src/services/format/ruleAction.ts
similarity index 100%
rename from src/services/formatting/new/ruleAction.ts
rename to src/services/format/ruleAction.ts
diff --git a/src/services/formatting/new/ruleDescriptor.ts b/src/services/format/ruleDescriptor.ts
similarity index 100%
rename from src/services/formatting/new/ruleDescriptor.ts
rename to src/services/format/ruleDescriptor.ts
diff --git a/src/services/formatting/new/ruleFlag.ts b/src/services/format/ruleFlag.ts
similarity index 100%
rename from src/services/formatting/new/ruleFlag.ts
rename to src/services/format/ruleFlag.ts
diff --git a/src/services/formatting/new/ruleOperation.ts b/src/services/format/ruleOperation.ts
similarity index 100%
rename from src/services/formatting/new/ruleOperation.ts
rename to src/services/format/ruleOperation.ts
diff --git a/src/services/formatting/new/ruleOperationContext.ts b/src/services/format/ruleOperationContext.ts
similarity index 100%
rename from src/services/formatting/new/ruleOperationContext.ts
rename to src/services/format/ruleOperationContext.ts
diff --git a/src/services/formatting/new/rules.ts b/src/services/format/rules.ts
similarity index 100%
rename from src/services/formatting/new/rules.ts
rename to src/services/format/rules.ts
diff --git a/src/services/formatting/new/rulesMap.ts b/src/services/format/rulesMap.ts
similarity index 100%
rename from src/services/formatting/new/rulesMap.ts
rename to src/services/format/rulesMap.ts
diff --git a/src/services/formatting/new/rulesProvider.ts b/src/services/format/rulesProvider.ts
similarity index 100%
rename from src/services/formatting/new/rulesProvider.ts
rename to src/services/format/rulesProvider.ts
diff --git a/src/services/formatting/new/tokenRange.ts b/src/services/format/tokenRange.ts
similarity index 100%
rename from src/services/formatting/new/tokenRange.ts
rename to src/services/format/tokenRange.ts
diff --git a/src/services/formatting/new/tokenSpan.ts b/src/services/format/tokenSpan.ts
similarity index 100%
rename from src/services/formatting/new/tokenSpan.ts
rename to src/services/format/tokenSpan.ts
diff --git a/src/services/formatting/lineMapUtilities.ts b/src/services/formatting/lineMapUtilities.ts
deleted file mode 100644
index cd429019dba..00000000000
--- a/src/services/formatting/lineMapUtilities.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-///
-
-module ts.formatting {
-
- export function getEndLinePosition(line: number, sourceFile: SourceFile): number {
- Debug.assert(line >= 1);
- var lineStarts = sourceFile.getLineStarts();
-
- line = line - 1;
- if (line === lineStarts.length - 1) {
- // last line - return EOF
- return sourceFile.text.length - 1;
- }
- else {
- // current line start
- var start = lineStarts[line];
- // take the start position of the next line -1 = it should be some line break
- var pos = lineStarts[line + 1] - 1;
- Debug.assert(isLineBreak(sourceFile.text.charCodeAt(pos)));
- // walk backwards skipping line breaks, stop the the beginning of current line.
- // i.e:
- //
- // $ <- end of line for this position should match the start position
- while (start <= pos && isLineBreak(sourceFile.text.charCodeAt(pos))) {
- pos--;
- }
- return pos;
- }
- }
-
- export function getStartPositionOfLine(line: number, sourceFile: SourceFile): number {
- Debug.assert(line >= 1);
- return sourceFile.getLineStarts()[line - 1];
- }
-
- export function getStartLinePositionForPosition(position: number, sourceFile: SourceFile): number {
- var lineStarts = sourceFile.getLineStarts();
- var line = sourceFile.getLineAndCharacterFromPosition(position).line;
- return lineStarts[line - 1];
- }
-}
\ No newline at end of file
diff --git a/src/services/formatting/new/smartIndenter.ts b/src/services/formatting/new/smartIndenter.ts
deleted file mode 100644
index df57929dff3..00000000000
--- a/src/services/formatting/new/smartIndenter.ts
+++ /dev/null
@@ -1,401 +0,0 @@
-///
-///
-
-module ts.formatting {
- export module SmartIndenter {
- export function getIndentation(position: number, sourceFile: SourceFile, options: EditorOptions): number {
- if (position > sourceFile.text.length) {
- return 0; // past EOF
- }
-
- var precedingToken = ServicesSyntaxUtilities.findPrecedingToken(position, sourceFile);
- if (!precedingToken) {
- return 0;
- }
-
- // no indentation in string \regex literals
- if ((precedingToken.kind === SyntaxKind.StringLiteral || precedingToken.kind === SyntaxKind.RegularExpressionLiteral) &&
- precedingToken.getStart(sourceFile) <= position &&
- precedingToken.end > position) {
- return 0;
- }
-
- var lineAtPosition = sourceFile.getLineAndCharacterFromPosition(position).line;
-
- if (precedingToken.kind === SyntaxKind.CommaToken && precedingToken.parent.kind !== SyntaxKind.BinaryExpression) {
- // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
- var actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
- if (actualIndentation !== -1) {
- return actualIndentation;
- }
- }
-
- // try to find node that can contribute to indentation and includes 'position' starting from 'precedingToken'
- // if such node is found - compute initial indentation for 'position' inside this node
- var previous: Node;
- var current = precedingToken;
- var currentStart: LineAndCharacter;
- var indentationDelta: number;
-
- while (current) {
- if (positionBelongsToNode(current, position, sourceFile) && nodeContentIsIndented(current, previous)) {
- currentStart = getStartLineAndCharacterForNode(current, sourceFile);
-
- if (nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile)) {
- indentationDelta = 0;
- }
- else {
- indentationDelta = lineAtPosition !== currentStart.line ? options.IndentSize : 0;
- }
-
- break;
- }
-
- // check if current node is a list item - if yes, take indentation from it
- var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
- if (actualIndentation !== -1) {
- return actualIndentation;
- }
-
- previous = current;
- current = current.parent;
- }
-
- if (!current) {
- // no parent was found - return 0 to be indented on the level of SourceFile
- return 0;
- }
-
- return getIndentationForNode(current, currentStart, indentationDelta, sourceFile, options);
- }
-
- export function getIndentationForNode(current: Node, currentStart: LineAndCharacter, indentationDelta: number, sourceFile: SourceFile, options: EditorOptions): number {
- var parent: Node = current.parent;
- var parentStart: LineAndCharacter;
-
- // walk upwards and collect indentations for pairs of parent-child nodes
- // indentation is not added if parent and child nodes start on the same line or if parent is IfStatement and child starts on the same line with 'else clause'
- while (parent) {
- // check if current node is a list item - if yes, take indentation from it
- var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
- if (actualIndentation !== -1) {
- return actualIndentation + indentationDelta;
- }
-
- parentStart = sourceFile.getLineAndCharacterFromPosition(parent.getStart(sourceFile));
- var parentAndChildShareLine =
- parentStart.line === currentStart.line ||
- childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
-
- // try to fetch actual indentation for current node from source text
- var actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
- if (actualIndentation !== -1) {
- return actualIndentation + indentationDelta;
- }
-
- // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
- if (nodeContentIsIndented(parent, current) && !parentAndChildShareLine) {
- indentationDelta += options.IndentSize;
- }
-
- current = parent;
- currentStart = parentStart;
- parent = current.parent;
- }
-
- return indentationDelta;
- }
-
- /*
- * Function returns -1 if indentation cannot be determined
- */
- function getActualIndentationForListItemBeforeComma(commaToken: Node, sourceFile: SourceFile, options: EditorOptions): number {
- // previous token is comma that separates items in list - find the previous item and try to derive indentation from it
- var commaItemInfo = ServicesSyntaxUtilities.findListItemInfo(commaToken);
- Debug.assert(commaItemInfo.listItemIndex > 0);
- // The item we're interested in is right before the comma
- return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
- }
-
- /*
- * Function returns -1 if actual indentation for node should not be used (i.e because node is nested expression)
- */
- function getActualIndentationForNode(current: Node,
- parent: Node,
- currentLineAndChar: LineAndCharacter,
- parentAndChildShareLine: boolean,
- sourceFile: SourceFile,
- options: EditorOptions): number {
-
- // actual indentation is used for statements\declarations if one of cases below is true:
- // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
- // - parent and child are not on the same line
- var useActualIndentation =
- (isDeclaration(current) || isStatement(current)) &&
- (parent.kind === SyntaxKind.SourceFile || !parentAndChildShareLine);
-
- if (!useActualIndentation) {
- return -1;
- }
-
- return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
- }
-
- function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: Node, current: Node, lineAtPosition: number, sourceFile: SourceFile): boolean {
- var nextToken = ServicesSyntaxUtilities.findNextToken(precedingToken, current);
- if (!nextToken) {
- return false;
- }
-
- if (nextToken.kind === SyntaxKind.OpenBraceToken) {
- // open braces are always indented at the parent level
- return true;
- }
- else if (nextToken.kind === SyntaxKind.CloseBraceToken) {
- // close braces are indented at the parent level if they are located on the same line with cursor
- // this means that if new line will be added at $ position, this case will be indented
- // class A {
- // $
- // }
- /// and this one - not
- // class A {
- // $}
-
- var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
- return lineAtPosition === nextTokenStartLine;
- }
-
- return false;
- }
-
- function getStartLineAndCharacterForNode(n: Node, sourceFile: SourceFile): LineAndCharacter {
- return sourceFile.getLineAndCharacterFromPosition(n.getStart(sourceFile));
- }
-
- function positionBelongsToNode(candidate: Node, position: number, sourceFile: SourceFile): boolean {
- return candidate.end > position || !isCompletedNode(candidate, sourceFile);
- }
-
- function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFile): boolean {
- if (parent.kind === SyntaxKind.IfStatement && (parent).elseStatement === child) {
- var elseKeyword = forEach(parent.getChildren(), c => c.kind === SyntaxKind.ElseKeyword && c);
- Debug.assert(elseKeyword);
-
- var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
- return elseKeywordStartLine === childStartLine;
- }
- }
-
- function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorOptions): number {
- if (node.parent) {
- switch (node.parent.kind) {
- case SyntaxKind.TypeReference:
- if ((node.parent).typeArguments) {
- return getActualIndentationFromList((node.parent).typeArguments);
- }
- break;
- case SyntaxKind.ObjectLiteral:
- return getActualIndentationFromList((node.parent).properties);
- case SyntaxKind.TypeLiteral:
- return getActualIndentationFromList((node.parent).members);
- case SyntaxKind.ArrayLiteral:
- return getActualIndentationFromList((node.parent).elements);
- case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.FunctionExpression:
- case SyntaxKind.ArrowFunction:
- case SyntaxKind.Method:
- case SyntaxKind.CallSignature:
- case SyntaxKind.ConstructSignature:
- if ((node.parent).typeParameters && node.end < (node.parent).typeParameters.end) {
- return getActualIndentationFromList((node.parent).typeParameters);
- }
-
- return getActualIndentationFromList((node.parent).parameters);
- case SyntaxKind.NewExpression:
- case SyntaxKind.CallExpression:
- if ((node.parent).typeArguments && node.end < (node.parent).typeArguments.end) {
- return getActualIndentationFromList((node.parent).typeArguments);
- }
-
- return getActualIndentationFromList((node.parent).arguments);
- }
- }
-
- return -1;
-
- function getActualIndentationFromList(list: Node[]): number {
- var index = indexOf(list, node);
- return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : -1;
- }
- }
-
-
- function deriveActualIndentationFromList(list: Node[], index: number, sourceFile: SourceFile, options: EditorOptions): number {
- Debug.assert(index >= 0 && index < list.length);
- var node = list[index];
-
- // walk toward the start of the list starting from current node and check if the line is the same for all items.
- // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i]
- var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
- for (var i = index - 1; i >= 0; --i) {
- if (list[i].kind === SyntaxKind.CommaToken) {
- continue;
- }
- // skip list items that ends on the same line with the current list element
- var prevEndLine = sourceFile.getLineAndCharacterFromPosition(list[i].end).line;
- if (prevEndLine !== lineAndCharacter.line) {
- return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
- }
-
- lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
- }
- return -1;
- }
-
- function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter: LineAndCharacter, sourceFile: SourceFile, options: EditorOptions): number {
- var lineStart = sourceFile.getPositionFromLineAndCharacter(lineAndCharacter.line, 1);
- var column = 0;
- for (var i = 0; i < lineAndCharacter.character; ++i) {
- var charCode = sourceFile.text.charCodeAt(lineStart + i);
- if (!isWhiteSpace(charCode)) {
- return column;
- }
-
- if (charCode === CharacterCodes.tab) {
- column += options.TabSize;
- }
- else {
- column++;
- }
- }
-
- return column;
- }
-
- function nodeContentIsIndented(parent: Node, child: Node): boolean {
- switch (parent.kind) {
- case SyntaxKind.ClassDeclaration:
- case SyntaxKind.InterfaceDeclaration:
- case SyntaxKind.EnumDeclaration:
- return true;
- case SyntaxKind.ModuleDeclaration:
- // ModuleBlock should take care of indentation
- return false;
- case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.Method:
- case SyntaxKind.FunctionExpression:
- case SyntaxKind.GetAccessor:
- case SyntaxKind.SetAccessor:
- case SyntaxKind.Constructor:
- // FunctionBlock should take care of indentation
- return false;
- case SyntaxKind.DoStatement:
- case SyntaxKind.WhileStatement:
- case SyntaxKind.ForInStatement:
- case SyntaxKind.ForStatement:
- return child && child.kind !== SyntaxKind.Block;
- case SyntaxKind.IfStatement:
- return child && child.kind !== SyntaxKind.Block;
- case SyntaxKind.TryStatement:
- // TryBlock\CatchBlock\FinallyBlock should take care of indentation
- return false;
- case SyntaxKind.ArrayLiteral:
- case SyntaxKind.Block:
- case SyntaxKind.FunctionBlock:
- case SyntaxKind.TryBlock:
- case SyntaxKind.CatchBlock:
- case SyntaxKind.FinallyBlock:
- case SyntaxKind.ModuleBlock:
- case SyntaxKind.ObjectLiteral:
- case SyntaxKind.TypeLiteral:
- case SyntaxKind.SwitchStatement:
- case SyntaxKind.DefaultClause:
- case SyntaxKind.CaseClause:
- case SyntaxKind.ParenExpression:
- case SyntaxKind.CallExpression:
- case SyntaxKind.NewExpression:
- case SyntaxKind.VariableStatement:
- case SyntaxKind.VariableDeclaration:
- return true;
- default:
- return false;
- }
- }
-
- /*
- * Checks if node ends with 'expectedLastToken'.
- * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'.
- */
- function nodeEndsWith(n: Node, expectedLastToken: SyntaxKind, sourceFile: SourceFile): boolean {
- var children = n.getChildren(sourceFile);
- if (children.length) {
- var last = children[children.length - 1];
- if (last.kind === expectedLastToken) {
- return true;
- }
- else if (last.kind === SyntaxKind.SemicolonToken && children.length !== 1) {
- return children[children.length - 2].kind === expectedLastToken;
- }
- }
- return false;
- }
-
- /*
- * This function is always called when position of the cursor is located after the node
- */
- function isCompletedNode(n: Node, sourceFile: SourceFile): boolean {
- switch (n.kind) {
- case SyntaxKind.ClassDeclaration:
- case SyntaxKind.InterfaceDeclaration:
- case SyntaxKind.EnumDeclaration:
- case SyntaxKind.ObjectLiteral:
- case SyntaxKind.Block:
- case SyntaxKind.CatchBlock:
- case SyntaxKind.FinallyBlock:
- case SyntaxKind.FunctionBlock:
- case SyntaxKind.ModuleBlock:
- case SyntaxKind.SwitchStatement:
- return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile);
- case SyntaxKind.ParenExpression:
- case SyntaxKind.CallSignature:
- case SyntaxKind.CallExpression:
- case SyntaxKind.ConstructSignature:
- return nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile);
- case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.FunctionExpression:
- case SyntaxKind.Method:
- case SyntaxKind.ArrowFunction:
- return !(n).body || isCompletedNode((n).body, sourceFile);
- case SyntaxKind.ModuleDeclaration:
- return (n).body && isCompletedNode((n).body, sourceFile);
- case SyntaxKind.IfStatement:
- if ((n).elseStatement) {
- return isCompletedNode((n).elseStatement, sourceFile);
- }
- return isCompletedNode((n).thenStatement, sourceFile);
- case SyntaxKind.ExpressionStatement:
- return isCompletedNode((n).expression, sourceFile);
- case SyntaxKind.ArrayLiteral:
- return nodeEndsWith(n, SyntaxKind.CloseBracketToken, sourceFile);
- case SyntaxKind.Missing:
- return false;
- case SyntaxKind.CaseClause:
- case SyntaxKind.DefaultClause:
- // there is no such thing as terminator token for CaseClause\DefaultClause so for simplicitly always consider them non-completed
- return false;
- case SyntaxKind.WhileStatement:
- return isCompletedNode((n).statement, sourceFile);
- case SyntaxKind.DoStatement:
- // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
- var hasWhileKeyword = forEach(n.getChildren(), c => c.kind === SyntaxKind.WhileKeyword && c);
- if(hasWhileKeyword) {
- return nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile);
- }
- return isCompletedNode((n).statement, sourceFile);
- default:
- return true;
- }
- }
- }
-}
-
diff --git a/src/services/services.ts b/src/services/services.ts
index 113e878efb4..33bec5ae8d8 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -12,8 +12,8 @@
///
///
///
-///
-///
+///
+///
///
///
diff --git a/src/services/formatting/smartIndenter.ts b/src/services/smartIndenter.ts
similarity index 97%
rename from src/services/formatting/smartIndenter.ts
rename to src/services/smartIndenter.ts
index 010dcf174c8..98971b1f14a 100644
--- a/src/services/formatting/smartIndenter.ts
+++ b/src/services/smartIndenter.ts
@@ -1,4 +1,4 @@
-///
+///
module ts.formatting {
export module SmartIndenter {
diff --git a/src/services/utilities.ts b/src/services/utilities.ts
index 1fede7f3a1b..a4146c52e5e 100644
--- a/src/services/utilities.ts
+++ b/src/services/utilities.ts
@@ -5,6 +5,43 @@ module ts {
list: Node;
}
+ export function getEndLinePosition(line: number, sourceFile: SourceFile): number {
+ Debug.assert(line >= 1);
+ var lineStarts = sourceFile.getLineStarts();
+
+ line = line - 1;
+ if (line === lineStarts.length - 1) {
+ // last line - return EOF
+ return sourceFile.text.length - 1;
+ }
+ else {
+ // current line start
+ var start = lineStarts[line];
+ // take the start position of the next line -1 = it should be some line break
+ var pos = lineStarts[line + 1] - 1;
+ Debug.assert(isLineBreak(sourceFile.text.charCodeAt(pos)));
+ // walk backwards skipping line breaks, stop the the beginning of current line.
+ // i.e:
+ //
+ // $ <- end of line for this position should match the start position
+ while (start <= pos && isLineBreak(sourceFile.text.charCodeAt(pos))) {
+ pos--;
+ }
+ return pos;
+ }
+ }
+
+ export function getStartPositionOfLine(line: number, sourceFile: SourceFile): number {
+ Debug.assert(line >= 1);
+ return sourceFile.getLineStarts()[line - 1];
+ }
+
+ export function getStartLinePositionForPosition(position: number, sourceFile: SourceFile): number {
+ var lineStarts = sourceFile.getLineStarts();
+ var line = sourceFile.getLineAndCharacterFromPosition(position).line;
+ return lineStarts[line - 1];
+ }
+
export function rangeContainsRange(r1: TextRange, r2: TextRange): boolean {
return startEndContainsRange(r1.pos, r1.end, r2);
}