diff --git a/src/services/formatting/format.ts b/src/services/formatting/format.ts index e4d2ba6416d..00a8227cf52 100644 --- a/src/services/formatting/format.ts +++ b/src/services/formatting/format.ts @@ -15,7 +15,6 @@ module ts.formatting { trailingTrivia: TextRangeWithKind[]; } - export function formatOnEnter(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[]{ var line = getNonAdjustedLineAndCharacterFromPosition(position, sourceFile).line; // get the span for the previous\current line @@ -92,7 +91,7 @@ module ts.formatting { return []; } var span = { - pos: getStartLinePositionForPosition(parent.pos, sourceFile), + pos: getStartLinePositionForPosition(parent.getStart(sourceFile), sourceFile), end: parent.end }; return formatSpan(span, sourceFile, options, rulesProvider, requestKind); @@ -157,9 +156,9 @@ module ts.formatting { } } - function getIndentationForNode(n: Node, sourceFile: SourceFile, options: FormatCodeOptions): number { + function getIndentationForNode(n: Node, ignoreActualIndentationRange: TextRange, sourceFile: SourceFile, options: FormatCodeOptions): number { var start = sourceFile.getLineAndCharacterFromPosition(n.getStart(sourceFile)); - return SmartIndenter.getIndentationForNode(n, start, /*indentationDelta*/ 0, sourceFile, options); + return SmartIndenter.getIndentationForNode(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, options); } function getNonAdjustedLineAndCharacterFromPosition(position: number, sourceFile: SourceFile): LineAndCharacter { @@ -177,7 +176,7 @@ module ts.formatting { var formattingContext = new FormattingContext(sourceFile, requestKind); var enclosingNode = findEnclosingNode(originalRange, sourceFile); - var initialIndentation = getIndentationForNode(enclosingNode, sourceFile, options); + var initialIndentation = getIndentationForNode(enclosingNode, originalRange, sourceFile, options); var formattingScanner = getFormattingScanner(sourceFile, enclosingNode, originalRange); @@ -205,39 +204,33 @@ module ts.formatting { var childContextNode = contextNode; forEachChild( node, - child => processChildNode(child, /*containingList*/ undefined, /*listElementIndex*/ -1), + child => processChildNode(child, indentation, /*containingList*/ undefined, /*listElementIndex*/ -1), nodes => { for (var i = 0, len = nodes.length; i < len; ++i) { - processChildNode(nodes[i], /*containingList*/ nodes, /*listElementIndex*/ i) + processChildNode(nodes[i], indentation, /*containingList*/ nodes, /*listElementIndex*/ i) } } ); // this eats up last tokens in the node - // TODO: resync token info and consume it while (formattingScanner.isOnToken()) { var tokenInfo = formattingScanner.readTokenInfo(node); if (node.end >= tokenInfo.token.end) { - consumeTokenAndAdvance(tokenInfo, node, childContextNode, indentation); + var commentIndentation = + SmartIndenter.nodeContentIsAlwaysIndented(node) && node.end === tokenInfo.token.end + ? indentation + options.IndentSize + : indentation; + consumeTokenAndAdvance(tokenInfo, node, childContextNode, indentation, commentIndentation); childContextNode = node; } else { break; } } - //while (currentTokenInfo.token && node.end >= currentTokenInfo.token.end) { - // if (SmartIndenter.nodeContentIsAlwaysIndented(node)) { - // currentTokenInfo = consumeCurrentToken(node, childContextNode, indentation); - // } - // else { - // currentTokenInfo = consumeCurrentToken(node, childContextNode, indentation); - // } - // childContextNode = node; - //} /// Local functions - function processChildNode(child: Node, containingList: Node[], listElementIndex: number): void { + function processChildNode(child: Node, indentation: number, containingList: Node[], listElementIndex: number): void { if (child.kind === SyntaxKind.Missing) { return; } @@ -246,7 +239,7 @@ module ts.formatting { while (formattingScanner.isOnToken()) { var tokenInfo = formattingScanner.readTokenInfo(node); if (start >= tokenInfo.token.end) { - consumeTokenAndAdvance(tokenInfo, node, childContextNode, indentation); + consumeTokenAndAdvance(tokenInfo, node, childContextNode, indentation, indentation); childContextNode = node; } else { @@ -254,26 +247,15 @@ module ts.formatting { } } - //while (currentTokenInfo.token && start >= currentTokenInfo.token.end) { - // // we've walked past the current token - // // ask parent to handle it - // currentTokenInfo = consumeCurrentToken(node, childContextNode, indentation); - // childContextNode = node; - //} - if (!formattingScanner.isOnToken()) { return; } - //if (!currentTokenInfo.token) { - // return; - //} - // ensure that current token is inside child node if (isToken(child)) { var tokenInfo = formattingScanner.readTokenInfo(node); if (tokenInfo.token.end === child.end) { - consumeTokenAndAdvance(tokenInfo, node, childContextNode, indentation); + consumeTokenAndAdvance(tokenInfo, node, childContextNode, indentation, indentation); childContextNode = node; return; } @@ -283,11 +265,10 @@ module ts.formatting { var childIndentation = indentation; if (listElementIndex === -1) { - // child is not list element - + // child is not list element } else { - // child is a list element + // child is a list element } // determine child indentation // if child @@ -299,38 +280,10 @@ module ts.formatting { processNode(child, childContextNode, childStartLine, increaseIndentation ? indentation + options.IndentSize : indentation); childContextNode = node; - - //if (isToken(child) && currentTokenInfo.token.end === child.end) { - // // tokens belong to parent nodes - // currentTokenInfo = consumeCurrentToken(node, childContextNode, indentation); - // childContextNode = node; - //} - //else { - // var childStartLine = getNonAdjustedLineAndCharacterFromPosition(start, sourceFile).line; - - // var childIndentation = indentation; - // if (listElementIndex === -1) { - // // child is not list element - - // } - // else { - // // child is a list element - // } - // // determine child indentation - // // if child - // // TODO: share this code with SmartIndenter - // var increaseIndentation = - // childStartLine !== nodeStartLine && - // !SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(node, child, childStartLine, sourceFile) && - // SmartIndenter.shouldIndentChildNode(node, child); - - // processNode(child, childContextNode, childStartLine, increaseIndentation ? indentation + options.IndentSize : indentation); - // childContextNode = node; - //} } } - function consumeTokenAndAdvance(currentTokenInfo: TokenInfo, parent: Node, contextNode: Node, indentation: number): void { + function consumeTokenAndAdvance(currentTokenInfo: TokenInfo, parent: Node, contextNode: Node, indentation: number, commentIndentation: number): void { Debug.assert(rangeContainsRange(parent, currentTokenInfo.token)); lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine(); @@ -356,12 +309,12 @@ module ts.formatting { if (rangeContainsRange(originalRange, triviaItem)) { switch (triviaItem.kind) { case SyntaxKind.MultiLineCommentTrivia: - indentMultilineComment(triviaItem, indentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); + indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); indentNextTokenOrTrivia = false; break; case SyntaxKind.SingleLineCommentTrivia: if (indentNextTokenOrTrivia) { - insertIndentation(triviaItem.pos, indentation); + insertIndentation(triviaItem.pos, commentIndentation); indentNextTokenOrTrivia = false; } break; @@ -375,8 +328,9 @@ module ts.formatting { } } } - - insertIndentation(currentTokenInfo.token.pos, indentation); + if (rangeContainsRange(originalRange, currentTokenInfo.token)) { + insertIndentation(currentTokenInfo.token.pos, indentation); + } //// TODO: remove //var tokenRange = getNonAdjustedLineAndCharacterFromPosition(currentTokenInfo.token.pos, sourceFile); diff --git a/src/services/formatting/new/rules.ts b/src/services/formatting/new/rules.ts index 612b8b07ad4..bb54f85ca1e 100644 --- a/src/services/formatting/new/rules.ts +++ b/src/services/formatting/new/rules.ts @@ -703,8 +703,6 @@ module ts.formatting { return false; } - //return ((token.kind === SyntaxKind.LessThanToken || token.kind === SyntaxKind.GreaterThanToken) && - // (parentKind === SyntaxKind.TypeParameterList || parentKind === SyntaxKind.TypeArgumentList)); } static IsTypeArgumentOrParameterContext(context: FormattingContext): boolean { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 4021c8b6788..57f49bc43ca 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -65,31 +65,47 @@ module ts.formatting { return 0; } - return getIndentationForNode(current, currentStart, indentationDelta, sourceFile, options); + return getIndentationForNode(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, options); } - export function getIndentationForNode(current: Node, currentStart: LineAndCharacter, indentationDelta: number, sourceFile: SourceFile, options: EditorOptions): number { - var parent: Node = current.parent; + export function getIndentationForNode( + current: Node, + currentStart: LineAndCharacter, + ignoreActualIndentationRange: TextRange, + 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; + var useActualIndentation = true; + if (ignoreActualIndentationRange) { + var start = current.getStart(sourceFile); + useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end; } + if (useActualIndentation) { + // 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; + if (useActualIndentation) { + // 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 @@ -105,6 +121,7 @@ module ts.formatting { return indentationDelta; } + /* * Function returns -1 if indentation cannot be determined */