Skip to content
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

Fix: object-curly-newline for flow code #9458

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 34 additions & 2 deletions lib/rules/object-curly-newline.js
Expand Up @@ -88,6 +88,38 @@ function normalizeOptions(options) {
return { ObjectExpression: value, ObjectPattern: value };
}

/**
* Gets the closing brace of an object expression with support for flow-style type annotations
*
* @param {SourceCode} sourceCode - The SourceCode object for the current object node
* @param {ASTNode} openBrace - The open brace for the object node
*
* @returns {ASTNode|null} The closing brace, or null if none is found
*
*/
function getMatchingClosingBrace(sourceCode, openBrace) {

// With flow, an object can have the form of `{ a : 3 } : { a : number }`. In this form the
// closing brace isn't simply the last brace. In order to find the closing brace we actually
// need to traverse through the node and count the braces, to find the matching pair.
Copy link
Member

@btmills btmills Oct 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to do this that doesn't involve linearly traversing the node and counting braces? I'm imagining something like this:

if (node.typeAnnotation) {
    return sourceCode.getTokenBefore(node.typeAnnotation);
} else {
    return sourceCode.getLastToken(node);
}

Where node is the same node passed to check, instead of passing the openBrace to this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vaguely remember looking for that, but couldn't find it. Nevertheless, I'll look again and see if I can make this linear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welp, that exact snippet seems to have done the trick 😄 Thanks for helping me out!


let braceCount = 1;
let nextBrace = openBrace;

do {
nextBrace = sourceCode.getTokenAfter(nextBrace, token => token.value === "}" || token.value === "{");
if (nextBrace.value === "{") {
braceCount++;
} else {
braceCount--;
}
if (braceCount === 0) {
return nextBrace;
}
} while (nextBrace !== null);
return null;
}

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -131,8 +163,8 @@ module.exports = {
*/
function check(node) {
const options = normalizedOptions[node.type];
const openBrace = sourceCode.getFirstToken(node);
const closeBrace = sourceCode.getLastToken(node);
const openBrace = sourceCode.getFirstToken(node, token => token.value === "{");
const closeBrace = getMatchingClosingBrace(sourceCode, openBrace);
let first = sourceCode.getTokenAfter(openBrace, { includeComments: true });
let last = sourceCode.getTokenBefore(closeBrace, { includeComments: true });
const needsLinebreaks = (
Expand Down