-
-
Notifications
You must be signed in to change notification settings - Fork 32
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
[New]: Provide both range and start & end property on Node, support eslint v7 #97
Conversation
…onfig-airbnb-base`, `eslint-plugin-import`, `flow-parser`
@evcohen @ljharb CI is passing here, but supporting ESLint 7.x in Use node.range[0] instead of node.start Can't figure out what causes this error though... 🤔 If any of you can point me in the right direction, that would be great! 🙂 |
I've been doing some research and found out the reason why they disallowed the usage After disabling the return of both Another option would be to change the |
Giving this some thoughts and I think we should fix it on our end if we want to keep supporting Node@<6.x. |
Since this package only uses eslint as a dev dep, this PR isn't a feature; and it's blocked on the plugins it uses supporting eslint v7. We definitely need to keep supporting the same node versions. In this case, we should find a way to configure the tests to use start/end only when it's allowed by RuleTester. |
@evcohen @ljharb I've managed to change the code so that it doesn't return the non-standard Since it's non-standard and |
@evcohen @ljharb All tests are green 🙂 |
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 looks good, but it will be a breaking change due to removing the start
and end
properties. Is there any way you can think of to avoid making that be the case?
@ljharb That will indeed be a breaking change. This will only make |
I don’t think it’s worth a breaking change to any package just so it can use a newer version of the linter - leaving this package on eslint 6 for the foreseeable future seems fine to me. |
@ljharb That will break all ESLint plugins/configs (like |
I'm not sure why it would? it's RuleTester that can't use start/end, not plugins. |
It's because
|
Sure - but error or not, consumers will still work, no? |
@ljharb Since it's a hard deprecation that's throwing an error, It won't. |
It throws an error in RuleTester - it wouldn't throw one at runtime, since eslint itself doesn't interact with the code between this package and rules. |
@ljharb Any suggestion on how we can fix this then? 🤔 |
I think we could revert the runtime removal of start/end, and then in the tests, skip the appropriate tests when eslint is 7+? |
@ljharb If we can do this somehow, that will still fail tests in our dependants, no? 🤔 ESLint is pushing towards not using ESLint/Espree is not a dependency, but it’s some sort of “hidden” peerDependency in my opinion, since this package relies on the AST format they provide. People who need to get rid of the |
That’s fine; dependents can change themselves to use the range property when using eslint 7. It wouldn’t fail our dependents using eslint 6. In other words, because this package does not require eslint 7 - it works on both 6 and 7 - and start and end work fine in v6 - this package should continue to provide them. |
@ljharb That's the whole point: this package wouldn't work with dependents who want to use ESLint 7.x at this moment (see https://github.com/evcohen/eslint-plugin-jsx-a11y/pull/684), because this package is using
|
Thanks for bearing with me, I see the test failure here. So, there's two considerations for back compat:
Does that sound workable? |
@ljharb I just logged out It seems like either console.log src/getProp.js:57
{ range: [ 11, 13 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: [ 11, 20 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 13 }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 20 }
console.log src/getProp.js:57
{ range: [ 11, 13 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: [ 11, 13 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: [ 11, 13 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 13 }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 13 }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 13 }
console.log src/getProp.js:57
{ range: [ 11, 13 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: [ 15, 29 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: [ 11, 29 ], start: undefined, end: undefined }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 13 }
console.log src/getProp.js:57
{ range: undefined, start: 15, end: 29 }
console.log src/getProp.js:57
{ range: undefined, start: 11, end: 29 } So tests will fail if I change the code to your suggestion function getBaseProps({
loc,
range,
...node
}) {
const [start, end] = range || [node.start, node.end];
return {
// ...
};
} |
Then it'd be semver-minor to pass both; could we do that? |
Then we'll have the same as removing them, except we're adding the other missing ones, no? 🤔 So both doing it in code + in the tests? |
What I mean is, this package at runtime can provide both forms, by computing the missing ones from the present ones. The tests will use "range" when present, else "start/end". |
So what you're saying is doing it like this? function getBaseProps({
loc,
range,
...node
}) {
const [start, end] = range || [node.start, node.end];
return {
end,
loc: getBaseLocation(loc),
range: [start, end],
start,
};
} This will create Expected value to deeply and strictly equal to:
{"end": 24, "loc": {"end": {"column": 24, "line": 1}, "filename": "test.js", "start": {"column": 5, "line": 1}}, "name": {"end": 7, "loc": {"end": {"column": 7, "line": 1}, "filename": "test.js", "start": {"column": 5, "line": 1}}, "name": "id", "start": 5, "type": "JSXIdentifier"}, "start": 5, "type": "JSXAttribute", "value": {"end": 24, "expression": {"end": 23, "expressions": [{"end": 18, "loc": {"end": {"column": 18, "line": 1}, "filename": "test.js", "identifierName": "bar", "start": {"column": 15, "line": 1}}, "name": "bar", "start": 15, "type": "Identifier"}], "loc": {"end": {"column": 23, "line": 1}, "filename": "test.js", "start": {"column": 9, "line": 1}}, "quasis": [{"end": 13, "loc": {"end": {"column": 13, "line": 1}, "filename": "test.js", "start": {"column": 10, "line": 1}}, "start": 10, "tail": false, "type": "TemplateElement", "value": {"cooked": "foo", "raw": "foo"}}, {"end": 22, "loc": {"end": {"column": 22, "line": 1}, "filename": "test.js", "start": {"column": 19, "line": 1}}, "start": 19, "tail": true, "type": "TemplateElement", "value": {"cooked": "baz", "raw": "baz"}}], "start": 9, "type": "TemplateLiteral"}, "loc": {"end": {"column": 24, "line": 1}, "filename": "test.js", "start": {"column": 8, "line": 1}}, "start": 8, "type": "JSXExpressionContainer"}}
Received:
{"end": 24, "loc": {"end": {"column": 24, "line": 1}, "filename": "test.js", "start": {"column": 5, "line": 1}}, "name": {"end": 7, "loc": {"end": {"column": 7, "line": 1}, "filename": "test.js", "start": {"column": 5, "line": 1}}, "name": "id", "range": [5, 7], "start": 5, "type": "JSXIdentifier"}, "range": [5, 24], "start": 5, "type": "JSXAttribute", "value": {"end": 24, "expression": {"end": 23, "expressions": [{"end": 18, "loc": {"end": {"column": 18, "line": 1}, "filename": "test.js", "identifierName": "bar", "start": {"column": 15, "line": 1}}, "name": "bar", "start": 15, "type": "Identifier"}], "loc": {"end": {"column": 23, "line": 1}, "filename": "test.js", "start": {"column": 9, "line": 1}}, "quasis": [{"end": 13, "loc": {"end": {"column": 13, "line": 1}, "filename": "test.js", "start": {"column": 10, "line": 1}}, "start": 10, "tail": false, "type": "TemplateElement", "value": {"cooked": "foo", "raw": "foo"}}, {"end": 22, "loc": {"end": {"column": 22, "line": 1}, "filename": "test.js", "start": {"column": 19, "line": 1}}, "start": 19, "tail": true, "type": "TemplateElement", "value": {"cooked": "baz", "raw": "baz"}}], "start": 9, "type": "TemplateLiteral"}, "loc": {"end": {"column": 24, "line": 1}, "filename": "test.js", "start": {"column": 8, "line": 1}}, "range": [8, 24], "start": 8, "type": "JSXExpressionContainer"}} |
Not unconditionally ofc; where one of range or start+end is present, i would expect both to be. |
Did some investigation and I came to the following conclusions:
This means that the user of The ultimate goal would be to remove |
Totally agree; i'd love to ship a non-major update for this, and then a major update that does nothing except drop start/end and some older eslint versions. |
On it boss 😉 |
…slint v7 Co-authored-by: Michaël De Boey <[email protected]> Co-authored-by: Jordan Harband <[email protected]>
@ljharb Fixed like we said & all green 🎉 |
so, i think this really can't land yet. This repo uses I'll rebase and land this once that's done. |
Looks like eslint-plugin-import just published v7 support in ^2.21.0! |
Ping @ljharb |
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 LGTM, and seems like it's a semver-minor.
@ljharb Resolved all and all tests are green |
That's just because tests don't run |
@ljharb Is there anything I can do to help ESLint 7.x compatibility land on |
Nope, it's on my list, I just need to get to it. |
@ljharb I've updated Or is there something else I should do first? |
(dev)Dependencies should be compatible with ESLint 7 too before we can merge this one:
eslint-config-airbnb-base
(eslint v7 support airbnb/javascript#2223)eslint
v7
airbnb/javascript#2240Closes #96