-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
feat: Allow languages to provide defaultLanguageOptions
#19003
Conversation
✅ Deploy Preview for docs-eslint canceled.
|
// wrap any parsers | ||
if (itemConfig.languageOptions && itemConfig.languageOptions.parser) { | ||
|
||
const parser = itemConfig.languageOptions.parser; | ||
|
||
if (parser && typeof parser !== "object") { | ||
throw new Error("Parser must be an object with a parse() or parseForESLint() method."); | ||
} | ||
|
||
} |
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.
JS language already checks this (see the updated RuleTester test case), so I just removed this check since we don't know what this property should be in other languages.
const report = engine.executeOnFiles(["lib/cli.js"]); | ||
const report = engine.executeOnFiles(["tests/fixtures/simple-valid-project/foo.js"]); |
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.
esprima
doesn't recognize the object spread syntax I used in lib/cli.js
, so I had to update this.
The browser test is failing on the main branch too. |
languageOptions.ecmaVersion = normalizeEcmaVersionForLanguageOptions( | ||
languageOptions.ecmaVersion | ||
); | ||
if (config.language === jslang) { |
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.
How will languages other than JS perform the kind of option normalization that's done in this block?
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.
Currently, there's no way to do that. We could consider allowing languages to provide a normalizeLanguageOptions()
method. Or maybe to return a value from validateLanguageOptions()
, though the naming would be weird and seems better to just have normalizeLanguageOptions()
that can throw an error if the config is invalid, otherwise return a normalized config.
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.
Currently, there's no way to do that. We could consider allowing languages to provide a
normalizeLanguageOptions()
method. Or maybe to return a value fromvalidateLanguageOptions()
, though the naming would be weird and seems better to just havenormalizeLanguageOptions()
that can throw an error if the config is invalid, otherwise return a normalized config.
Both options seem reasonable. Shall we leave this if-block as it stands and open a new issue to discuss how to normalize language options?
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.
Shall we leave this if-block as it stands and open a new issue to discuss how to normalize language options?
Sounds good to me.
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.
Alright, I'll file a new issue.
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 is a good catch. 👍
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.
LGTM, thanks! I'd suggest we also add defaultLanguageOptions
to the type definition for the Language
interface in @eslint/core
before marking #18985 as fixed.
Leaving open for a second review.
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.
LGTM. Let's update the types too.
I opened a PR to add |
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 really good!
For the question of whether or not languageOptions
can be undefined -- before this change, languageOptions
was always an object by the time we get into Linter
, so there was never an observable time when context.languageOptions
was undefined inside of a rule (because the default config had languageOptions
specified). So, despite Config
being able to create an object without languageOptions
, I think it may be better to default to an empty object for languageOptions
, which will prevent languages and rules from constantly needing to check for its existence.
What do you think?
languageOptions.ecmaVersion = normalizeEcmaVersionForLanguageOptions( | ||
languageOptions.ecmaVersion | ||
); | ||
if (config.language === jslang) { |
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 is a good catch. 👍
👍 I was also more inclined to make it always be an object. It's just that the previous code looked like it should be |
Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
e092417
A93C
Updated |
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.
LGTM. Would like @fasttime to approve before merging.
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.
LGTM. We will bump the @eslint/core
version in package.json during today's release #19000 to make sure that users get the updated Language
type with defaultLanguageOptions
.
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@eslint/js](https://eslint.org) ([source](https://github.com/eslint/eslint/tree/HEAD/packages/js)) | devDependencies | minor | [`9.10.0` -> `9.13.0`](https://renovatebot.com/diffs/npm/@eslint%2fjs/9.10.0/9.13.0) | --- ### Release Notes <details> <summary>eslint/eslint (@​eslint/js)</summary> ### [`v9.13.0`](https://github.com/eslint/eslint/releases/tag/v9.13.0) [Compare Source](eslint/eslint@v9.12.0...v9.13.0) #### Features - [`381c32b`](eslint/eslint@381c32b) feat: Allow languages to provide `defaultLanguageOptions` ([#​19003](eslint/eslint#19003)) (Milos Djermanovic) - [`bf723bd`](eslint/eslint@bf723bd) feat: Improve eslintrc warning message ([#​19023](eslint/eslint#19023)) (Milos Djermanovic) - [`1def4cd`](eslint/eslint@1def4cd) feat: drop support for jiti v1.21 ([#​18996](eslint/eslint#18996)) (Francesco Trotta) - [`f879be2`](eslint/eslint@f879be2) feat: export `ESLint.defaultConfig` ([#​18983](eslint/eslint#18983)) (Nitin Kumar) #### Bug Fixes - [`78836d4`](eslint/eslint@78836d4) fix: update the `complexity` rule type ([#​19027](eslint/eslint#19027)) (Nitin Kumar) - [`064c8b6`](eslint/eslint@064c8b6) fix: update rule types ([#​18925](eslint/eslint#18925)) (Nitin Kumar) #### Documentation - [`abdbfa8`](eslint/eslint@abdbfa8) docs: mark `LintMessage#nodeType` as deprecated ([#​19019](eslint/eslint#19019)) (Nitin Kumar) - [`19e68d3`](eslint/eslint@19e68d3) docs: update deprecated rules type definitions ([#​19018](eslint/eslint#19018)) (Nitin Kumar) - [`7dd402d`](eslint/eslint@7dd402d) docs: Update examples of passing multiple values to a CLI option ([#​19006](eslint/eslint#19006)) (Milos Djermanovic) - [`5dcbc51`](eslint/eslint@5dcbc51) docs: Add example with side-effect imports to no-restricted-imports ([#​18997](eslint/eslint#18997)) (Milos Djermanovic) - [`1ee87ca`](eslint/eslint@1ee87ca) docs: Update README (GitHub Actions Bot) - [`2c3dbdc`](eslint/eslint@2c3dbdc) docs: Use prerendered sponsors for README ([#​18988](eslint/eslint#18988)) (Milos Djermanovic) #### Chores - [`68d2d9d`](eslint/eslint@68d2d9d) chore: upgrade to `@eslint/js@9.13.0` and `@eslint/core@^0.7.0` ([#​19034](eslint/eslint#19034)) (Francesco Trotta) - [`2211f0a`](eslint/eslint@2211f0a) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`c7abaef`](eslint/eslint@c7abaef) perf: using Node.js compile cache ([#​19012](eslint/eslint#19012)) (唯然) - [`1d7c077`](eslint/eslint@1d7c077) chore: add pkg.type "commonjs" ([#​19011](eslint/eslint#19011)) (唯然) - [`468e3bd`](eslint/eslint@468e3bd) test: fix `ESLint` tests ([#​19021](eslint/eslint#19021)) (Francesco Trotta) - [`ed4635f`](eslint/eslint@ed4635f) ci: upgrade knip@5.32.0 ([#​18992](eslint/eslint#18992)) (Milos Djermanovic) - [`efad767`](eslint/eslint@efad767) chore: remove unused ignore dependency ([#​18993](eslint/eslint#18993)) (Amaresh S M) ### [`v9.12.0`](https://github.com/eslint/eslint/releases/tag/v9.12.0) [Compare Source](eslint/eslint@v9.11.1...v9.12.0) #### Features - [`5a6a053`](eslint/eslint@5a6a053) feat: update to `jiti` v2 ([#​18954](eslint/eslint#18954)) (Arya Emami) - [`17a07fb`](eslint/eslint@17a07fb) feat: Hooks for test cases (RuleTester) ([#​18771](eslint/eslint#18771)) (Anna Bocharova) - [`2ff0e51`](eslint/eslint@2ff0e51) feat: Implement alternate config lookup ([#​18742](eslint/eslint#18742)) (Nicholas C. Zakas) - [`2d17453`](eslint/eslint@2d17453) feat: Implement modified cyclomatic complexity ([#​18896](eslint/eslint#18896)) (Dmitry Pashkevich) #### Bug Fixes - [`ea380ca`](eslint/eslint@ea380ca) fix: Upgrade retry to avoid EMFILE errors ([#​18986](eslint/eslint#18986)) (Nicholas C. Zakas) - [`fdd6319`](eslint/eslint@fdd6319) fix: Issues with type definitions ([#​18940](eslint/eslint#18940)) (Arya Emami) #### Documentation - [`ecbd522`](eslint/eslint@ecbd522) docs: Mention code explorer ([#​18978](eslint/eslint#18978)) (Nicholas C. Zakas) - [`7ea4ecc`](eslint/eslint@7ea4ecc) docs: Clarifying the Use of Meta Objects ([#​18697](eslint/eslint#18697)) (Amaresh S M) - [`d3e4b2e`](eslint/eslint@d3e4b2e) docs: Clarify how to exclude `.js` files ([#​18976](eslint/eslint#18976)) (Milos Djermanovic) - [`57232ff`](eslint/eslint@57232ff) docs: Mention plugin-kit in language docs ([#​18973](eslint/eslint#18973)) (Nicholas C. Zakas) - [`b80ed00`](eslint/eslint@b80ed00) docs: Update README (GitHub Actions Bot) - [`cb69ab3`](eslint/eslint@cb69ab3) docs: Update README (GitHub Actions Bot) - [`7fb0d95`](eslint/eslint@7fb0d95) docs: Update README (GitHub Actions Bot) - [`493348a`](eslint/eslint@493348a) docs: Update README (GitHub Actions Bot) - [`87a582c`](eslint/eslint@87a582c) docs: fix typo in `id-match` rule ([#​18944](eslint/eslint#18944)) (Jay) #### Chores - [`555aafd`](eslint/eslint@555aafd) chore: upgrade to `@eslint/js@9.12.0` ([#​18987](eslint/eslint#18987)) (Francesco Trotta) - [`873ae60`](eslint/eslint@873ae60) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`d0a5414`](eslint/eslint@d0a5414) refactor: replace strip-ansi with native module ([#​18982](eslint/eslint#18982)) (Cristopher) - [`b827029`](eslint/eslint@b827029) chore: Enable JSON5 linting ([#​18979](eslint/eslint#18979)) (Milos Djermanovic) - [`8f55ca2`](eslint/eslint@8f55ca2) chore: Upgrade espree, eslint-visitor-keys, eslint-scope ([#​18962](eslint/eslint#18962)) (Nicholas C. Zakas) - [`c1a2725`](eslint/eslint@c1a2725) chore: update dependency mocha to ^10.7.3 ([#​18945](eslint/eslint#18945)) (Milos Djermanovic) ### [`v9.11.1`](https://github.com/eslint/eslint/releases/tag/v9.11.1) [Compare Source](eslint/eslint@v9.11.0...v9.11.1) #### Bug Fixes - [`20fd916`](eslint/eslint@20fd916) fix: add `@eslint/core`, `@types/estree`, & `@types/json-schema` deps ([#​18938](eslint/eslint#18938)) (Nitin Kumar) - [`2738322`](eslint/eslint@2738322) fix: add missing types for `require-atomic-updates` rule ([#​18937](eslint/eslint#18937)) (Kristóf Poduszló) - [`d71ff30`](eslint/eslint@d71ff30) fix: add missing types for `object-shorthand` rule ([#​18935](eslint/eslint#18935)) (Kristóf Poduszló) - [`561cadc`](eslint/eslint@561cadc) fix: add missing types for `no-unsafe-negation` rule ([#​18932](eslint/eslint#18932)) (Kristóf Poduszló) - [`8843656`](eslint/eslint@8843656) fix: add missing types for `no-underscore-dangle` rule ([#​18931](eslint/eslint#18931)) (Kristóf Poduszló) - [`92cde5c`](eslint/eslint@92cde5c) fix: add missing types for `no-shadow` rule ([#​18930](eslint/eslint#18930)) (Kristóf Poduszló) - [`b3cbe11`](eslint/eslint@b3cbe11) fix: add missing types for `no-sequences` rule ([#​18929](eslint/eslint#18929)) (Kristóf Poduszló) - [`976f77f`](eslint/eslint@976f77f) fix: add missing types for `no-unused-expressions` rule ([#​18933](eslint/eslint#18933)) (Kristóf Poduszló) #### Documentation - [`3eff709`](eslint/eslint@3eff709) docs: replace deprecated `Linter.FlatConfig` type with `Linter.Config` ([#​18941](eslint/eslint#18941)) (Carlos Meira) #### Chores - [`df4a859`](eslint/eslint@df4a859) chore: upgrade [@​eslint/js](https://github.com/eslint/js)[@​9](https://github.com/9).11.1 ([#​18943](eslint/eslint#18943)) (Milos Djermanovic) - [`36d8095`](eslint/eslint@36d8095) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) ### [`v9.11.0`](https://github.com/eslint/eslint/releases/tag/v9.11.0) [Compare Source](eslint/eslint@v9.10.0...v9.11.0) #### Features - [`ec30c73`](eslint/eslint@ec30c73) feat: add "eslint/universal" to export `Linter` ([#​18883](eslint/eslint#18883)) (唯然) - [`c591da6`](eslint/eslint@c591da6) feat: Add language to types ([#​18917](eslint/eslint#18917)) (Nicholas C. Zakas) - [`492eb8f`](eslint/eslint@492eb8f) feat: limit the name given to `ImportSpecifier` in `id-length` ([#​18861](eslint/eslint#18861)) (Tanuj Kanti) - [`19c6856`](eslint/eslint@19c6856) feat: Add `no-useless-constructor` suggestion ([#​18799](eslint/eslint#18799)) (Jordan Thomson) - [`a48f8c2`](eslint/eslint@a48f8c2) feat: add type `FormatterFunction`, update `LoadedFormatter` ([#​18872](eslint/eslint#18872)) (Francesco Trotta) #### Bug Fixes - [`5e5f39b`](eslint/eslint@5e5f39b) fix: add missing types for `no-restricted-exports` rule ([#​18914](eslint/eslint#18914)) (Kristóf Poduszló) - [`8f630eb`](eslint/eslint@8f630eb) fix: add missing types for `no-param-reassign` options ([#​18906](eslint/eslint#18906)) (Kristóf Poduszló) - [`d715781`](eslint/eslint@d715781) fix: add missing types for `no-extra-boolean-cast` options ([#​18902](eslint/eslint#18902)) (Kristóf Poduszló) - [`2de5742`](eslint/eslint@2de5742) fix: add missing types for `no-misleading-character-class` options ([#​18905](eslint/eslint#18905)) (Kristóf Poduszló) - [`c153084`](eslint/eslint@c153084) fix: add missing types for `no-implicit-coercion` options ([#​18903](eslint/eslint#18903)) (Kristóf Poduszló) - [`fa11b2e`](eslint/eslint@fa11b2e) fix: add missing types for `no-empty-function` options ([#​18901](eslint/eslint#18901)) (Kristóf Poduszló) - [`a0deed1`](eslint/eslint@a0deed1) fix: add missing types for `camelcase` options ([#​18897](eslint/eslint#18897)) (Kristóf Poduszló) #### Documentation - [`e4e5709`](eslint/eslint@e4e5709) docs: correct `prefer-object-has-own` type definition comment ([#​18924](eslint/eslint#18924)) (Nitin Kumar) - [`91cbd18`](eslint/eslint@91cbd18) docs: add unicode abbreviations in no-irregular-whitespace rule ([#​18894](eslint/eslint#18894)) (Alix Royere) - [`59cfc0f`](eslint/eslint@59cfc0f) docs: clarify `resultsMeta` in `LoadedFormatter` type ([#​18881](eslint/eslint#18881)) (Milos Djermanovic) - [`adcc50d`](eslint/eslint@adcc50d) docs: Update README (GitHub Actions Bot) - [`4edac1a`](eslint/eslint@4edac1a) docs: Update README (GitHub Actions Bot) #### Build Related - [`959d360`](eslint/eslint@959d360) build: Support updates to previous major versions ([#​18871](eslint/eslint#18871)) (Milos Djermanovic) #### Chores - [`ca21a64`](eslint/eslint@ca21a64) chore: upgrade [@​eslint/js](https://github.com/eslint/js)[@​9](https://github.com/9).11.0 ([#​18927](eslint/eslint#18927)) (Milos Djermanovic) - [`a10f90a`](eslint/eslint@a10f90a) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`e4e02cc`](eslint/eslint@e4e02cc) refactor: Extract processor logic into ProcessorService ([#​18818](eslint/eslint#18818)) (Nicholas C. Zakas) - [`6d4484d`](eslint/eslint@6d4484d) chore: updates for v8.57.1 release (Jenkins) - [`71f37c5`](eslint/eslint@71f37c5) refactor: use optional chaining when validating config rules ([#​18893](eslint/eslint#18893)) (lucasrmendonca) - [`2c2805f`](eslint/eslint@2c2805f) chore: Add PR note to all templates ([#​18892](eslint/eslint#18892)) (Nicholas C. Zakas) - [`7b852ce`](eslint/eslint@7b852ce) refactor: use `Directive` class from `@eslint/plugin-kit` ([#​18884](eslint/eslint#18884)) (Milos Djermanovic) - [`d594ddd`](eslint/eslint@d594ddd) chore: update dependency [@​eslint/core](https://github.com/eslint/core) to ^0.6.0 ([#​18863](eslint/eslint#18863)) (renovate\[bot]) - [`78b2421`](eslint/eslint@78b2421) chore: Update change.yml ([#​18882](eslint/eslint#18882)) (Nicholas C. Zakas) - [`a416f0a`](eslint/eslint@a416f0a) chore: enable `$ExpectType` comments in .ts files ([#​18869](eslint/eslint#18869)) (Francesco Trotta) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC44MC4wIiwidXBkYXRlZEluVmVyIjoiMzguODAuMCIsInRhcmdldEJyYW5jaCI6ImRldmVsb3AiLCJsYWJlbHMiOlsidHlwZS9kZXBlbmRlbmNpZXMiXX0=--> Reviewed-on: https://git.vylpes.xyz/RabbitLabs/random-bunny/pulls/231 Reviewed-by: Vylpes <ethan@vylpes.com> Co-authored-by: Renovate Bot <renovate@vylpes.com> Co-committed-by: Renovate Bot <renovate@vylpes.com>
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
[x] Add something to the core
[ ] Other, please explain:
Fixes #18985.
What changes did you make? (Give an overview)
Config
class to usedefaultLanguageOptions
property from the language, if provided. User-definedlanguageOptions
in the config array are merged overLanguage#defaultLanguageOptions
to make the final calculatedlanguageOptions
.cli
to not pass alanguageOptions
object inoverrideConfig
unless necessary (when--global
,--parser
or--parser-options
CLI option was used).Is there anything you'd like reviewers to focus on?
By the previous code in the
Config
class, in particular theif (languageOptions)
check, I assumed we wantlanguageOptions
to beundefined
in the final config object if there were no default language options and no user-provided language options in the config array. So, in that case, ESLint will passlanguageOptions: undefined
toLanguage#parse()
andLanguage#createSourceCode()
methods. If that's the desired behavior, we might also want to update types. Also,context.languageOptions
in rules will beundefined
.