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
Extend fixers for prefer-string-slice
#424
Extend fixers for prefer-string-slice
#424
Conversation
I've realized that I need to do some more changes to this |
Done, now it should be a more correct auto fixer |
const firstArgument = argumentNodes[0] ? sourceCode.getText(argumentNodes[0]) : undefined; | ||
const secondArgument = argumentNodes[1] ? sourceCode.getText(argumentNodes[1]) : undefined; | ||
|
||
let slice; |
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 can be an array and concat with .slice(
and )
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.
rename to sliceArguments
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 you rename this variable? more specific
some |
Fixed most of your feedback @fisker, thanks!
Could you give me an example of what kind of |
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 initially did not aim to include advanced fixing due to subtle differences in index handling between the methods. Sorry I can't review this properly and check this myself, but I hope if this PR is merged, it handles edge cases properly (or good arguments are provided for why it should not and it is documented that it does not):
If
indexStart
is greater thanindexEnd
, then the effect of substring() is as if the two arguments were swapped
If start is a positive number, the index starts counting at the start of the string. Its value is capped at str.length.
If start is a negative number, the index starts counting from the end of the string. Its value is capped at -str.length.
If length is undefined, substr() extracts characters to the end of the string.
.. and maybe some others.
This handled wherever it can be handled and in cases where it can't be handled, no fix is provided.
This is very similar to |
sorry, I thought too much, not really needed |
@voxpelli I just send a PR to your fork, I did't change any your logic, should be more readable https://github.com/voxpelli/eslint-plugin-unicorn/pull/1 |
@fisker I actually prefer my version, but I wouldn't want it to block a merger of this, so whoever merges it can pick :) |
@fisker How do we best proceed? |
rules/prefer-string-slice.js
Outdated
} | ||
|
||
if (node.type === 'UnaryExpression' && node.operator === '-') { | ||
return 0 - getNumericValue(node.argument); |
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 0 should remove
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.
also, do we really want recury this? just number and negative number should enough
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 0 should remove
It's usually useful to explain why if it's not immediately obvious.
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.
Why should the 0
be removed?
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.
sorry, I was not explaining clear, this is negative number, right?
0 - 1
is the same as -1
am I missing something?
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.
It's a positive number Literal
wrapped in a UnaryExpression
with a -
operator, so the 0 -
part is to convert the positive number into its correct negative value. I do think I have added tests for that?
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 know that -1
is parsed as UnaryExpression
and operator:-
and argument:1
so return 0 - node.argument
equals to return - node.argument
.
I am getting confused, am I wrong?
const firstArgument = argumentNodes[0] ? sourceCode.getText(argumentNodes[0]) : undefined; | ||
const secondArgument = argumentNodes[1] ? sourceCode.getText(argumentNodes[1]) : undefined; | ||
|
||
let slice; |
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.
rename to sliceArguments
} else if (argumentNodes.length === 1) { | ||
slice = [firstArgument]; | ||
} else if (argumentNodes.length === 2) { | ||
if (firstArgument === '0') { |
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.
should be literal zero, we don't want handle "0"
, utils should have a function do this
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.
The text representation of an argument node can only ever be === '0'
if it's a literal zero, no?
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.
sorry, my comment is based on const firstArgument = argumentNodes[0]
(I changed it in my refactoring, but forgot it's not changed here), why we need sourceCode.getText
? Isn't argumentNodes[0]
easier to use?
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.
As almost every branch used the value of firstArgument
I decided to calculate them in shared space to make the code more easy to read and more DRY.
As firstArgument
then was already calculated I considered firstArgument === '0'
to be preferable over isLiteralNumber(argumentNodes[0]) && argumentNodes[0].value === 0
as it's shorter and simpler.
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.
thanks for explaining this, this make sense now, but I think it makes the logic little hard to understand. you want use those functions?
const isLiteralValue = require('./utils/is-literal-value'); |
const isLiteralZero = node => isLiteralValue(node, 0); |
prefer-string-slice
rules/prefer-string-slice.js
Outdated
} | ||
|
||
if (node.type === 'UnaryExpression' && node.operator === '-') { | ||
return 0 - getNumericValue(node.argument); |
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 0 should remove
It's usually useful to explain why if it's not immediately obvious.
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.
Adapted to some of the feedback + asked for clarification where I'm not sure regarding the feedback.
} else if (argumentNodes.length === 1) { | ||
slice = [firstArgument]; | ||
} else if (argumentNodes.length === 2) { | ||
if (firstArgument === '0') { |
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.
The text representation of an argument node can only ever be === '0'
if it's a literal zero, no?
rules/prefer-string-slice.js
Outdated
} | ||
|
||
if (node.type === 'UnaryExpression' && node.operator === '-') { | ||
return 0 - getNumericValue(node.argument); |
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.
Why should the 0
be removed?
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 guess I can accept the rest, except this https://github.com/sindresorhus/eslint-plugin-unicorn/pull/424/files#discussion_r341821231
Thanks for working on this, @voxpelli 👌 |
Currently barely any
substr()
orsubstring()
calls can be automatically fixed.This PR makes pretty much all
substring()
calls fixable and makes manysubstr()
fixable.