Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(linter/plugins): rule options#16215

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
lilnasy wants to merge12 commits intooxc-project:main
base:main
Choose a base branch
Loading
fromlilnasy:js-plugin-options

Conversation

@lilnasy
Copy link
Contributor

@lilnasylilnasy commentedNov 27, 2025
edited
Loading

Big changes from the original approach

  • Options IDs are stored in their own arrays. This was laid out inrefactor(linter/plugins): prepare for rule options #16158. The original approach was to storeruleId-optionId pairs as tuples in an array - several heap allocated objects and excessive pointer indirection.
  • The rust code populates the options by calling a new JS callback namedsetupConfigs(). I expect we would use this callback for more plugin related data, including settings which are currently implemented in a hacky way.
  • Investigate a refactor to avoid requiring a mutable reference toExternalPluginStore everywhere.

Smaller Changes

  • Removed the extra fixture ("working version"). There were no meaningful changes compared to the first fixture. Probably slop.

CopilotAI review requested due to automatic review settingsNovember 27, 2025 20:58
@lilnasylilnasy marked this pull request as draftNovember 27, 2025 20:58
@github-actionsgithub-actionsbot added A-linterArea - Linter A-cliArea - CLI A-editorArea - Editor and Language Server A-linter-pluginsArea - Linter JS plugins C-enhancementCategory - New feature or request labelsNov 27, 2025
Copilot finished reviewing on behalf oflilnasyNovember 27, 2025 21:00
Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements rule options support for external JavaScript plugins in the linter. It introduces anExternalOptionsId type to track and pass rule-specific configuration options from Rust to JavaScript plugins, allowing JS plugin rules to receive configuration parameters similar to ESLint rule options.

