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
Breaking: upgrade espree and support new class features (refs #14343) #14591
Conversation
Hi @mysticatea!, thanks for the Pull Request The pull request title isn't properly formatted. We ask that you update the message to match this format, as we use it to generate changelogs and automate releases.
Read more about contributing to ESLint here |
Keep up the good work @mysticatea very excited for this 🙌 |
@mysticatea do we also plan to update code path analysis, or shall we leave it as is? For example: a = 1;
class A {
foo = a++;
}
b = a;
Non-static |
Rules that use /* eslint no-use-before-define: ["error", { "variables": false }] */
class A {
foo = x; // false positive?
}
const x = 1; /* eslint require-atomic-updates: error */
async () => {
let i;
foo(class { x = i++ });
i = i + await bar(); // false negative?
} Less sure about this one, since formally it isn't a function so maybe we could add an option later: /* eslint no-loop-func: error */
for (var i = 0; i < 10; i++) {
foo[i] = class {
x = i; // false negative?
}
} |
/* eslint semi: ["error", "never"] */
class A {
a = b; // syntax error without `;`
*c(){}
} |
/* eslint dot-notation: ["error", { allowKeywords: false }] */
class C {
#in;
foo() {
this.#in; // autofixed to `this["in"]`
}
} |
"PropertyDefinition > ArrowFunctionExpression.value": enterFunction, | ||
"PropertyDefinition > ArrowFunctionExpression.value:exit": exitFunction, |
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 we put this behind an option, since this isn't a class method by definition?
VariableDeclarator(node) { | ||
const name = sourceCode.getText(node.id), | ||
init = node.init && node.init.name, | ||
"VariableDeclarator, PropertyDefinition"(node) { |
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 think PropertyDefinition
should be behind an option (or a separate rule?), the docs for this rule says that it checks variable declarations.
lib/rules/no-useless-computed-key.js
Outdated
@@ -97,6 +97,7 @@ module.exports = { | |||
|
|||
return { | |||
Property: check, | |||
PropertyDefinition: enforceForClassMembers ? check : lodash.noop, |
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.
We should add something like || node.type === "PropertyDefinition"
on line 64:
/* eslint no-useless-computed-key: ["error", { enforceForClassMembers: true }] */
class C {
["constructor"]; // false positive
static ["prototype"]; // false positive
["__proto__"]; // false negative
}
(also, lodash
has been removed in the meantime)
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.
static ["constructor"]
is also false positive (produces parsing error instead of a runtime error in a maybe-unused code).
For some reason, "constructor" is allowed as the name of a static method, but not as the name of a static field.
ClassElement : static MethodDefinition
- It is a Syntax Error if PropName of MethodDefinition is "prototype".
ClassElement : static FieldDefinition ;
- It is a Syntax Error if PropName of FieldDefinition is "prototype" or "constructor".
In /* eslint class-methods-use-this: ["error", { exceptMethods: ["a"] }] */
class C {
a() {} // ok
#a() {} // ok
} Does it make sense, or should |
/* eslint no-extra-parens: ["error"] */
class C {
[(a)]; // false negative
b = (c + d); // false negative
} |
class C {
a = this.a.bind(this);
a() {
// uses `this`
}
} Thoughts? |
I'm sorry for my inactive while a time. I'm rebooting... |
Oh. I had forgotten about code path analysis. |
A remaining task is to update code path analysis to create separate code paths for class field initializers (#14591 (comment) and #14591 (comment)). This is a change in the core that affects rules (built-in and custom), so it might be good to implement it before beta release? Aside from that, I left comments for about 15-20 rules. Some are obvious bugs, some need discussion. I can open issues after we merge this PR, so that they could be worked on in parallel. |
I think code path analysis may not make it. @mysticatea is the only one who really understands it. I can take a swing at it but unsure how far I can actually get. Yes, let’s deal with other rule changes separately. There is always a long tail of rule changes to support new syntax, and that’s part of what the beta period is for. |
WIP.
Remaining steps:
id-denylist
id-length
id-match
espree
andeslint-scope
.package.json
with the new versions ofespree
andeslint-scope
.Refs #14343
Fixes #14632
Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
[X] Changes an existing rule
[X] Other, please explain: The espree update contains breaking changes.
What changes did you make? (Give an overview)
camelcase
,id-denylist
,id-length
, andid-match
) are broken. This PR contains the fix of those rules as well. It will fix [camelcase] false positive when parsing object pattern with a default value, and using a non-default parser. #13021.parserOptions: { ecmaVersion: 2022 }
to use the new class features. This PR also change a ton of rules to support the new class features.camelcase
eslint-scope
.class-methods-use-this
computed-property-spacing
func-names
"as-needed"
option recognizes that.id-denylist
id-length
id-match
indent
keyword-spacing
get
,set
,static
. Tweaks spacing between those and private identifier. And it additinally checks class fields.no-dupe-class-members
no-eval
this.eval()
at class field initializers is not eval. Theast-utils
change in 7ccd811 and 8009406 is related.no-extra-semi
no-invalid-this
this
in class field initializers is valid.no-multi-assign
no-self-assign
no-undef-init
undefined
at class field initializers.no-underscore-dangle
no-unreachable
no-useless-computed-key
operator-linebreak
=
of class field initializers.prefer-exponentiation-operator
eslint-utils
.quotes
semi-spacing
;
of class fields.semi-style
;
of class fields.semi
;
of class fields. Some cases are affected bybeforeStatementContinuationChars
option.space-infix-ops
=
of class field initializers.And this PR adds some tests to a ton of rules.
Is there anything you'd like reviewers to focus on?
camelcase
,id-denylist
,id-length
, andid-match
. Is this good or not?