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

implicit-arrow-linebreak autofixer sometimes adds extra characters #11268

Closed
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion bug ESLint is working incorrectly rule Relates to ESLint's core rules

Comments

@bradennapier
Copy link

bradennapier commented Jan 12, 2019

Tell us about your environment

  • ESLint Version: 5.12.0
  • Node Version: 10.15.0
  • npm Version: 6.4.1

What parser (default, Babel-ESLint, etc.) are you using?

babel-eslint (but i dont believe it matters)


Configuration
{
  "parser": "babel-eslint",
  "parserOptions": {
    "sourceType": "module"
  },
  "env": {
    "node": true
  },
  "rules": {
    "implicit-arrow-linebreak": "error"
  }
}

What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.

start()
  .then(() => 
    /* If I put a comment here, eslint --fix breaks badly */
    process && typeof process.send === 'function' && process.send('ready')
  )
  .catch(err => {
  	/* catch seems to be needed here */
       console.log('Error: ', err)
  })
eslint --fix

What did you expect to happen?

Code that it "fixes" should not be invalid javascript

What actually happened? Please include the actual, raw output from ESLint.

It creates broken code

start()
  .then(() => ( 
    /* If I put a comment here, eslint --fix breaks badly */
    process && typeof process.send === 'function' && process.send('ready')
         )
        )
  )
  .catch(err => ( {
  	/* catch seems to be needed here */
       console.log('Error: ', err)
  })

Notice that it broke the catch as it seems to assume its an implicit object return

Are you willing to submit a pull request to fix this bug?

not really, wouldnt know where to start


This can get REALLY bad and is especially an issue since its part of eslint-config-airbnb, granted this file is crazy, but the bug ends up filling the entire file up with thousands of invalid lines

image

@bradennapier bradennapier added bug ESLint is working incorrectly triage An ESLint team member will look at this issue soon labels Jan 12, 2019
@bradennapier bradennapier changed the title implicit-arrow-linebreak is badly broken [CRITICAL] implicit-arrow-linebreak is badly broken Jan 12, 2019
@not-an-aardvark not-an-aardvark changed the title [CRITICAL] implicit-arrow-linebreak is badly broken implicit-arrow-linebreak autofixer sometimes adds extra characters Jan 12, 2019
@not-an-aardvark not-an-aardvark added rule Relates to ESLint's core rules accepted There is consensus among the team that this change meets the criteria for inclusion and removed triage An ESLint team member will look at this issue soon labels Jan 12, 2019
@not-an-aardvark
Copy link
Member

Hi, thanks for the report. I can reproduce this issue.

The implicit-arrow-linebreak rule has a lot of logic that deals with trying to move around comments when autofixing, whereas most other rules just skip autofixing if there's a comment in the way. It would probably be worth into whether this particular comment-moving issue can be easily fixed, but if not I think it would be better to just remove the comment-moving logic from implicit-arrow-linebreak and skip autofixing if there's a comment in the wrong place.

@ghost
Copy link

ghost commented Jan 12, 2019

I'll look into this.

@not-an-aardvark
Copy link
Member

Hi @peanutenthusiast, just checking in to see if you've had a chance to work on this.

@ghost
Copy link

ghost commented Feb 16, 2019

@not-an-aardvark you can expect a PR by tomorrow afternoon/early evening! thank you for your patience

@zliy
Copy link

zliy commented Feb 28, 2019

another falling case:

hello(response =>
  // comment
  response, param => param)

=>

hello(response => (
  // comment
  response
)), param => (param)

btmills pushed a commit that referenced this issue Mar 15, 2019
…11407)

* add failing test case

* Add specified test case from issue

* Remove calculation for white spaces from formatComments and addParentheses, add condition to check for arrow expressions with block statements

* Fix linting errors, ensure npm test runs without fail

* Change new test case to check for prepended comment, add unIndent function to tests for implicit arrow linebreak

* Add optional token type to arrow body

* Add failing test case

* Remove null return from autofixBesides, refactor body setting lines to use .body

* Fix linting errors

* Fix linting error in unIndent rule in implicit arrow linebreak test

* Add another test case where nested arrow function contains block statement

* Add constraint for block statement in add parentheses
not-an-aardvark added a commit that referenced this issue Mar 17, 2019
Currently, the implicit-arrow-linebreak rule contains a lot of logic to determine how comments should be adjusted in code when an autofix is needed. The goal is to be able to autofix cases where there is a comment between an arrow token and the start of an arrow function body. Most other core rules simply decide not to fix cases when there is a comment interfering with the fix.

This logic accounts for a large fraction of the code in the rule, and seems to require a lot of different code for many individual cases. Unfortunately, bugs keep being reported identifying problems in the rule (e.g. #11268, #11521) and it's not clear that the fixes are moving us closer to making the rule correct in general, given that there are always more cases than we can explicitly account for.

To address those problems, this commit updates the implicit-arrow-linebreak rule to just skip autofixing when comments interfere, rather than trying to do an autofix anyway and find an alternate location for the comments. I'm reluctant to make this change given that a lot of time has been invested in the autofixing logic, but I think this is ultimately a better solution than trying to guess where the user wants their comments to go, and crashing/producing incorrect code if we get it wrong.
not-an-aardvark added a commit that referenced this issue Mar 18, 2019
…#11522)

Currently, the implicit-arrow-linebreak rule contains a lot of logic to determine how comments should be adjusted in code when an autofix is needed. The goal is to be able to autofix cases where there is a comment between an arrow token and the start of an arrow function body. Most other core rules simply decide not to fix cases when there is a comment interfering with the fix.

This logic accounts for a large fraction of the code in the rule, and seems to require a lot of different code for many individual cases. Unfortunately, bugs keep being reported identifying problems in the rule (e.g. #11268, #11521) and it's not clear that the fixes are moving us closer to making the rule correct in general, given that there are always more cases than we can explicitly account for.

To address those problems, this commit updates the implicit-arrow-linebreak rule to just skip autofixing when comments interfere, rather than trying to do an autofix anyway and find an alternate location for the comments. I'm reluctant to make this change given that a lot of time has been invested in the autofixing logic, but I think this is ultimately a better solution than trying to guess where the user wants their comments to go, and crashing/producing incorrect code if we get it wrong.
@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Sep 12, 2019
@eslint-deprecated eslint-deprecated bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Sep 12, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.