From 1ced600efecd61010aac0551aa054f7a19c5d9e1 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 26 Mar 2018 17:53:50 -0700 Subject: [PATCH] pass in sourceFile and revert child to `TextRangeOfKind` --- src/services/formatting/formatting.ts | 8 ++++---- src/services/formatting/smartIndenter.ts | 23 ++++++++++------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 8b60952d4f6..e1825a4411c 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -328,7 +328,7 @@ namespace ts.formatting { break; } - if (SmartIndenter.shouldIndentChildNode(n, child)) { + if (SmartIndenter.shouldIndentChildNode(n, child, sourceFile)) { return options.indentSize; } @@ -514,7 +514,7 @@ namespace ts.formatting { if ((node).asteriskToken) { return SyntaxKind.AsteriskToken; } - // falls through + // falls through case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: return getNameOfDeclaration(node).kind; @@ -541,7 +541,7 @@ namespace ts.formatting { getIndentation: () => indentation, getDelta, recomputeIndentation: lineAdded => { - if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { + if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node, sourceFile)) { indentation += lineAdded ? options.indentSize : -options.indentSize; delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0; } @@ -583,7 +583,7 @@ namespace ts.formatting { function getDelta(child: Node) { // Delta value should be zero when the node explicitly prevents indentation of the child node - return SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0; + return SmartIndenter.nodeWillIndentChild(node, child, sourceFile, /*indentByDefault*/ true) ? delta : 0; } } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 23256b6b754..99d57668b27 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -112,7 +112,7 @@ namespace ts.formatting { let previous: Node | undefined; let current = precedingToken; while (current) { - if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous, /*isNextChild*/ true)) { + if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous, sourceFile, /*isNextChild*/ true)) { const currentStart = getStartLineAndCharacterForNode(current, sourceFile); const nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile); const indentationDelta = nextTokenKind !== NextTokenKind.Unknown @@ -193,7 +193,7 @@ namespace ts.formatting { } // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line - if (shouldIndentChildNode(parent, current, isNextChild) && !parentAndChildShareLine) { + if (shouldIndentChildNode(parent, current, sourceFile, isNextChild) && !parentAndChildShareLine) { indentationDelta += options.indentSize; } @@ -531,21 +531,18 @@ namespace ts.formatting { return false; } - export function nodeWillIndentChild(parent: TextRangeWithKind, child: Node | undefined, indentByDefault: boolean): boolean { + export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind | undefined, sourceFile: SourceFileLike | undefined, indentByDefault: boolean): boolean { const childKind = child ? child.kind : SyntaxKind.Unknown; switch (parent.kind) { case SyntaxKind.VariableDeclaration: case SyntaxKind.PropertyAssignment: case SyntaxKind.ObjectLiteralExpression: - if (childKind === SyntaxKind.ObjectLiteralExpression) { - const sourceFile = child.getSourceFile(); - if (sourceFile) { - // May not be defined for synthesized nodes. - const startLine = sourceFile.getLineAndCharacterOfPosition(child.getStart()).line; - const endLine = sourceFile.getLineAndCharacterOfPosition(child.getEnd()).line; - return startLine === endLine; - } + if (sourceFile && childKind === SyntaxKind.ObjectLiteralExpression) { + const childStart = skipTrivia(sourceFile.text, child.pos); + const startLine = sourceFile.getLineAndCharacterOfPosition(childStart).line; + const endLine = sourceFile.getLineAndCharacterOfPosition(child.end).line; + return startLine === endLine; } break; case SyntaxKind.DoStatement: @@ -599,8 +596,8 @@ namespace ts.formatting { * True when the parent node should indent the given child by an explicit rule. * @param isNextChild If true, we are judging indent of a hypothetical child *after* this one, not the current child. */ - export function shouldIndentChildNode(parent: TextRangeWithKind, child?: Node, isNextChild = false): boolean { - return (nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false)) + export function shouldIndentChildNode(parent: TextRangeWithKind, child?: Node, sourceFile?: SourceFileLike, isNextChild = false): boolean { + return (nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, sourceFile, /*indentByDefault*/ false)) && !(isNextChild && child && isControlFlowEndingStatement(child.kind, parent)); } }