Skip to content
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

fix: unify LintMessage type #17076

Merged
merged 7 commits into from May 16, 2023

Conversation

btmills
Copy link
Member

@btmills btmills commented Apr 8, 2023

Prerequisites checklist

What is the purpose of this pull request? (put an "X" next to an item)

[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[x] Other, please explain: Update JSDoc types

What changes did you make? (Give an overview)

Fix #16968, changing runtime code as little as possible. First, this updates the LintMessage type to match the most common implementation. It also combines some undefined types or duplicate definitions into LintMessage so everything references the single definition. Finally, it normalizes the few remaining divergent implementations in three ways: 1) always set a line and column, even if they're 1/0, 2) always set ruleId, even if it's null, and 3) always set nodeType, even if it's null. Were we designing the API from scratch, we might make those properties optional, but for this existing API, I followed the most common precedent of providing dummy values.

Is there anything you'd like reviewers to focus on?

This will be easiest to review going one commit at a time, and see each commit message for more context.

For nodeType, I changed direction from where we were leaning in #16968 after the original direction became a bit more complicated. There are three possible solutions:

  1. Make nodeType non-nullable but optional. This is where we were originally leaning. However, it had the most significant runtime code change, adding branching in report-translator to set it conditionally.
  2. Preserve the existing type definition with nodeType nullable and required. This is what's currently in this PR. This way, all three changes do conceptually the same thing of providing an "emtpy" value for a required property. That felt cleaner than making line/column/ruleId required yet nodeType optional. It's larger in terms of absolute lines in the diff because I had to add more nulls, but that's all I had to do.
  3. Make nodeType nullable and optional. This would only require changing the type definition. After seeing the nulls added in the nodeType commit, let me know if you'd like me to go with this option instead. It's not consistent with the others, but it does match current reality.

@btmills btmills requested a review from a team as a code owner April 8, 2023 23:48
@eslint-github-bot eslint-github-bot bot added the chore This change is not user-facing label Apr 8, 2023
@netlify
Copy link

netlify bot commented Apr 8, 2023

Deploy Preview for docs-eslint ready!

Name Link
🔨 Latest commit 55bed08
🔍 Latest deploy log https://app.netlify.com/sites/docs-eslint/deploys/6456fc357d9c910008f8732a
😎 Deploy Preview https://deploy-preview-17076--docs-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.

@btmills btmills added the evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion label Apr 8, 2023
@btmills btmills force-pushed the chore-unify-lint-message-type branch 3 times, most recently from d2604b7 to 406c2b0 Compare April 9, 2023 00:29
Copy link
Member

@nzakas nzakas 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 for doing this, and thanks for the tip about reviewing commit-by-commit.

Just want to leave open for @mdjermanovic to review. (He's on holiday this week, so will likely not be until next week.)

docs/src/integrate/nodejs-api.md Outdated Show resolved Hide resolved
lib/cli-engine/cli-engine.js Outdated Show resolved Hide resolved
@github-actions
Copy link

Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update.

@github-actions github-actions bot added the Stale label Apr 24, 2023
@Rec0iL99
Copy link
Member

Don't close. Not stale.

@btmills there are a few review comments for you to look into. Thanks.

@Rec0iL99 Rec0iL99 removed the Stale label Apr 25, 2023
@github-actions
Copy link

github-actions bot commented May 5, 2023

Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update.

@github-actions github-actions bot added the Stale label May 5, 2023
@Rec0iL99 Rec0iL99 removed the Stale label May 6, 2023
@Rec0iL99
Copy link
Member

Rec0iL99 commented May 6, 2023

I believe this is still not stale.

cc @btmills

I made three changes to `LintMessage` and `SuppressedLintMessage`:

1. Many places that create `LintMessage`s don't set `fatal`, so I made
   it optional. This would be a breaking change if we made types part of
   our exports, but in this case I believe it's updating JSDoc
   documentation to reflect reality.
2. Added an optional `messageId` property that's set by reports from rules.
3. Added an optional, nullable `nodeType` property.
    - Reports from rules set it to a value.
    - `applyDirectives()` explicitly sets it to `null` for unused
      disable directives.
    - `Linter`'s `createLintingProblem()` explicitly sets it to `null`.

Two open questions:

1. Should I make `nodeType` non-nullable and update the places in the
   implementation that explicitly set it to `null` to omit it instead? A
   few places already omit it for e.g. parse errors or ignored file
   messages, so API consumers already have to check that it might not be
   set.
2. `line` and column` are currently required but possibly `undefined`.
    - Ignored file messages currently omit `line` and `column`.
    - `Linter` explicitly sets them to `0` for two configuration errors
      (configured parser not found and no configuration found for file).
    - `Linter`'s `createLintingProblem()` has a `DEFAULT_ERROR_LOC` that
      defaults to line 1 column 0, but the default is only used for
      missing rule definition messages.

    Should I either:
    a. Keep `line` and `column` required but possibly `undefined` and
       update ignored file messages to explicitly set them to `0`,
       following precedent elsewhere?
    b. Or make `line` and `column` optional and remove fallback 0/0 or
       1/0 values from configuration issues?

    Option b is how I'd design the API from scratch because I wouldn't
    report a location unless we had a real locationl. But it might be a
    breaking change. Even though the type is specified as possibly
    `undefined`, in practice, some API consumers might only see messages
    that have real or fallback locations if they don't encounter ignored
    file messages. Option b would slightly increase the prevalence of
    location-less messages.
All of these previously referenced a `Problem` type that does not have a
definition.
`ReportInfo` was defined within `report-translator.js` to be very
similar to `LintMessage`. It had one extra property, `source`, which
wasn't ever set, so it would've been removed anyway. In
`Linter.runRules()`, the return value from `reportTranslator()` gets
pushed into a `lintingProblems` array and returned, and the return type
annotation is `LintMessage[]`, which gives me confidence that
`ReportInfo` was intended to be the same type as `LintMessage`
elsewhere.
Originally, we talked about the reverse - making `ruleId` optional but
non-nullable and relying on `report-translator.js`'s `createProblem()`
to normalize it. However, the `LintMessage` type would differ from
`createProblem()`'s return value only by `null` vs `undefined` for
`ruleId`. So instead, I made `ruleId` required but nullable and
explicitly set it to `null` in the few remaining places that didn't
already.
`LintMessage.nodeType` is currently defined as required but nullable.
Actual implementations explicitly set it to `null` in a couple places
and omit it in several.

After discussion in eslint#16968, we initially leaned toward making it
non-nullable but optional. I pursued that, but it resulted in slightly
more runtime code changes, including some branching in
`report-translator` to set it conditionally.

Instead, I'm presenting the opposite solution of updating the remaining
implementations to match the existing type definition by explicitly
setting `nodeType` to `null`.
This updates existing documented properties to match the updated `LintMessage`
type and implementations.

`messageId`, `nodeType`, and `suppressions` remain undocumented.
@btmills btmills force-pushed the chore-unify-lint-message-type branch from c519894 to 55bed08 Compare May 7, 2023 01:17
@nzakas
Copy link
Member

nzakas commented May 8, 2023

@mdjermanovic can you take another look?

@mdjermanovic mdjermanovic changed the title chore: unify LintMessage type fix: unify LintMessage type May 16, 2023
@eslint-github-bot eslint-github-bot bot added the bug ESLint is working incorrectly label May 16, 2023
@mdjermanovic mdjermanovic removed evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion chore This change is not user-facing labels May 16, 2023
@mdjermanovic mdjermanovic added core Relates to ESLint's core APIs and features accepted There is consensus among the team that this change meets the criteria for inclusion labels May 16, 2023
@mdjermanovic
Copy link
Member

I changed this to fix: as it adds properties to objects that ESLint public APIs return.

Copy link
Member

@mdjermanovic mdjermanovic 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!

@mdjermanovic mdjermanovic merged commit 94da96c into eslint:main May 16, 2023
22 checks passed
@mdjermanovic
Copy link
Member

@btmills could you please submit this same change to docs/src/extend/custom-processors.md again in a new PR, as we had to undo it due to #17225.

@snitin315
Copy link
Contributor

Re-submitted in #17265

@btmills btmills deleted the chore-unify-lint-message-type branch June 12, 2023 18:47
@eslint-github-bot eslint-github-bot bot locked and limited conversation to collaborators Nov 13, 2023
@eslint-github-bot eslint-github-bot bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Nov 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion bug ESLint is working incorrectly core Relates to ESLint's core APIs and features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change Request: Correct and unify LintMessage type
5 participants