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: no-regex-spaces false positives and invalid autofix (fixes #12226) #12231

Merged
merged 4 commits into from Sep 29, 2019

Conversation

mdjermanovic
Copy link
Member

What is the purpose of this pull request? (put an "X" next to item)

[X] Bug fix #12226 + 2 other bugs.

This PR fixes 3 unrelated bugs in no-regex-spaces:

  1. False positives in character classes (e.g. /[ ]/ fixed to /[ {2}]/)
  2. Invalid autofix for strings with escape sequences (e.g. RegExp('\\d ') fixed to RegExp('\\ {2} '))
  3. Regex with invalid syntax were reported and fixed (e.g. RegExp('[ ') fixed to RegExp('[ {2}')). This might not be a bug, but I guess it's better to ignore invalid regex.

1. Character classes

The following tests were failing:

// valid[]
"var foo = /[  ]/;",
"var foo = /[   ]/;",
"var foo = / [  ] /;",
"var foo = new RegExp('[  ]');",
"var foo = new RegExp('[   ]');",
"var foo = new RegExp(' [  ] ');",

// invalid[]
"var foo = /[   ]  /;",
"var foo = new RegExp('[   ]  ');"

The code is now using regexpp parser to target only spaces with "Alternative" parent.

Example:

/* eslint no-regex-spaces:error */

var foo = /[  ]/;
var foo = new RegExp('[   ]  ');

Previous fix:

/* eslint no-regex-spaces:error */

var foo = /[ {2}]/; // incorrect
var foo = new RegExp('[ {3}] {2}'); // incorrect

New behavior:

/* eslint no-regex-spaces:error */

var foo = /[  ]/; // no error
var foo = new RegExp('[   ] {2}'); // error and autofix, but not inside []

2. Strings with escape sequences

It was assumed that the indexes are same as in the string's source code literal presentation.

The following tests were failing:

// valid[]
"var foo = new RegExp('bar \\ baz')",
"var foo = new RegExp('bar\\ \\ baz')",
"var foo = new RegExp('bar \\u0020 baz')",
"var foo = new RegExp('bar\\u0020\\u0020baz')",

// invalid[]
"var foo = new RegExp('\\\\d  ')"
"var foo = RegExp('\\u0041   ')"

The logic is now changed to check for consecutive spaces in the source code (Node.raw), and also don't fix if the raw presentation is not same as the internal.

Example:

/* eslint no-regex-spaces:error */

var foo = new RegExp('bar \ baz');
var foo = new RegExp('\\d  ');

Previous fix:

/* eslint no-regex-spaces:error */

var foo = new RegExp('bar {2} baz'); // incorrect, requires 3 spaces
var foo = new RegExp('\\ {2} '); // incorrect, missing 'd'

New behavior:

/* eslint no-regex-spaces:error */

var foo = new RegExp('bar \ baz'); // no error, there are no consecutive spaces in the source
var foo = new RegExp('\\d  '); // error, but no autofix

3. Invalid syntax

The following tests were failing:

// valid[]
"var foo = new RegExp('[  ');",
"var foo = new RegExp('{  ', 'u');"

Example:

/* eslint no-regex-spaces:error */

var foo = new RegExp('[  ');

Previous fix:

/* eslint no-regex-spaces:error */

var foo = new RegExp('[ {2}');

New behavior:

/* eslint no-regex-spaces:error */

var foo = new RegExp('[  '); // no error

What changes did you make? (Give an overview)

Use regexpp to parse, don't fix strings that have a different raw representation, don't report regex with invalid syntax.

Is there anything you'd like reviewers to focus on?

Everything please, I didn't use regexpp before.

The cases in 2. could be auto-fixed but that would require a utility to map indexes (that could be a future enhancement, I believe at the moment it's good enough to prevent invalid autofix).

There are some edge cases where the rule will report an error, e.g. RegExp('[ ]\\u0020\\u0020'), but that would require the same utility.

@eslint-deprecated eslint-deprecated bot added the triage An ESLint team member will look at this issue soon label Sep 6, 2019
@mdjermanovic
Copy link
Member Author

Marking as accepted as the bug 1. is accepted in #12226, just to note that this PR additionaly:

  • Disables autofix in certain situations (2.)
  • Ignores invalid regex (3.).

@platinumazure there is a TODO in the code, I'm not sure is it already fixed in #7053?

@mdjermanovic mdjermanovic added accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly rule Relates to ESLint's core rules and removed triage An ESLint team member will look at this issue soon labels Sep 6, 2019
Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

The TODO can be removed. Thanks!

It looks like the rule is intentionally only reporting one violation and relying on multipass autofix to find multiple violations, is that correct?

Otherwise LGTM, thanks!

}

/*
* TODO: (platinumazure) Fix message to use rule message
Copy link
Member

Choose a reason for hiding this comment

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

You are right, this TODO can be removed. Thanks!

Copy link
Member Author

Choose a reason for hiding this comment

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

TODO is removed now :)

@mdjermanovic
Copy link
Member Author

It looks like the rule is intentionally only reporting one violation and relying on multipass autofix to find multiple violations, is that correct?

Didn't want to change that, I think it was intentional because the messages can't be more descriptive and the whole range of the node (literal/call/new) is reported, so it could be confusing to see multiple similar messages for the same node.

@platinumazure
Copy link
Member

Thanks @mdjermanovic. I think it would be awesome to try to report smaller ranges as a future enhancement.

I'll re-review shortly.

Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@mdjermanovic mdjermanovic added the autofix This change is related to ESLint's autofixing capabilities label Sep 23, 2019
@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Mar 29, 2020
@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 Mar 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
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 autofix This change is related to ESLint's autofixing capabilities bug ESLint is working incorrectly rule Relates to ESLint's core rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

no-regex-spaces false positive in character class
3 participants