diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index fad3ebe6e2b..fe313cb1edd 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -325,7 +325,7 @@ namespace ts.formatting { let lastIndentedLine: number; let indentationOnLastIndentedLine: number; - + let edits: TextChange[] = []; formattingScanner.advance(); @@ -354,12 +354,12 @@ namespace ts.formatting { * If list element is in the range - its indentation will be equal * to inherited indentation from its predecessors. */ - function tryComputeIndentationForListItem(startPos: number, - endPos: number, - parentStartLine: number, - range: TextRange, + function tryComputeIndentationForListItem(startPos: number, + endPos: number, + parentStartLine: number, + range: TextRange, inheritedIndentation: number): number { - + if (rangeOverlapsWithStartEnd(range, startPos, endPos)) { if (inheritedIndentation !== Constants.Unknown) { return inheritedIndentation; @@ -376,7 +376,7 @@ namespace ts.formatting { return Constants.Unknown; } - + function computeIndentation( node: TextRangeWithKind, startLine: number, @@ -419,8 +419,8 @@ namespace ts.formatting { // if node is located on the same line with the parent // - inherit indentation from the parent // - push children if either parent of node itself has non-zero delta - indentation = startLine === lastIndentedLine - ? indentationOnLastIndentedLine + indentation = startLine === lastIndentedLine + ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(); delta = Math.min(options.IndentSize, parentDynamicIndentation.getDelta() + delta); } @@ -445,7 +445,7 @@ namespace ts.formatting { if ((node).asteriskToken) { return SyntaxKind.AsteriskToken; } - // fall-through + // fall-through case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: @@ -586,7 +586,7 @@ namespace ts.formatting { if (!rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) { return inheritedIndentation; } - + if (child.getFullWidth() === 0) { return inheritedIndentation; } @@ -609,6 +609,9 @@ namespace ts.formatting { if (isToken(child)) { // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules let tokenInfo = formattingScanner.readTokenInfo(child); + + + Debug.assert(tokenInfo.token.end === child.end); consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation); return inheritedIndentation; @@ -624,8 +627,8 @@ namespace ts.formatting { return inheritedIndentation; } - function processChildNodes(nodes: NodeArray, - parent: Node, + function processChildNodes(nodes: NodeArray, + parent: Node, parentStartLine: number, parentDynamicIndentation: DynamicIndentation): void { @@ -751,7 +754,7 @@ namespace ts.formatting { // indent token only if is it is in target range and does not overlap with any error ranges if (tokenIndentation !== Constants.Unknown) { insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded); - + lastIndentedLine = tokenStart.line; indentationOnLastIndentedLine = tokenIndentation; } @@ -772,12 +775,12 @@ namespace ts.formatting { } } - function processRange(range: TextRangeWithKind, - rangeStart: LineAndCharacter, - parent: Node, - contextNode: Node, + function processRange(range: TextRangeWithKind, + rangeStart: LineAndCharacter, + parent: Node, + contextNode: Node, dynamicIndentation: DynamicIndentation): boolean { - + let rangeHasError = rangeContainsError(range); let lineAdded: boolean; if (!rangeHasError && !previousRangeHasError) { @@ -787,8 +790,8 @@ namespace ts.formatting { trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line); } else { - lineAdded = - processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation) + lineAdded = + processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation) } } @@ -933,8 +936,8 @@ namespace ts.formatting { let lineStartPosition = getStartPositionOfLine(line, sourceFile); let lineEndPosition = getEndLinePosition(line, sourceFile); - // do not trim whitespaces in comments - if (range && isComment(range.kind) && range.pos <= lineEndPosition && range.end > lineEndPosition) { + // do not trim whitespaces in comments or template expression + if (range && (isComment(range.kind) || isTemplate(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) { continue; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 8b77dcb953b..f08f3f38460 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -562,6 +562,10 @@ namespace ts { return kind === SyntaxKind.SingleLineCommentTrivia || kind === SyntaxKind.MultiLineCommentTrivia; } + export function isTemplate(kind: SyntaxKind): boolean { + return kind >= SyntaxKind.FirstTemplateToken && kind <= SyntaxKind.LastTemplateToken; + } + export function isPunctuation(kind: SyntaxKind): boolean { return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation; }