Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(eslint-plugin): [class-literal-property-style] correct handling of override cases #5983

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

Closed
wants to merge 4 commits into from

Conversation

sviat9440
Copy link
Contributor

@sviat9440 sviat9440 commented Nov 13, 2022

[prefer-optional-chain] A literal getter with a setter does not pass lint, and incorrectly auto-fix (#5961)

[prefer-optional-chain] The overridden literal getter does not pass lint and incorrectly auto-fix (#5962)

PR Checklist

Overview

  1. Ignore accessors with computed names (like get [a + b](): string {}, because we cannot be sure that the computed names are not overrides.
/// a.ts

const a = 'a';
const b = 'b';

class A {
  get [a + b](): string {
    return ...;
  }
}

/// b.ts
import { A } from './a';

const a = 'c';
const b = 'd';

class B extends A {
  get [a + b](): string {
    return ...;
  }
}

In this case, visually, the accessors keys are no different, and can be taken as an override. But in fact, this is a completely different key.
So, the supported nodes are now: Identifier, PrivateIdentifier, Literal

  1. The rule now uses type checker, and if parserOptions.project is not defined, rule will cause an error. (BREAKING CHANGE!)
  2. If the literal getter overrides the getter of the parent class. the rule will not cause an error, because there is no way to fix it.
  3. If the literal getter has a setter in a pair, the rule will not cause an error, because there is no way to fix it.

@nx-cloud
Copy link

nx-cloud bot commented Nov 13, 2022

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 704cc72. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this branch


✅ Successfully ran 47 targets

Sent with 💌 from NxCloud.

@typescript-eslint
Copy link
Contributor

Thanks for the PR, @sviat9440!

typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community.

The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately.

Thanks again!


🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint.

@netlify
Copy link

netlify bot commented Nov 13, 2022

Deploy Preview for typescript-eslint ready!

Name Link
🔨 Latest commit 704cc72
🔍 Latest deploy log https://app.netlify.com/sites/typescript-eslint/deploys/63dc26d0cb87de000878f214
😎 Deploy Preview https://deploy-preview-5983--typescript-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@sviat9440
Copy link
Contributor Author

  1. For backward compatibility, I can add a try catch when creating a ParserServices, and not apply logic to find an override if parserOptions.project is not defined. If needed...

@codecov
Copy link

codecov bot commented Nov 14, 2022

Codecov Report

Merging #5983 (704cc72) into main (a948729) will decrease coverage by 0.02%.
The diff coverage is 92.30%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5983      +/-   ##
==========================================
- Coverage   91.52%   91.51%   -0.02%     
==========================================
  Files         371      371              
  Lines       12649    12643       -6     
  Branches     3714     3714              
==========================================
- Hits        11577    11570       -7     
  Misses        755      755              
- Partials      317      318       +1     
Flag Coverage Δ
unittest 91.51% <92.30%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...t-plugin/src/rules/class-literal-property-style.ts 97.50% <92.30%> (-2.50%) ⬇️

@bradzacher bradzacher changed the title fix(class-literal-property-style) fix(eslint-plugin): [class-literal-property-style] correct handling of override cases Nov 15, 2022
@bradzacher
Copy link
Member

The rule now uses type checker, and if parserOptions.project is not defined, rule will cause an error

Strongly disagree with this change.
Overriding a getter with another getter that specifically and intentionally returns a constant value is a really, really, really rare usecase. TBH I've never actually seen code do it.
The rule is well over 2 years old at this point and you're the first report of the problem - another point in the column of really rare.

It's not worth locking the rule into type information and restricting many people from using it just to prevent a really, really rare false-positive.

As per the comments on #5962 - the change we would accept is making the fixer a suggestion fixer so that the rule cannot automatically fix and break code.


For backward compatibility, I can add a try catch when creating a ParserServices, and not apply logic to find an override if parserOptions.project is not defined. If needed...

Making rules conditionally dependent on type information is not something we really like doing in this project. Most users struggle with understanding config as it is, and adding extra forks to rules dependent on certain configs that are separate to the rule's configs further complicates things.

Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

Blocked on #5961 passing triage. Also what Brad said. 😄

Edit: now just what Brad said.

@JoshuaKGoldberg JoshuaKGoldberg added the awaiting response Issues waiting for a reply from the OP or another party label Nov 15, 2022
@JoshuaKGoldberg
Copy link
Member

Ping @sviat9440 - is this something you have the time to work on? No worries if not, just checking in - thanks!

@sviat9440
Copy link
Contributor Author

@JoshuaKGoldberg I'll take a look this weekend

[prefer-optional-chain] A literal getter with a setter does not pass lint, and incorrectly auto-fix (typescript-eslint#5961)

[prefer-optional-chain] The overridden literal getter does not pass lint and incorrectly auto-fix (typescript-eslint#5962)
Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg 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! I'll defer to @bradzacher since Brad was active in the comments, and this is a tricky edge case kind of scenario.

Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

Whoops, meant to request changes on the test coverage dipping...

@sviat9440
Copy link
Contributor Author

@JoshuaKGoldberg ready to go

@JoshuaKGoldberg JoshuaKGoldberg added the 1 approval >=1 team member has approved this PR; we're now leaving it open for more reviews before we merge label Feb 3, 2023
case AST_NODE_TYPES.Identifier:
return key.name;
case AST_NODE_TYPES.Literal:
return key.raw;
Copy link
Member

@bradzacher bradzacher Feb 7, 2023

Choose a reason for hiding this comment

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

You can't use .raw here because:

  • For strings it encodes in the quotes and backslashes.
  • For numbers it encodes the _ separators, decimal points, and differentiates between binary/octal/hex/decimal notation
  • For bigints it encodes the _ separators

EG this would mean that these cases are not matched:

class Foo {
  get 'a\"'() { return 1; }
  set 'a"'(v) { }

  get 'a'() { return 1; }
  set "a"(v) {}

  get 11() { return 1; }
  set 1_1(v) { }

  get 1.0() { return 1; }
  set 1(v) { }

  get 0b10() { return 1; }
  set 2(v) { }

  get 0o10() { return 1; }
  set 8(v) { }

  get 0x10() { return 1; }
  set 16(v) { }
}

Cases case to be careful of:

  • RegExp literals are not primitives, so .value === .value will not work.
  • BigInt literals can technically be .value = null, but shouldn't really ever be.

Comment on lines +65 to +66
item.kind === 'set' &&
isEqualPropertyKey(node.key, item.key),
Copy link
Member

Choose a reason for hiding this comment

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

this also needs to check .computed or else you will false negative on this case:

const key = 'not key lol';
class Foo {
  get key() { return 'a' }
  set [key](arg) {}
}

Though worth noting that right now your logic correctly handles this case:

class Foo {
  get 'key'() { return 'a' }
  set ['key'](arg) {}
}

If we want to keep handling this case then the logic change will need to be more sophisticated than just checking .computed

Comment on lines +62 to +67
const setter = classBody.body.find(
item =>
item.type === AST_NODE_TYPES.MethodDefinition &&
item.kind === 'set' &&
isEqualPropertyKey(node.key, item.key),
);
Copy link
Member

Choose a reason for hiding this comment

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

This logic also does not respect static and thus will false negative on this case:

class Foo {
  get key() { return 'a' }
  static set key(arg) {}
}

@bradzacher bradzacher removed the 1 approval >=1 team member has approved this PR; we're now leaving it open for more reviews before we merge label Feb 7, 2023
@JoshuaKGoldberg
Copy link
Member

👋 ping @sviat9440, is this still something you have time for? No worries if not - I just don't want to leave it hanging.

@bradzacher bradzacher added the bug Something isn't working label Mar 15, 2023
@JoshuaKGoldberg
Copy link
Member

Closing this PR as it's been stale for ~6 weeks without activity. Feel free to reopen @sviat9440 if you have time - but no worries if not! If anybody wants to drive it forward, please do post your own PR - and if you use this as a start, consider adding Co-authored-by: @sviat9440 at the end of your PR description. Thanks! 😊

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
awaiting response Issues waiting for a reply from the OP or another party bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants