From 67878c934c687daf4c62f08c29e2aaa5b2c27b91 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Wed, 19 Aug 2015 17:46:01 +0900 Subject: [PATCH 1/8] adding tests for JSX attributes/closing bracket --- tests/cases/fourslash/formattingJsxElements.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index d0c77804ed..3219fb396b 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -10,10 +10,24 @@ //// ) ////} //// +////function () { +//// return
/*danglingBraketAutoformat*/ +////
+////} format.document(); goTo.marker("autoformat"); verify.currentLineContentIs(' Hello, World!'); goTo.marker("indent"); -verify.indentationIs(12); \ No newline at end of file +verify.indentationIs(12); + +goTo.marker("attrAutoformat"); +verify.currentLineContentIs(' className="">'); +goTo.marker("attrIndent"); +verify.indentationIs(8); +goTo.marker("danglingBracketAutoformat") +verify.currentLineContentIs(" >"); \ No newline at end of file From 2677b3fa2624c82c56843ac8b1109a3aecfa59ee Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 22 Aug 2015 03:37:48 +0900 Subject: [PATCH 2/8] fixing autoformat not working with empty JsxText --- src/services/formatting/formatting.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 66cdbd5375..c508d8696a 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -360,7 +360,9 @@ namespace ts.formatting { range: TextRange, inheritedIndentation: number): number { - if (rangeOverlapsWithStartEnd(range, startPos, endPos)) { + if (rangeOverlapsWithStartEnd(range, startPos, endPos) || + rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) { + if (inheritedIndentation !== Constants.Unknown) { return inheritedIndentation; } @@ -387,7 +389,10 @@ namespace ts.formatting { let indentation = inheritedIndentation; if (indentation === Constants.Unknown) { - if (isSomeBlock(node.kind)) { + if (isIndentPreventedChildNode(parent.kind, node.kind)) { + indentation = parentDynamicIndentation.getIndentation(); + } + else if (isSomeBlock(node.kind)) { // blocks should be indented in // - other blocks // - source file @@ -1016,6 +1021,14 @@ namespace ts.formatting { return false; } + function isIndentPreventedChildNode(parent: SyntaxKind, child: SyntaxKind) { + switch (parent) { + case SyntaxKind.JsxElement: { + return child === SyntaxKind.JsxClosingElement; + } + } + } + function getOpenTokenForList(node: Node, list: Node[]) { switch (node.kind) { case SyntaxKind.Constructor: From eae30fd3de440dda52843b48f0929b24cf9a2651 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 22 Aug 2015 03:39:15 +0900 Subject: [PATCH 3/8] adding JSX closing tag/attribute/expression test --- src/services/formatting/smartIndenter.ts | 2 + .../cases/fourslash/formattingJsxElements.ts | 39 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index c7f762fea6..30211e0a91 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -429,6 +429,8 @@ namespace ts.formatting { case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.JsxElement: + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxExpression: return true; } return false; diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index 3219fb396b..3b98e7b5ca 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -6,7 +6,7 @@ ////
////Hello, World!/*autoformat*/ /////*indent*/ -////
+//// /*closingTagAutoformat*/ //// ) ////} //// @@ -14,20 +14,49 @@ //// return
/*danglingBraketAutoformat*/ +////id={ +////"abc" + "cde"/*expressionAutoformat*/ +/////*expressionIndent*/ +////} +//// >/*danglingBracketAutoformat*/ ////
////} - +//// +////let h5 =
+/////*childJsxElementAutoformat*/ +/////*childJsxElementIndent*/ +/////*grandchildJsxElementAutoformat*/ +/////*containedClosingTagAutoformat*/ +////
format.document(); goTo.marker("autoformat"); verify.currentLineContentIs(' Hello, World!'); goTo.marker("indent"); verify.indentationIs(12); +goTo.marker("closingTagAutoformat"); +verify.currentLineContentIs(" "); goTo.marker("attrAutoformat"); -verify.currentLineContentIs(' className="">'); +verify.currentLineContentIs(' className=""'); goTo.marker("attrIndent"); verify.indentationIs(8); +goTo.marker("expressionAutoformat"); +verify.currentLineContentIs(' "abc" + "cde"'); +goTo.marker("expressionIndent"); +verify.indentationIs(12); + + goTo.marker("danglingBracketAutoformat") -verify.currentLineContentIs(" >"); \ No newline at end of file +// TODO: verify.currentLineContentIs(" >"); +verify.currentLineContentIs(" >"); + + +goTo.marker("childJsxElementAutoformat"); +verify.currentLineContentIs(" "); +goTo.marker("childJsxElementIndent"); +verify.indentationIs(8); +goTo.marker("grandchildJsxElementAutoformat"); +verify.currentLineContentIs(" "); +goTo.marker("containedClosingTagAutoformat"); +verify.currentLineContentIs(" "); \ No newline at end of file From 060828c8b9b4747a83c89ca22bf8f2fd4695162f Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 22 Aug 2015 21:35:58 +0900 Subject: [PATCH 4/8] partially move getIndentationToken into new function --- src/services/formatting/formatting.ts | 42 +++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index c508d8696a..0b1d08e8b0 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -389,7 +389,7 @@ namespace ts.formatting { let indentation = inheritedIndentation; if (indentation === Constants.Unknown) { - if (isIndentPreventedChildNode(parent.kind, node.kind)) { + if (isIndentPreventedCoreComponent(node.kind)) { indentation = parentDynamicIndentation.getIndentation(); } else if (isSomeBlock(node.kind)) { @@ -479,21 +479,12 @@ namespace ts.formatting { return indentation; } } - switch (kind) { - // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent - case SyntaxKind.OpenBraceToken: - case SyntaxKind.CloseBraceToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.CloseBracketToken: - case SyntaxKind.OpenParenToken: - case SyntaxKind.CloseParenToken: - case SyntaxKind.ElseKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.AtToken: - 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; + if (isIndentPreventedCoreComponent(kind)) { + return indentation; + } + else { + // 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; } }, getIndentation: () => indentation, @@ -1021,11 +1012,20 @@ namespace ts.formatting { return false; } - function isIndentPreventedChildNode(parent: SyntaxKind, child: SyntaxKind) { - switch (parent) { - case SyntaxKind.JsxElement: { - return child === SyntaxKind.JsxClosingElement; - } + function isIndentPreventedCoreComponent(child: SyntaxKind) { + switch (child) { + // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent + case SyntaxKind.OpenBraceToken: + case SyntaxKind.CloseBraceToken: + case SyntaxKind.OpenBracketToken: + case SyntaxKind.CloseBracketToken: + case SyntaxKind.OpenParenToken: + case SyntaxKind.CloseParenToken: + case SyntaxKind.ElseKeyword: + case SyntaxKind.WhileKeyword: + case SyntaxKind.AtToken: + case SyntaxKind.JsxClosingElement: + return true; } } From 56fc7ec68d5117224c64d25ddf89a6fdcbce3fdf Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 22 Aug 2015 22:24:31 +0900 Subject: [PATCH 5/8] revert 060828c --- src/services/formatting/formatting.ts | 32 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 0b1d08e8b0..9a91c85db0 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -389,7 +389,7 @@ namespace ts.formatting { let indentation = inheritedIndentation; if (indentation === Constants.Unknown) { - if (isIndentPreventedCoreComponent(node.kind)) { + if (isIndentPreventedChildNode(parent.kind, node.kind)) { indentation = parentDynamicIndentation.getIndentation(); } else if (isSomeBlock(node.kind)) { @@ -479,12 +479,21 @@ namespace ts.formatting { return indentation; } } - if (isIndentPreventedCoreComponent(kind)) { - return indentation; - } - else { - // 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; + switch (kind) { + // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent + case SyntaxKind.OpenBraceToken: + case SyntaxKind.CloseBraceToken: + case SyntaxKind.OpenBracketToken: + case SyntaxKind.CloseBracketToken: + case SyntaxKind.OpenParenToken: + case SyntaxKind.CloseParenToken: + case SyntaxKind.ElseKeyword: + case SyntaxKind.WhileKeyword: + case SyntaxKind.AtToken: + 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; } }, getIndentation: () => indentation, @@ -1012,6 +1021,14 @@ namespace ts.formatting { return false; } + function isIndentPreventedChildNode(parent: SyntaxKind, child: SyntaxKind) { + switch (parent) { + case SyntaxKind.JsxElement: { + return child === SyntaxKind.JsxClosingElement; + } + } + } + function isIndentPreventedCoreComponent(child: SyntaxKind) { switch (child) { // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent @@ -1027,6 +1044,7 @@ namespace ts.formatting { case SyntaxKind.JsxClosingElement: return true; } + return false; } function getOpenTokenForList(node: Node, list: Node[]) { From 92e3b3b5faad8531d381e54c5856879b29d6d3c0 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Wed, 26 Aug 2015 01:06:37 +0900 Subject: [PATCH 6/8] remove isIndentPreventedChildNode --- src/services/formatting/formatting.ts | 29 ++------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 9a91c85db0..a3b32099cc 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -389,7 +389,8 @@ namespace ts.formatting { let indentation = inheritedIndentation; if (indentation === Constants.Unknown) { - if (isIndentPreventedChildNode(parent.kind, node.kind)) { + if (parent.kind === SyntaxKind.JsxElement && node.kind === SyntaxKind.JsxClosingElement) { + // JsxClosingElement should not be indented indentation = parentDynamicIndentation.getIndentation(); } else if (isSomeBlock(node.kind)) { @@ -1021,32 +1022,6 @@ namespace ts.formatting { return false; } - function isIndentPreventedChildNode(parent: SyntaxKind, child: SyntaxKind) { - switch (parent) { - case SyntaxKind.JsxElement: { - return child === SyntaxKind.JsxClosingElement; - } - } - } - - function isIndentPreventedCoreComponent(child: SyntaxKind) { - switch (child) { - // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent - case SyntaxKind.OpenBraceToken: - case SyntaxKind.CloseBraceToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.CloseBracketToken: - case SyntaxKind.OpenParenToken: - case SyntaxKind.CloseParenToken: - case SyntaxKind.ElseKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.AtToken: - case SyntaxKind.JsxClosingElement: - return true; - } - return false; - } - function getOpenTokenForList(node: Node, list: Node[]) { switch (node.kind) { case SyntaxKind.Constructor: From 593503f6d57bee8452fccdb42d0350d2d70a51fa Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Wed, 9 Dec 2015 23:34:13 +0900 Subject: [PATCH 7/8] move blocker to nodeWillIndentChild --- src/services/formatting/smartIndenter.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index fc2650b3b3..8e0fef884e 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -450,10 +450,9 @@ namespace ts.formatting { case SyntaxKind.ConditionalExpression: case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.JsxElement: case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxExpression: + case SyntaxKind.JsxExpression: case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: @@ -469,6 +468,7 @@ namespace ts.formatting { return false; } + /* @internal */ export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { let childKind = child ? child.kind : SyntaxKind.Unknown; switch (parent.kind) { @@ -486,6 +486,8 @@ namespace ts.formatting { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: return childKind !== SyntaxKind.Block; + case SyntaxKind.JsxElement: + return childKind !== SyntaxKind.JsxClosingElement; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; From 9e3ee5d716d439b40fe0f6838141e9890fe77c46 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Wed, 9 Dec 2015 23:42:49 +0900 Subject: [PATCH 8/8] remove whitespace --- 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 4bb3d13f65..4e48a4bf4f 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -359,7 +359,7 @@ namespace ts.formatting { parentStartLine: number, range: TextRange, inheritedIndentation: number): number { - + if (rangeOverlapsWithStartEnd(range, startPos, endPos) || rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) {