-
Notifications
You must be signed in to change notification settings - Fork 12.9k
CSharp Style Object Literal Formatting #22849
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSharp Style Object Literal Formatting #22849
Conversation
if (childKind === SyntaxKind.ObjectLiteralExpression) { | ||
const sourceFile = child.getSourceFile(); | ||
if (sourceFile) { | ||
// May not be defined for synthesized nodes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was meant to describe the if (sourceFile)
? I think it should go on the same line then.
const sourceFile = child.getSourceFile(); | ||
if (sourceFile) { | ||
// May not be defined for synthesized nodes. | ||
const startLine = sourceFile.getLineAndCharacterOfPosition(child.getStart()).line; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use an isSingleLineNode(Node, SourceFile)
helper
// May not be defined for synthesized nodes. | ||
const startLine = sourceFile.getLineAndCharacterOfPosition(child.getStart()).line; | ||
const endLine = sourceFile.getLineAndCharacterOfPosition(child.getEnd()).line; | ||
return startLine === endLine; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did any of the tests cover the case where this is false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added test where the startline is the same as the endline, despite leading trivia making the object-literal child's pos
inappropriate to refer to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any back compat concerns?
I have back compat concerns. I'd sort of rather this be an option for users than the default. At the time of writing, the suggestion has 0 upvotes, so I have no idea who would want this feature vs. who would be very unhappy with this feature. |
case SyntaxKind.PropertyAssignment: | ||
case SyntaxKind.ObjectLiteralExpression: | ||
if (childKind === SyntaxKind.ObjectLiteralExpression) { | ||
const sourceFile = child.getSourceFile(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in the sourceFile instead of walking up on every node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and keep child TextRangeWithKind
We do need an option to control this formatting change. does not matter much which is the default really, but a way to opt out/in into this |
@mhegazy @DanielRosenwasser To clarify, this doesn't actually put object literals on their own line. All it does is change the indentation of object literals that already started on their own line and are multi-line. Should we still offer a switch? |
Well, we need to have formatting working correctly as well... I am assuming ppl want to format the file and have the formatting sticks.. it would be weird to have something like: var x =
{
a: 0,
b: "",
|
} work, but then you add a semi-colon after the |
case SyntaxKind.ObjectLiteralExpression: | ||
if (sourceFile && childKind === SyntaxKind.ObjectLiteralExpression) { | ||
const childStart = skipTrivia(sourceFile.text, child.pos); | ||
const startLine = sourceFile.getLineAndCharacterOfPosition(childStart).line; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My previous comment's marked outdated since this code was moved: This could use an isSingleLineNode(Node, SourceFile)
helper function.
@@ -581,9 +581,9 @@ namespace ts.formatting { | |||
&& !(node.decorators && kind === getFirstNonDecoratorTokenOfNode(node)); | |||
} | |||
|
|||
function getDelta(child: TextRangeWithKind) { | |||
function getDelta(child: Node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not think you need this change from TextRangeWithKind
to Node
.
Fixes a vsfeedback issue: https://developercommunity.visualstudio.com/content/problem/217993/javascript-braces-incorrectly-alignedindented.html
Today, we format object literals that star on their own line like this
the user asked that we instead format them like this
which is what this PR implements.
One subtlety is in the handling of formatting a synthesized object literal node. Since it is synthesized, the node doesn't exist within a sourcefile. So, we cannot reference the node's sourcefile to figure out if it is multiline (where the non-indentation of the open curly kicks in). Today, all object literals are synthesized to be single line, so the multi-line check just defers to the default indentation.
This reasoning coudld be made more explicit as a comment within the smart indenter if a reviewer considers it worthwhile.