From 6a789b3a7d8df7380b5283d23dd7b4bcba319602 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Thu, 3 Dec 2015 12:38:10 +0900 Subject: [PATCH 1/4] format conditional expression based on #4757 --- src/services/formatting/smartIndenter.ts | 3 ++- .../fourslash/formatConditionalExpressions.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/formatConditionalExpressions.ts diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 18b0479c85a30..415c940e07827 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -463,7 +463,6 @@ namespace ts.formatting { case SyntaxKind.VariableDeclaration: case SyntaxKind.ExportAssignment: case SyntaxKind.ReturnStatement: - case SyntaxKind.ConditionalExpression: case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.JsxOpeningElement: @@ -512,6 +511,8 @@ namespace ts.formatting { ((child).namedBindings && (child).namedBindings.kind !== SyntaxKind.NamedImports); case SyntaxKind.JsxElement: return childKind !== SyntaxKind.JsxClosingElement; + case SyntaxKind.ConditionalExpression: + return (parent as ConditionalExpression).whenFalse !== child; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; diff --git a/tests/cases/fourslash/formatConditionalExpressions.ts b/tests/cases/fourslash/formatConditionalExpressions.ts new file mode 100644 index 0000000000000..f810c7e17d34d --- /dev/null +++ b/tests/cases/fourslash/formatConditionalExpressions.ts @@ -0,0 +1,18 @@ +/// + +////let v = +//// 0 ? 1 : +//// // +/////*falseBranchExpression*/ 2 ? 3 : +/////*indent*/ +//// // +/////*falseBranchToken*/ 2; + +format.document(); + +goTo.marker("falseBranchExpression"); +verify.currentLineContentIs(" 2 ? 3 :"); +goTo.marker("indent"); +verify.indentationIs(8); +goTo.marker("falseBranchToken"); +verify.currentLineContentIs(" 2;"); \ No newline at end of file From 8d5c8fb2a815d0efbd1056084f8548c4651afff8 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sat, 17 Dec 2016 14:15:42 +0900 Subject: [PATCH 2/4] add formatting options to shouldIndentChildNode --- src/harness/fourslash.ts | 1 + src/server/utilities.ts | 1 + src/services/formatting/formatting.ts | 10 ++--- src/services/formatting/smartIndenter.ts | 16 +++---- src/services/types.ts | 3 +- .../formattingOptionsChangeTernary.ts | 44 +++++++++++++++++++ 6 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 tests/cases/fourslash/formattingOptionsChangeTernary.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 8f19b83c7ada5..1aad267df4dac 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -376,6 +376,7 @@ namespace FourSlash { insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceAfterTypeAssertion: false, + indentInsideTernaryOperator: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 093958b60c55f..1853a543bb8ba 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -90,6 +90,7 @@ namespace ts.server { insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceBeforeFunctionParenthesis: false, + indentInsideTernaryOperator: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 531b768f6d80f..d0a0b80f80f09 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -303,7 +303,7 @@ namespace ts.formatting { break; } - if (SmartIndenter.shouldIndentChildNode(n, child)) { + if (SmartIndenter.shouldIndentChildNode(n, options, child)) { return options.indentSize; } @@ -443,7 +443,7 @@ namespace ts.formatting { effectiveParentStartLine: number): Indentation { let indentation = inheritedIndentation; - let delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0; + let delta = SmartIndenter.shouldIndentChildNode(node, options) ? options.indentSize : 0; if (effectiveParentStartLine === startLine) { // if node is located on the same line with the parent @@ -547,7 +547,7 @@ namespace ts.formatting { getIndentation: () => indentation, getDelta: child => getEffectiveDelta(delta, child), recomputeIndentation: lineAdded => { - if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { + if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, options, node)) { if (lineAdded) { indentation += options.indentSize; } @@ -555,7 +555,7 @@ namespace ts.formatting { indentation -= options.indentSize; } - if (SmartIndenter.shouldIndentChildNode(node)) { + if (SmartIndenter.shouldIndentChildNode(node, options)) { delta = options.indentSize; } else { @@ -567,7 +567,7 @@ namespace ts.formatting { function getEffectiveDelta(delta: number, child: TextRangeWithKind) { // 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, /*indentByDefault*/ true, options) ? delta : 0; } } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 415c940e07827..7224ffa15a4d9 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -20,7 +20,7 @@ namespace ts.formatting { * when inserting some text after open brace we would like to get the value of indentation as if newline was already there. * However by default indentation at position | will be 0 so 'assumeNewLineBeforeCloseBrace' allows to override this behavior, */ - export function getIndentation(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { + export function getIndentation(position: number, sourceFile: SourceFile, options: FormatCodeSettings, assumeNewLineBeforeCloseBrace = false): number { if (position > sourceFile.text.length) { return getBaseIndentation(options); // past EOF } @@ -80,7 +80,7 @@ namespace ts.formatting { let indentationDelta: number; while (current) { - if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous)) { + if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, options, previous)) { currentStart = getStartLineAndCharacterForNode(current, sourceFile); const nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile); @@ -131,7 +131,7 @@ namespace ts.formatting { ignoreActualIndentationRange: TextRange, indentationDelta: number, sourceFile: SourceFile, - options: EditorSettings): number { + options: FormatCodeSettings): number { let parent: Node = current.parent; let parentStart: LineAndCharacter; @@ -170,7 +170,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) && !parentAndChildShareLine) { + if (shouldIndentChildNode(parent, options, current) && !parentAndChildShareLine) { indentationDelta += options.indentSize; } @@ -487,7 +487,7 @@ namespace ts.formatting { } /* @internal */ - export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { + export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean, options: FormatCodeSettings) { const childKind = child ? child.kind : SyntaxKind.Unknown; switch (parent.kind) { case SyntaxKind.DoStatement: @@ -512,7 +512,7 @@ namespace ts.formatting { case SyntaxKind.JsxElement: return childKind !== SyntaxKind.JsxClosingElement; case SyntaxKind.ConditionalExpression: - return (parent as ConditionalExpression).whenFalse !== child; + return options.indentInsideTernaryOperator || (parent as ConditionalExpression).whenFalse !== child; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; @@ -521,8 +521,8 @@ namespace ts.formatting { /* Function returns true when the parent node should indent the given child by an explicit rule */ - export function shouldIndentChildNode(parent: TextRangeWithKind, child?: TextRangeWithKind): boolean { - return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false); + export function shouldIndentChildNode(parent: TextRangeWithKind, options: FormatCodeSettings, child?: TextRangeWithKind): boolean { + return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false, options); } } } diff --git a/src/services/types.ts b/src/services/types.ts index e042276e65002..ff7bbec0c01e1 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -250,7 +250,7 @@ namespace ts { getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; - getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | EditorSettings): number; + getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | FormatCodeSettings): number; getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): TextChange[]; getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[]; @@ -472,6 +472,7 @@ namespace ts { insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceAfterTypeAssertion?: boolean; insertSpaceBeforeFunctionParenthesis?: boolean; + indentInsideTernaryOperator?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; } diff --git a/tests/cases/fourslash/formattingOptionsChangeTernary.ts b/tests/cases/fourslash/formattingOptionsChangeTernary.ts new file mode 100644 index 0000000000000..0e170a26f7105 --- /dev/null +++ b/tests/cases/fourslash/formattingOptionsChangeTernary.ts @@ -0,0 +1,44 @@ +/// + +////const expectedScanAction = +//// shouldRescanGreaterThanToken(n) +//// ? ScanAction.RescanGreaterThanToken +//// : shouldRescanSlashToken(n) +//// ? ScanAction.RescanSlashToken +//// : shouldRescanTemplateToken(n) +//// ? ScanAction.RescanTemplateToken +//// : shouldRescanJsxIdentifier(n) +//// ? ScanAction.RescanJsxIdentifier +//// : shouldRescanJsxText(n) +//// ? ScanAction.RescanJsxText +//// : ScanAction.Scan; + +format.setOption("indentInsideTernaryOperator", false); +format.document(); +verify.currentFileContentIs(`const expectedScanAction = + shouldRescanGreaterThanToken(n) + ? ScanAction.RescanGreaterThanToken + : shouldRescanSlashToken(n) + ? ScanAction.RescanSlashToken + : shouldRescanTemplateToken(n) + ? ScanAction.RescanTemplateToken + : shouldRescanJsxIdentifier(n) + ? ScanAction.RescanJsxIdentifier + : shouldRescanJsxText(n) + ? ScanAction.RescanJsxText + : ScanAction.Scan;`) + +format.setOption("indentInsideTernaryOperator", true); +format.document(); +verify.currentFileContentIs(`const expectedScanAction = + shouldRescanGreaterThanToken(n) + ? ScanAction.RescanGreaterThanToken + : shouldRescanSlashToken(n) + ? ScanAction.RescanSlashToken + : shouldRescanTemplateToken(n) + ? ScanAction.RescanTemplateToken + : shouldRescanJsxIdentifier(n) + ? ScanAction.RescanJsxIdentifier + : shouldRescanJsxText(n) + ? ScanAction.RescanJsxText + : ScanAction.Scan;`) \ No newline at end of file From 590ac4c4534d98813626622805a567b00dec6ece Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Fri, 26 May 2017 18:51:36 +0900 Subject: [PATCH 3/4] optional indentation on text changes --- src/services/textChanges.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 5aa4ebca7d088..0b90645d16620 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -470,7 +470,7 @@ namespace ts.textChanges { const delta = change.options.delta !== undefined ? change.options.delta - : formatting.SmartIndenter.shouldIndentChildNode(change.node) + : formatting.SmartIndenter.shouldIndentChildNode(change.node, formatOptions) ? formatOptions.indentSize : 0; From 53f75f9137030af8adcaefa664bd0e6d72c630e3 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sat, 27 May 2017 05:03:34 +0900 Subject: [PATCH 4/4] add on protocol.ts + renaming --- src/harness/fourslash.ts | 2 +- src/server/protocol.ts | 1 + src/server/utilities.ts | 2 +- src/services/formatting/smartIndenter.ts | 2 +- src/services/types.ts | 2 +- tests/cases/fourslash/formattingOptionsChangeTernary.ts | 4 ++-- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 1aad267df4dac..7adaba1c41295 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -376,7 +376,7 @@ namespace FourSlash { insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceAfterTypeAssertion: false, - indentInsideTernaryOperator: false, + indentConditionalExpressionFalseBranch: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 4e474edd0c441..4058b18016ec9 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2321,6 +2321,7 @@ namespace ts.server.protocol { insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceAfterTypeAssertion?: boolean; insertSpaceBeforeFunctionParenthesis?: boolean; + indentConditionalExpressionFalseBranch?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 1853a543bb8ba..4cdbd2007ba3f 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -90,7 +90,7 @@ namespace ts.server { insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceBeforeFunctionParenthesis: false, - indentInsideTernaryOperator: false, + indentConditionalExpressionFalseBranch: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 7224ffa15a4d9..d6af5ceeb626d 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -512,7 +512,7 @@ namespace ts.formatting { case SyntaxKind.JsxElement: return childKind !== SyntaxKind.JsxClosingElement; case SyntaxKind.ConditionalExpression: - return options.indentInsideTernaryOperator || (parent as ConditionalExpression).whenFalse !== child; + return options.indentConditionalExpressionFalseBranch || (parent as ConditionalExpression).whenFalse !== child; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; diff --git a/src/services/types.ts b/src/services/types.ts index ff7bbec0c01e1..49858bd2b5601 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -472,7 +472,7 @@ namespace ts { insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceAfterTypeAssertion?: boolean; insertSpaceBeforeFunctionParenthesis?: boolean; - indentInsideTernaryOperator?: boolean; + indentConditionalExpressionFalseBranch?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; } diff --git a/tests/cases/fourslash/formattingOptionsChangeTernary.ts b/tests/cases/fourslash/formattingOptionsChangeTernary.ts index 0e170a26f7105..8af415b9b74f1 100644 --- a/tests/cases/fourslash/formattingOptionsChangeTernary.ts +++ b/tests/cases/fourslash/formattingOptionsChangeTernary.ts @@ -13,7 +13,7 @@ //// ? ScanAction.RescanJsxText //// : ScanAction.Scan; -format.setOption("indentInsideTernaryOperator", false); +format.setOption("indentConditionalExpressionFalseBranch", false); format.document(); verify.currentFileContentIs(`const expectedScanAction = shouldRescanGreaterThanToken(n) @@ -28,7 +28,7 @@ verify.currentFileContentIs(`const expectedScanAction = ? ScanAction.RescanJsxText : ScanAction.Scan;`) -format.setOption("indentInsideTernaryOperator", true); +format.setOption("indentConditionalExpressionFalseBranch", true); format.document(); verify.currentFileContentIs(`const expectedScanAction = shouldRescanGreaterThanToken(n)