Skip to content

Linter plugins: Support options for JS rules #14825

@overlookmotel

Description

@overlookmotel

We need to support options passed to JS rules.

e.g.:

{
  "jsPlugins": ["./some-plugin.js"],
  "rules": {
    "some-plugin/stuff": ["error", true, false],
    "some-plugin/other-stuff": ["error", { "option": true, "otherOption": false }]
  }
}

Would result in the rules receiving these values as options property on Context object:

// `stuff` rule
[true, false]
// `other-stuff` rule
[{ option: true, otherOption: false }]

Implementation

Configs are parsed only once. So it'd be unnecessary to repeatedly pass options as objects/JSON to lintFile (on JS side) for every file.

I imagine something like this:

  • Have an IndexVec keyed by ExternalOptionsId, containing serde_json::Values, representing options arrays.
  • First element of the IndexVec (index 0) is reserved for "no options". Contains an empty array.
  • When parsing a config file:
    • Push any options for JS rules onto the IndexVec.
    • Record the ExternalOptionsId in the config object, along with ExternalRuleId.
    • If no options provided for a rule, use 0 as ExternalOptionsId.
  • After processing all configs:
    • Serialize all of the options from all configs (the IndexVec) to JSON (as a single array).
    • Send that JSON to JS, JSON.parse on JS side, and store as allOptions array.
  • When linting a file:
    • Send array of ExternalRuleId + ExternalOptionsId pairs to JS side - to say what rules to run, with what options.
    • On JS side, get the options object for each rule from allOptions array (at index ExternalOptionsId).
    • Set options property of Context to the options for each rule.
    • Run rules on the file (as now).

Overall idea is:

  • Only do the expensive work of serializing, sending to JS, and deserializing options once.
  • For each file, all that needs to be sent to JS is a number (ExternalOptionsId), which points to the relevant options object. This is much cheaper.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions