-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Rule Change: lines-between-class-members customize properties/instance field spacing #17082
Comments
Hi @domdomegg, thanks for the issue. I can confirm the proposal has reached stage 4. cc @eslint/eslint-tsc |
Thanks for the suggestion. Can you please explain what option you're proposing to add and what it would change? "As per example" code doesn't actually tell us what you're proposing. We need a description to really understand what it is you're proposing. |
Current stateCurrently, So you have to pick between: class ClassWithInstanceField {
fieldA = 'Field A'
fieldB = this.fieldA
fieldC = 42
methodA() {
return 'abc'
}
methodB() {
return 'def'
}
} or class ClassWithInstanceField {
fieldA = 'Field A'
fieldB = this.fieldA
fieldC = 42
methodA() {
return 'abc'
}
methodB() {
return 'def'
}
} According to #13295 (comment), this was because at the time members were non-stage 4 syntax and therefore considered out of scope for ESLint. Proposed stateOptions to set spacing for property and and method members independently. So the option type would be something like: type Option = "always" | "never" | { properties: "always" | "never" | "off", methods: "always" | "never" | "off" } Allowing for: // ["error", { "properties": "off", "methods": "always" }]
class ClassA {
fieldA = 'Field A'
fieldB = this.fieldA
fieldC = 42
instanceMethodA() {
return 'abc'
}
instanceMethodB() {
return 'def'
}
}
// ["error", { "properties": "never", "methods": "always" }]
class ClassB {
fieldA = 'Field A'
fieldB = this.fieldA
fieldC = 42
instanceMethodA() {
return 'abc'
}
instanceMethodB() {
return 'def'
}
}
// ["error", { "properties": "always", "methods": "never" }]
class ClassB {
fieldA = 'Field A'
fieldB = this.fieldA
fieldC = 42
instanceMethodA() {
return 'abc'
}
instanceMethodB() {
return 'def'
}
} WhyThis allows enforcing consistent spacing between methods (as this is standard), while enabling users to group properties (as this is useful for readability). This appears to be a common desire, as indicated by #13295 and typescript-eslint/typescript-eslint#977. This also allows for differences between properties and methods. For example, at my organisation we have a code standard that currently requires a custom ESLint rule to enforce no spacing between properties, and spacing between methods. |
Got it, thanks for explaining. I think this makes sense, though I'd suggest replacing "properties" with "fields", as they are described in the spec. (Properties are
@mdjermanovic what do you think? |
I agree that "fields" would be better than "properties". Getters and setters will fall under "methods"? |
How will it be determined from the configuration whether or not there should be a blank line between a field and a method? class C {
fieldA = 'Field A'
instanceMethodA() {
return 'abc'
}
} |
Sounds good, also agreed this makes sense.
Yes, I think so.
I gave this some thought. I think in the majority of cases it makes most sense to put in a newline if either has a setting for a newline (e.g. in your example if either of fields or methods is true, insert a newline, otherwise don't). I think this makes sense given that if you are introducing spacing between a particular type of entry, it would be odd for it to be bunched up against other things: that makes the visual spacing of a class look unbalanced to me, e.g. this looks wrong:
and so does:
The other reasonable alternative is to pick one of them, probably the later clause, and use the rule for that (e.g. in your example because the method follows the field, we use the setting for method). |
@mdjermanovic can you check back on this? And if you agree we should make a change, let's mark as accepted. |
Oops! It looks like we lost track of this issue. What do we want to do here? This issue will auto-close in 7 days without an update. |
@mdjermanovic still looking for your response on this. |
Sorry for the delay. I think the logic would be clearer with a schema like the one in {
rules: {
"lines-between-class-members": ["error", {
// requires blank lines around methods, disallows blank lines between fields
enforce: [
{ blankLine: "always", prev: "*", next: "method" },
{ blankLine: "always", prev: "method", next: "*" },
{ blankLine: "never", prev: "field", next: "field" }
]
}]
}
} |
@mdjermanovic Super-demanded feature! As people say, "better is the enemy of the good". The syntax change similar to padding-line-between-statements would likely be hard to implement, whilst fields/methods property is straightforward and covers 99.9% of the usecases for people (people really don't want empty lines between properties and do want them between methods, it may even be the default). |
Oops! It looks like we lost track of this issue. What do we want to do here? This issue will auto-close in 7 days without an update. |
Not stale. I guess we can mark this as accepted? How do we proceed further? |
@mdjermanovic because you were driving this, up to you to mark as accepted. |
Accepted, PR is welcome. I think the schema I suggested in #17082 (comment) is easier to understand and implement because there will be no ambiguity about how the rule should work. |
I'll work on this |
What rule do you want to change?
lines-between-class-members
What change to do you want to make?
Generate fewer warnings
How do you think the change should be implemented?
A new option
Example code
What does the rule currently do for this code?
Either have to have spaces between everything, or spaces between nothing (with some changes if you enable
exceptAfterSingleLine
: but this seems to be used as a proxy rather than actual control - and can't enforce that there shouldn't be lines between single line members).What will the rule do after it's changed?
As per example code.
Participation
Additional comments
This was previously discussed in #13295, where it was agreed this would be discussed when the syntax reached stage 4, which it now has.
Not sure if this is now out of scope with the stylistic rule changes, but would argue that given this is a feature that has moved to stage 4 since last review it may fall under 'New ECMAScript features'.
The text was updated successfully, but these errors were encountered: