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

jsx-first-prop-new-line: autofix #886

Merged
merged 11 commits into from
Nov 4, 2016
Merged

jsx-first-prop-new-line: autofix #886

merged 11 commits into from
Nov 4, 2016

Conversation

snowypowers
Copy link
Contributor

Hi I have made an autofix for the rule jsx-first-prop-new-line for a fork and I thought it would be useful to have it on the main repo.

I am aware and monitoring #883. Will update the autofix after that is approved! Meanwhile, PR for visibility and to start the process :)

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

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

Thanks! Could you rebase, so as to remove all merge commits?

## Rule Details

This rule checks whether the first property of all JSX elements is correctly placed. There are three possible configurations:
* `always`: The first property should always be placed on a new line.
* `never` : The first property should never be placed on a new line, e.g. should always be on the same line as the Component opening tag.
* `multiline`: The first property should always be placed on a new line when the properties are spread over multiple lines.

In order to utilise autofix, please specify the indentation style as an additional argument in your configuration:
Copy link
Member

Choose a reason for hiding this comment

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

instead of adding an additional option, could we just choose any arbitrary indentation style, and rely on the indent autofixer to correct it?

Copy link
Member

Choose a reason for hiding this comment

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

If we did want to add the option, I think we'd want to make it be an object so that it's extensible in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we are to rely on indent autofixer wouldnt we require 2 runs of lint?
Anyway the current implementation does default to a specific style (2 spaces). Most of the indent fixing code is actually referenced and stripped down from jsx-indent.

To make it clearer, I could word it such that autofix has a optional arg for indents but does work without it.

PS: I think I should change the default back to 4 spaces so to be inline with indent defaults

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it might require two passes of --fix but I think that's OK.

And yes, the default should match whatever indent defaults to.

Choose a reason for hiding this comment

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

Can we go ahead and merge this in? Where are we with this? I added an issue in the repo that this autofix needs to be added and it looks like its right here waiting.

Copy link
Member

Choose a reason for hiding this comment

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

This is waiting on @snowypowers removing the indentation option.

(also, s/utilise/utilize)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • Removed all traces of indentation argument
  • utilize
  • Added a simple warning line in readme that the fixer will require a second run of lint to fix indentation

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

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

i'd like a few other collabs to weigh in, but LGTM!

@snowypowers
Copy link
Contributor Author

snowypowers commented Nov 1, 2016

Rebased on top of #883. No major changes except for adding outputs to test cases.
However, I would like to take this moment to point out that the current code uses a foreach loop:

        if (
          (configuration === 'multiline' && isMultilineJSX(node)) ||
          (configuration === 'multiline-multiprop' && isMultilineJSX(node) && node.attributes.length > 1) ||
          (configuration === 'always')
        ) {
          node.attributes.forEach(function(decl) {
            //code to verify and fix EACH PROP
         }

This results in multiple errors being thrown in fail cases with multiple props:

options: ['always']

<Foo propOne="one" propTwo="two"/>

Seeing that this rule is only concerned with amending the position of the first prop, should the function be only checking for the first prop and throwing error if the first prop fails?

Possible fix:

// We check for at least one prop to ensure we can safely use node.attributes[0] inside
        if (
          (configuration === 'multiline' && isMultilineJSX(node) && node.attributes.length > 0) ||
          (configuration === 'multiline-multiprop' && isMultilineJSX(node) && node.attributes.length > 1) ||
          (configuration === 'always' && node.attributes.length > 0)
        ) {
          var decl = node.attributes[0];
         //Code to verify and fix decl

@ljharb
Copy link
Member

ljharb commented Nov 2, 2016

@snowypowers while i think it makes sense to only throw for the first error as long as the autofixer results in no remaining cases of the error.

Test should ignore indent for now
- Adjust old cases to use default 2 indents
- Add new case to use optional rule for 4 indents
Utilised getNodeIndent helper from jsx-indent-props as base-code
cut out unused vars based on feedback
Add fixable for readme and update docs to reflect additional argument
Revert back to 3 cases as per parent repo
s/utilise/utilize & simple warning
fix referenced from GovTechSG's fork
@snowypowers
Copy link
Contributor Author

Included the fix for multiple props on the first line causing lint to throw 1 error per prop, causing AssertionError. First Invalid test case amended to include such a scenario.

Hope that is all :)

@revisionfour
Copy link

To be clear, if we can get this completed and merged and the Readme updated with the --fix command included
https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md

Then I'd like to donate $50 American to @snowypowers. I can Paypal or Venmo this if you shoot an email to leec85@gmail.com with the email you want it delivered to.

That would take care of this 930

My team could also greatly benefit from closing out 929 with a --fix command for jsx-max-props-per-line.

I'd donate another $50 American for whoever can get this working, completed and merged with the readme updated.

Have any questions, find me on twitter. Go team open source.
@revisionfour

});
}
return true;
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't we only return true inside the if? otherwise it will only ever run on the first value of node.attributes - is that intended?

Copy link
Contributor Author

@snowypowers snowypowers Nov 3, 2016

Choose a reason for hiding this comment

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

Yes, it is intentional. This rule only concerns the first prop for each React element so we should not be checking anything else after the first element.

Copy link
Member

Choose a reason for hiding this comment

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

I guess the some then is just a nicer way of doing [0] and then having to check if it's defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, its somewhat cleaner than adding && node.attributes.length > 0. Matter of preference.

Copy link
Member

Choose a reason for hiding this comment

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

sounds good 👍

@ljharb
Copy link
Member

ljharb commented Nov 3, 2016

I'll give this a day or two to be reviewed by other collabs, then I'll merge it in.

@ljharb ljharb merged commit 0220022 into jsx-eslint:master Nov 4, 2016
@revisionfour
Copy link

$50 donated to @snowypowers.

Thanks Yak Jun Xiang!

If you or anyone else is up for it, 929 has a $50 bounty on it.

Go team open source!

@snowypowers
Copy link
Contributor Author

Hey thanks @revisionfour for the generous donation! Glad to know that my code will be utilised immediately!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

6 participants