From 33fbce1ff76c8c1577f424263fb91fd22f1e1271 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 12 Sep 2015 17:05:12 +0900 Subject: [PATCH 01/11] nodeWillIndentChild from #4609 --- src/services/formatting/formatting.ts | 38 +++++++----------------- src/services/formatting/smartIndenter.ts | 36 +++++++++++++++------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index fad3ebe6e2b6b..868683bb6af89 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -282,19 +282,19 @@ namespace ts.formatting { */ function getOwnOrInheritedDelta(n: Node, options: FormatCodeOptions, sourceFile: SourceFile): number { let previousLine = Constants.Unknown; - let childKind = SyntaxKind.Unknown; + let child: Node = null; while (n) { let line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line; if (previousLine !== Constants.Unknown && line !== previousLine) { break; } - if (SmartIndenter.shouldIndentChildNode(n.kind, childKind)) { + if (SmartIndenter.shouldIndentChildNode(n, child)) { return options.IndentSize; } previousLine = line; - childKind = n.kind; + child = n; n = n.parent; } return 0; @@ -387,33 +387,17 @@ namespace ts.formatting { let indentation = inheritedIndentation; if (indentation === Constants.Unknown) { - if (isSomeBlock(node.kind)) { - // blocks should be indented in - // - other blocks - // - source file - // - switch\default clauses - if (isSomeBlock(parent.kind) || - parent.kind === SyntaxKind.SourceFile || - parent.kind === SyntaxKind.CaseClause || - parent.kind === SyntaxKind.DefaultClause) { - - indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(); - } - else { - indentation = parentDynamicIndentation.getIndentation(); - } + if (SmartIndenter.shouldInheritParentIndentation(parent, node) || + SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { + + indentation = parentDynamicIndentation.getIndentation(); } else { - if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { - indentation = parentDynamicIndentation.getIndentation(); - } - else { - indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(); - } + indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(); } } - var delta = SmartIndenter.shouldIndentChildNode(node.kind, SyntaxKind.Unknown) ? options.IndentSize : 0; + var delta = SmartIndenter.shouldIndentChildNode(node, null) ? options.IndentSize : 0; if (effectiveParentStartLine === startLine) { // if node is located on the same line with the parent @@ -495,7 +479,7 @@ namespace ts.formatting { getIndentation: () => indentation, getDelta: () => delta, recomputeIndentation: lineAdded => { - if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent.kind, node.kind)) { + if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { indentation += options.IndentSize; } @@ -503,7 +487,7 @@ namespace ts.formatting { indentation -= options.IndentSize; } - if (SmartIndenter.shouldIndentChildNode(node.kind, SyntaxKind.Unknown)) { + if (SmartIndenter.shouldIndentChildNode(node, null)) { delta = options.IndentSize; } else { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 8355fac03f5f5..ab23f3da93976 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -48,7 +48,7 @@ namespace ts.formatting { let indentationDelta: number; while (current) { - if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current.kind, previous ? previous.kind : SyntaxKind.Unknown)) { + if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous)) { currentStart = getStartLineAndCharacterForNode(current, sourceFile); if (nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile)) { @@ -133,7 +133,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.kind, current.kind) && !parentAndChildShareLine) { + if (shouldIndentChildNode(parent, current) && !parentAndChildShareLine) { indentationDelta += options.IndentSize; } @@ -446,11 +446,12 @@ namespace ts.formatting { return false; } - export function shouldIndentChildNode(parent: SyntaxKind, child: SyntaxKind): boolean { - if (nodeContentIsAlwaysIndented(parent)) { - return true; - } - switch (parent) { + /** + * Function returns true when a node with conditional indentation rule will indent certain child node. + */ + function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { + let childKind = child ? child.kind : SyntaxKind.Unknown; + switch (parent.kind) { case SyntaxKind.DoStatement: case SyntaxKind.WhileStatement: case SyntaxKind.ForInStatement: @@ -464,10 +465,25 @@ namespace ts.formatting { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return child !== SyntaxKind.Block; - default: - return false; + return childKind !== SyntaxKind.Block; + } + // No explicit rule for selected nodes, so result will follow the default value argument. + return indentByDefault; + } + + export function shouldIndentChildNode(parent: TextRangeWithKind, child: TextRangeWithKind): boolean { + if (nodeContentIsAlwaysIndented(parent.kind)) { + return true; } + return nodeWillIndentChild(parent, child, false); + } + + /** + * Function returns true if a node should not get additional indentation in its parent node. + */ + export function shouldInheritParentIndentation(parent: TextRangeWithKind, child: TextRangeWithKind): boolean { + // Check if + return !nodeWillIndentChild(parent, child, true); } } } \ No newline at end of file From 07fbf8bfd1358a9048c6af3d2742b0decc461ee4 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 12 Sep 2015 17:31:12 +0900 Subject: [PATCH 02/11] Fix some comments --- src/services/formatting/smartIndenter.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index ab23f3da93976..4477ea760bb79 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -447,7 +447,7 @@ namespace ts.formatting { } /** - * Function returns true when a node with conditional indentation rule will indent certain child node. + * Function returns true when a node with conditional indentation rule will indent certain child node */ function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { let childKind = child ? child.kind : SyntaxKind.Unknown; @@ -467,7 +467,7 @@ namespace ts.formatting { case SyntaxKind.SetAccessor: return childKind !== SyntaxKind.Block; } - // No explicit rule for selected nodes, so result will follow the default value argument. + // No explicit rule for selected nodes, so result will follow the default value argument return indentByDefault; } @@ -479,10 +479,11 @@ namespace ts.formatting { } /** - * Function returns true if a node should not get additional indentation in its parent node. + * Function returns true if existing node content indentation should be suppressed for a specific child */ export function shouldInheritParentIndentation(parent: TextRangeWithKind, child: TextRangeWithKind): boolean { - // Check if + // Consider parents without indentation rules can indent their children + // so that they can apply inherited delta value to them return !nodeWillIndentChild(parent, child, true); } } From f2329846cbc52074f9eb0affaecae2e406880dd5 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sun, 13 Sep 2015 04:02:18 +0900 Subject: [PATCH 03/11] apply suppression to tokens --- src/services/formatting/formatting.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 868683bb6af89..8a713dc032c82 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -387,9 +387,7 @@ namespace ts.formatting { let indentation = inheritedIndentation; if (indentation === Constants.Unknown) { - if (SmartIndenter.shouldInheritParentIndentation(parent, node) || - SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { - + if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { indentation = parentDynamicIndentation.getIndentation(); } else { @@ -590,6 +588,10 @@ namespace ts.formatting { return inheritedIndentation; } + if (SmartIndenter.shouldInheritParentIndentation(parent, child)) { + parentDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation, 0); + } + 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); From 46c8af10245751fc51880191a559a1ae27706115 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sun, 13 Sep 2015 07:47:16 +0900 Subject: [PATCH 04/11] make getDelta call suppressor --- src/services/formatting/formatting.ts | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 8a713dc032c82..5d4938498e420 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -54,7 +54,7 @@ namespace ts.formatting { * so bar inherits indentation from foo and bar.delta will be 4 * */ - getDelta(): number; + getDelta(child: TextRangeWithKind): number; /** * Formatter calls this function when rule adds or deletes new lines from the text * so indentation scope can adjust values of indentation and delta. @@ -386,15 +386,6 @@ namespace ts.formatting { effectiveParentStartLine: number): Indentation { let indentation = inheritedIndentation; - if (indentation === Constants.Unknown) { - if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { - indentation = parentDynamicIndentation.getIndentation(); - } - else { - indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(); - } - } - var delta = SmartIndenter.shouldIndentChildNode(node, null) ? options.IndentSize : 0; if (effectiveParentStartLine === startLine) { @@ -404,8 +395,17 @@ namespace ts.formatting { indentation = startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(); - delta = Math.min(options.IndentSize, parentDynamicIndentation.getDelta() + delta); + delta = Math.min(options.IndentSize, parentDynamicIndentation.getDelta(node) + delta); + } + else if (indentation === Constants.Unknown) { + if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { + indentation = parentDynamicIndentation.getIndentation(); + } + else { + indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node); + } } + return { indentation, delta @@ -475,7 +475,14 @@ namespace ts.formatting { } }, getIndentation: () => indentation, - getDelta: () => delta, + getDelta: (child: TextRangeWithKind) => { + if (SmartIndenter.shouldInheritParentIndentation(node, child)) { + return 0; + } + else { + return delta; + } + }, recomputeIndentation: lineAdded => { if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { @@ -588,10 +595,6 @@ namespace ts.formatting { return inheritedIndentation; } - if (SmartIndenter.shouldInheritParentIndentation(parent, child)) { - parentDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation, 0); - } - 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); From 4d1c067d752cd165ce2b69545629621033b93e4c Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sun, 13 Sep 2015 16:01:32 +0900 Subject: [PATCH 05/11] use undefined instead of null --- src/services/formatting/formatting.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 5d4938498e420..eeebfd1649d4a 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -282,7 +282,7 @@ namespace ts.formatting { */ function getOwnOrInheritedDelta(n: Node, options: FormatCodeOptions, sourceFile: SourceFile): number { let previousLine = Constants.Unknown; - let child: Node = null; + let child: Node; while (n) { let line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line; if (previousLine !== Constants.Unknown && line !== previousLine) { From b2cfddbe7a30c05ebac112af556974fa16913a9e Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sun, 13 Sep 2015 23:42:24 +0900 Subject: [PATCH 06/11] re-fix token indentation --- src/services/formatting/formatting.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index eeebfd1649d4a..9f300f1db7aaa 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -60,6 +60,11 @@ namespace ts.formatting { * so indentation scope can adjust values of indentation and delta. */ recomputeIndentation(lineAddedByFormatting: boolean): void; + + /** + * Returns DynamicIndentation object that includes modified delta value for specific child node. + */ + getCopyForSpecificChild(child: Node): DynamicIndentation; } interface Indentation { @@ -475,14 +480,7 @@ namespace ts.formatting { } }, getIndentation: () => indentation, - getDelta: (child: TextRangeWithKind) => { - if (SmartIndenter.shouldInheritParentIndentation(node, child)) { - return 0; - } - else { - return delta; - } - }, + getDelta: (child) => (!delta || SmartIndenter.shouldInheritParentIndentation(node, child)) ? 0 : delta, recomputeIndentation: lineAdded => { if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { @@ -500,6 +498,13 @@ namespace ts.formatting { } } }, + getCopyForSpecificChild(child) { + if (!delta) { + // delta value is already 0, so do not copy + return this; + } + return getDynamicIndentation(node, nodeStartLine, indentation, (this).getDelta(child)); + } } } @@ -599,7 +604,7 @@ namespace ts.formatting { // 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); + consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation.getCopyForSpecificChild(child)); return inheritedIndentation; } From 3dd7caafbfc0bf2cf15d910c27c585cd8237ae8e Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Tue, 22 Sep 2015 15:07:44 +0900 Subject: [PATCH 07/11] no null --- src/services/formatting/formatting.ts | 4 ++-- src/services/formatting/smartIndenter.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 9f300f1db7aaa..412daaa8ab0f0 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -391,7 +391,7 @@ namespace ts.formatting { effectiveParentStartLine: number): Indentation { let indentation = inheritedIndentation; - var delta = SmartIndenter.shouldIndentChildNode(node, null) ? options.IndentSize : 0; + var delta = SmartIndenter.shouldIndentChildNode(node) ? options.IndentSize : 0; if (effectiveParentStartLine === startLine) { // if node is located on the same line with the parent @@ -490,7 +490,7 @@ namespace ts.formatting { indentation -= options.IndentSize; } - if (SmartIndenter.shouldIndentChildNode(node, null)) { + if (SmartIndenter.shouldIndentChildNode(node)) { delta = options.IndentSize; } else { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 4477ea760bb79..dfe94b3fdbb7d 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -471,7 +471,7 @@ namespace ts.formatting { return indentByDefault; } - export function shouldIndentChildNode(parent: TextRangeWithKind, child: TextRangeWithKind): boolean { + export function shouldIndentChildNode(parent: TextRangeWithKind, child?: TextRangeWithKind): boolean { if (nodeContentIsAlwaysIndented(parent.kind)) { return true; } From f9e8d9562d91af7a77454b40d60c28162dac9079 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Tue, 22 Sep 2015 16:32:24 +0900 Subject: [PATCH 08/11] slight condition change for getDelta --- src/services/formatting/formatting.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 412daaa8ab0f0..4995fb34b543b 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -480,7 +480,7 @@ namespace ts.formatting { } }, getIndentation: () => indentation, - getDelta: (child) => (!delta || SmartIndenter.shouldInheritParentIndentation(node, child)) ? 0 : delta, + getDelta: (child) => (delta && SmartIndenter.shouldInheritParentIndentation(node, child)) ? 0 : delta, recomputeIndentation: lineAdded => { if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { From f53f70d79e2ca35f3b653ee90a0b10152931073b Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Tue, 29 Sep 2015 16:09:07 +0900 Subject: [PATCH 09/11] getEffectiveDelta --- src/services/formatting/formatting.ts | 76 ++++++++++++--------------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 4995fb34b543b..0bd2a47bb1e8e 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -31,8 +31,8 @@ namespace ts.formatting { * the first token in line so it should be indented */ interface DynamicIndentation { - getIndentationForToken(tokenLine: number, tokenKind: SyntaxKind): number; - getIndentationForComment(owningToken: SyntaxKind, tokenIndentation: number): number; + getIndentationForToken(tokenLine: number, tokenKind: SyntaxKind, container: Node): number; + getIndentationForComment(owningToken: SyntaxKind, tokenIndentation: number, container: Node): number; /** * Indentation for open and close tokens of the node if it is block or another node that needs special indentation * ... { @@ -60,11 +60,6 @@ namespace ts.formatting { * so indentation scope can adjust values of indentation and delta. */ recomputeIndentation(lineAddedByFormatting: boolean): void; - - /** - * Returns DynamicIndentation object that includes modified delta value for specific child node. - */ - getCopyForSpecificChild(child: Node): DynamicIndentation; } interface Indentation { @@ -330,7 +325,7 @@ namespace ts.formatting { let lastIndentedLine: number; let indentationOnLastIndentedLine: number; - + let edits: TextChange[] = []; formattingScanner.advance(); @@ -359,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; @@ -381,7 +376,7 @@ namespace ts.formatting { return Constants.Unknown; } - + function computeIndentation( node: TextRangeWithKind, startLine: number, @@ -397,8 +392,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(node) + delta); } @@ -442,7 +437,7 @@ namespace ts.formatting { function getDynamicIndentation(node: Node, nodeStartLine: number, indentation: number, delta: number): DynamicIndentation { return { - getIndentationForComment: (kind, tokenIndentation) => { + getIndentationForComment: (kind, tokenIndentation, container) => { switch (kind) { // preceding comment to the token that closes the indentation scope inherits the indentation from the scope // .. { @@ -451,11 +446,11 @@ namespace ts.formatting { case SyntaxKind.CloseBraceToken: case SyntaxKind.CloseBracketToken: case SyntaxKind.CloseParenToken: - return indentation + delta; + return indentation + getEffectiveDelta(delta, container); } return tokenIndentation !== Constants.Unknown ? tokenIndentation : indentation; }, - getIndentationForToken: (line, kind) => { + getIndentationForToken: (line, kind, container) => { if (nodeStartLine !== line && node.decorators) { if (kind === getFirstNonDecoratorTokenOfNode(node)) { // if this token is the first token following the list of decorators, we do not need to indent @@ -476,11 +471,11 @@ namespace ts.formatting { return indentation; default: // if token line equals to the line of containing node (this is a first token in the node) - use node indentation - return nodeStartLine !== line ? indentation + delta : indentation; + return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation; } }, getIndentation: () => indentation, - getDelta: (child) => (delta && SmartIndenter.shouldInheritParentIndentation(node, child)) ? 0 : delta, + getDelta: (child) => getEffectiveDelta(delta, child), recomputeIndentation: lineAdded => { if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { @@ -497,15 +492,12 @@ namespace ts.formatting { delta = 0; } } - }, - getCopyForSpecificChild(child) { - if (!delta) { - // delta value is already 0, so do not copy - return this; - } - return getDynamicIndentation(node, nodeStartLine, indentation, (this).getDelta(child)); } } + + function getEffectiveDelta(delta: number, child: TextRangeWithKind) { + return SmartIndenter.shouldInheritParentIndentation(node, child) ? 0 : delta; + } } function processNode(node: Node, contextNode: Node, nodeStartLine: number, undecoratedNodeStartLine: number, indentation: number, delta: number) { @@ -580,7 +572,7 @@ namespace ts.formatting { if (!rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) { return inheritedIndentation; } - + if (child.getFullWidth() === 0) { return inheritedIndentation; } @@ -604,7 +596,7 @@ namespace ts.formatting { // 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.getCopyForSpecificChild(child)); + consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child); return inheritedIndentation; } @@ -618,8 +610,8 @@ namespace ts.formatting { return inheritedIndentation; } - function processChildNodes(nodes: NodeArray, - parent: Node, + function processChildNodes(nodes: NodeArray, + parent: Node, parentStartLine: number, parentDynamicIndentation: DynamicIndentation): void { @@ -673,7 +665,7 @@ namespace ts.formatting { } } - function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: Node, dynamicIndentation: DynamicIndentation): void { + function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: Node, dynamicIndentation: DynamicIndentation, container?: Node): void { Debug.assert(rangeContainsRange(parent, currentTokenInfo.token)); let lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine(); @@ -712,11 +704,11 @@ namespace ts.formatting { if (indentToken) { let tokenIndentation = (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) ? - dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind) : + dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container) : Constants.Unknown; if (currentTokenInfo.leadingTrivia) { - let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation); + let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container); let indentNextTokenOrTrivia = true; for (let triviaItem of currentTokenInfo.leadingTrivia) { @@ -745,7 +737,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; } @@ -766,12 +758,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) { @@ -781,7 +773,7 @@ namespace ts.formatting { trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line); } else { - lineAdded = + lineAdded = processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation) } } From 9eb85e21731e5516f45b4e00e0fc0127002ad2c6 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Tue, 29 Sep 2015 19:50:42 +0900 Subject: [PATCH 10/11] remove parens --- src/services/formatting/formatting.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 0bd2a47bb1e8e..7d559f9946497 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -475,7 +475,7 @@ namespace ts.formatting { } }, getIndentation: () => indentation, - getDelta: (child) => getEffectiveDelta(delta, child), + getDelta: child => getEffectiveDelta(delta, child), recomputeIndentation: lineAdded => { if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { From 34b303a9c5caad182f0fafd5b60302333bcd4dce Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Tue, 8 Dec 2015 21:39:46 +0900 Subject: [PATCH 11/11] directly expose nodeWillIndentChild --- src/services/formatting/formatting.ts | 3 ++- src/services/formatting/smartIndenter.ts | 26 +++++++----------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index ee47e4fc98e36..55adb7b723353 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -496,7 +496,8 @@ namespace ts.formatting { } function getEffectiveDelta(delta: number, child: TextRangeWithKind) { - return SmartIndenter.shouldInheritParentIndentation(node, child) ? 0 : delta; + // Delta value should be zero when the node explicitly prevents indentation of the child node + return SmartIndenter.nodeWillIndentChild(node, child, true) ? delta : 0; } } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 83ef1df714413..9ede3691fc0de 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -465,11 +465,8 @@ namespace ts.formatting { } return false; } - - /** - * Function returns true when a node with conditional indentation rule will indent certain child node - */ - function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { + + export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { let childKind = child ? child.kind : SyntaxKind.Unknown; switch (parent.kind) { case SyntaxKind.DoStatement: @@ -487,24 +484,15 @@ namespace ts.formatting { case SyntaxKind.SetAccessor: return childKind !== SyntaxKind.Block; } - // No explicit rule for selected nodes, so result will follow the default value argument + // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; } + /* + Function returns true when the parent node should indent the given child by an explicit rule + */ export function shouldIndentChildNode(parent: TextRangeWithKind, child?: TextRangeWithKind): boolean { - if (nodeContentIsAlwaysIndented(parent.kind)) { - return true; - } - return nodeWillIndentChild(parent, child, false); - } - - /** - * Function returns true if existing node content indentation should be suppressed for a specific child - */ - export function shouldInheritParentIndentation(parent: TextRangeWithKind, child: TextRangeWithKind): boolean { - // Consider parents without indentation rules can indent their children - // so that they can apply inherited delta value to them - return !nodeWillIndentChild(parent, child, true); + return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false); } } }