Key changes:

  • AddedExternalOptionsId type and options storage toExternalPluginStore with index 0 reserved for "no options"
  • Updated external rule signatures from(ExternalRuleId, AllowWarnDeny) to(ExternalRuleId, ExternalOptionsId, AllowWarnDeny) throughout the codebase
  • Implemented options serialization/deserialization flow between Rust and JavaScript usingOnceLock for thread-safe caching

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/oxc_linter/src/external_plugin_store.rsAddedExternalOptionsId type and options storage with index 0 reserved for empty/null options
crates/oxc_linter/src/external_linter.rsUpdated callback signature to includeoptions_ids parameter
crates/oxc_linter/src/lib.rsUpdated external rule handling to pass options IDs to JS side
crates/oxc_linter/src/config/rules.rsModifiedoverride_rules to track options alongside severity; added comprehensive tests
crates/oxc_linter/src/config/config_store.rsUpdated rule storage and override logic to handle options IDs; added override precedence test
crates/oxc_linter/src/config/config_builder.rsUpdated builder to accept mutable reference to external plugin store for options registration
crates/oxc_linter/src/config/mod.rsUpdated test to use mutable external plugin store
crates/oxc_linter/src/tester.rsUpdated to pass mutable reference to external plugin store
crates/oxc_language_server/src/linter/server_linter.rsUpdated config building calls to use mutable external plugin store
tasks/benchmark/benches/linter.rsUpdated benchmark to use mutable external plugin store
napi/playground/src/lib.rsUpdated playground to properly share external plugin store between config building and linter creation
apps/oxlint/src/run.rsAddedOnceLock-based caching for serialized options JSON and export function for JS
apps/oxlint/src/lint.rsAdded serialization of external options after config building
apps/oxlint/src/js_plugins/external_linter.rsUpdated wrapper to forward options IDs to JS callback
apps/oxlint/src-js/plugins/options.tsAdded options initialization logic and storage
apps/oxlint/src-js/plugins/load.tsDuplicated options initialization logic (should be removed)
apps/oxlint/src-js/plugins/lint.tsAdded lazy options initialization and options ID handling; duplicateruleIndex assignment
apps/oxlint/src-js/cli.tsUpdated wrapper to forward options IDs parameter
apps/oxlint/src-js/bindings.jsExportedgetExternalRuleOptions function
apps/oxlint/src-js/bindings.d.tsAdded TypeScript declaration forgetExternalRuleOptions
apps/oxlint/test/fixtures/custom_plugin_with_options/*Added integration test fixture for external plugin with options

💡Add Copilot custom instructions for smarter, more guided reviews.Learn how to get started.

Comment on lines 35 to 40
/// JS callable function to retrieve the serialized external rule options.
/// Returns a JSON string of options arrays. Called once from JS after creating the external linter.
#[cfg(all(feature ="napi", target_pointer_width ="64", target_endian ="little"))]
#[napi]
pubfnget_external_rule_options() ->Option<String>{
EXTERNAL_OPTIONS_JSON.get().cloned()

Choose a reason for hiding this comment

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

The documentation comment states "Returns a JSON string of options arrays" but the function returnsOption<String>, which can beNone. The comment should clarify whenNone is returned (e.g., "Returns a JSON string of options arrays, orNone if options haven't been set yet").

Copilot uses AI. Check for mistakes.
@codspeed-hq
Copy link

codspeed-hqbot commentedNov 27, 2025
edited
Loading

CodSpeed Performance Report

Merging#16215 willnot alter performance

Comparinglilnasy:js-plugin-options (42eee5d) withmain (505ceb1)

Summary

✅ 42 untouched
⏩ 3 skipped1

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase,click here and archive them to remove them from the performance reports.

@lilnasylilnasyforce-pushed thejs-plugin-options branch 2 times, most recently froma7a3ca1 to9c2d8a4CompareNovember 27, 2025 21:11
@overlookmotel
Copy link
Member

Just a note: As I mentioned on Discord, I don't think we should worry about merging options with default options in this first PR - can leave that to a follow-on. But FYI I've implemented the merging logic in#16217 because I needed it for the rule tester.

lilnasy reacted with thumbs up emoji

@lilnasylilnasyforce-pushed thejs-plugin-options branch 2 times, most recently fromd62762c to3c46139CompareNovember 28, 2025 13:01
@overlookmotel
Copy link
Member

overlookmotel commentedNov 28, 2025
edited
Loading

Refactor to avoid requiring a mutable reference toExternalPluginStore everywhere.

I know it was me that said this should be possible, but I could very well be wrong. If it's not possible, don't worry about it.

lilnasy reacted with thumbs up emoji

Comment on lines 294 to 304
// TODO: refactor this elsewhere.
// This code is in the oxlint app, not in oxc_linter crate
ifletSome(ref external_linter) = external_linter{
ifletErr(err) = external_plugin_store.setup_configs(external_linter){
print_and_flush_stdout(
stdout,
&format!("Failed to setup external plugin options: {err}\n"),
);
returnCliRunResult::InvalidOptionConfig;
}
}
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I could use help here. I exposedsetup_configs() for theoxlint crate by putting it onExternalPluginStore only because it's the first place I found. I could do with a few pointers on separation of concerns regarding these structs.

Copy link
Member

@overlookmoteloverlookmotelNov 29, 2025
edited
Loading

Choose a reason for hiding this comment

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

Yeah, the types are a bit of a convoluted mess here. I'm tied up today. Will take a look tomorrow.

@lilnasylilnasy marked this pull request as ready for reviewNovember 28, 2025 20:25
Copilot finished reviewing on behalf oflilnasyNovember 28, 2025 20:28
Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 2 comments.


💡Add Copilot custom instructions for smarter, more guided reviews.Learn how to get started.

Comment on lines +4 to +14
* Populates Rust-resolved configuration options on the JS side.
* Called from Rust side after all configuration options have been resolved.
*
* Note: the name `setupConfigs` is currently incorrect, as we only populate rule options.
* The intention is for this function to transfer all configurations in a multi-config workspace.
* The configuration relevant to each file would then be resolved on the JS side.
*
*@param optionsJSON - JSON serialization of an array containing all rule options across all configurations.
*@returns "ok" on success, or error message on failure
*/
exportfunctionsetupConfigs(optionsJSON:string):string{

Choose a reason for hiding this comment

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

[nitpick] The comment states "Note: the namesetupConfigs is currently incorrect, as we only populate rule options." While this is acknowledged as a TODO, consider renaming tosetupOptions orsetupRuleOptions to accurately reflect the current functionality. This would make the code clearer until multi-config workspace support is implemented.

Suggested change
*PopulatesRust-resolvedconfigurationoptionsontheJSside.
*CalledfromRustsideafterallconfigurationoptionshavebeenresolved.
*
*Note:thename`setupConfigs`iscurrentlyincorrect,asweonlypopulateruleoptions.
*Theintentionisforthisfunctiontotransferallconfigurationsinamulti-configworkspace.
*TheconfigurationrelevanttoeachfilewouldthenberesolvedontheJSside.
*
* @paramoptionsJSON-JSONserializationofanarraycontainingallruleoptionsacrossallconfigurations.
* @returns"ok"onsuccess,orerrormessageonfailure
*/
exportfunctionsetupConfigs(optionsJSON:string):string{
*PopulatesRust-resolvedruleoptionsontheJSside.
*CalledfromRustsideafterallruleoptionshavebeenresolved.
*
*Theintentionisforthisfunctiontoeventuallytransferallconfigurationsinamulti-configworkspace.
*TheconfigurationrelevanttoeachfilewouldthenberesolvedontheJSside.
*
* @paramoptionsJSON-JSONserializationofanarraycontainingallruleoptionsacrossallconfigurations.
* @returns"ok"onsuccess,orerrormessageonfailure
*/
exportfunctionsetupOptions(optionsJSON:string):string{

Copilot uses AI. Check for mistakes.
Comment on lines +158 to 162

// If the rule has no user-provided options, use the plugin-provided default
// options (which falls back to `DEFAULT_OPTIONS`)
ruleDetails.options=
optionsId===DEFAULT_OPTIONS_ID ?ruleDetails.defaultOptions :allOptions[optionsId];
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

@overlookmotel You mentioned this could be simplified toallOptions[optionsId]. How would plugin-provided default options get used in that case?

constel=parsed[i];
if(!isArray(el))thrownewTypeError("Each options entry must be an array",{cause:el});
}
}
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

This is a debug check because I this validation is done probably done on the rust side as well. I need to confirm this.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

@camc314camc314Awaiting requested review from camc314camc314 is a code owner

@SysixSysixAwaiting requested review from SysixSysix is a code owner

@overlookmoteloverlookmotelAwaiting requested review from overlookmoteloverlookmotel is a code owner

At least 0 approving reviews are required to merge this pull request.

Assignees

No one assigned

Labels

A-cliArea - CLIA-editorArea - Editor and Language ServerA-linterArea - LinterA-linter-pluginsArea - Linter JS pluginsC-enhancementCategory - New feature or request

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

3 participants

@lilnasy@overlookmotel@wagenet

[8]ページ先頭

©2009-2025 Movatter.jp