Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/oxlint/src-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import type { SetNullable } from "./utils/types.ts";
export type * as ESTree from "./generated/types.d.ts";
export type { Context, LanguageOptions } from "./plugins/context.ts";
export type { Fix, Fixer, FixFn } from "./plugins/fix.ts";
export type { CreateOnceRule, CreateRule, Options, Plugin, Rule } from "./plugins/load.ts";
export type { CreateOnceRule, CreateRule, Plugin, Rule } from "./plugins/load.ts";
export type { Options } from "./plugins/options.ts";
export type { Diagnostic, Suggestion } from "./plugins/report.ts";
export type {
Definition,
Expand Down
4 changes: 3 additions & 1 deletion apps/oxlint/src-js/plugins/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import { report } from "./report.js";
import { settings, initSettings } from "./settings.js";
import { debugAssertIsNonNull } from "../utils/asserts.js";

import type { Options, RuleDetails } from "./load.ts";
import type { RuleDetails } from "./load.ts";
import type { Options } from "./options.ts";
import type { Diagnostic } from "./report.ts";
import type { Settings } from "./settings.ts";
import type { SourceCode } from "./source_code.ts";
Expand Down Expand Up @@ -363,6 +364,7 @@ export function createContext(fullRuleName: string, ruleDetails: RuleDetails): R
// Getter for rule options for this rule on this file
get options(): Readonly<Options> {
if (filePath === null) throw new Error("Cannot access `context.options` in `createOnce`");
debugAssertIsNonNull(ruleDetails.options);
return ruleDetails.options;
},
/**
Expand Down
11 changes: 10 additions & 1 deletion apps/oxlint/src-js/plugins/lint.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { setupFileContext, resetFileContext } from "./context.js";
import { registeredRules } from "./load.js";
import { allOptions, DEFAULT_OPTIONS_ID } from "./options.js";
import { diagnostics } from "./report.js";
import { setSettingsForFile, resetSettings } from "./settings.js";
import { ast, initAst, resetSourceAndAst, setupSourceForFile } from "./source_code.js";
Expand Down Expand Up @@ -55,8 +56,11 @@ export function lintFile(
ruleIds: number[],
settingsJSON: string,
): string {
// TODO: Get `optionsIds` from Rust side
const optionsIds = ruleIds.map((_) => DEFAULT_OPTIONS_ID);

try {
lintFileImpl(filePath, bufferId, buffer, ruleIds, settingsJSON);
lintFileImpl(filePath, bufferId, buffer, ruleIds, optionsIds, settingsJSON);
return JSON.stringify({ Success: diagnostics });
} catch (err) {
return JSON.stringify({ Failure: getErrorMessage(err) });
Expand All @@ -72,6 +76,7 @@ export function lintFile(
* @param bufferId - ID of buffer containing file data
* @param buffer - Buffer containing file data, or `null` if buffer with this ID was previously sent to JS
* @param ruleIds - IDs of rules to run on this file
* @param optionsIds - IDs of options to use for rules on this file
* @param settingsJSON - Stringified settings for this file
* @returns Diagnostics to send back to Rust
* @throws {Error} If any parameters are invalid
Expand All @@ -82,6 +87,7 @@ function lintFileImpl(
bufferId: number,
buffer: Uint8Array | null,
ruleIds: number[],
optionsIds: number[],
settingsJSON: string,
) {
// If new buffer, add it to `buffers` array. Otherwise, get existing buffer from array.
Expand Down Expand Up @@ -141,6 +147,9 @@ function lintFileImpl(
// Set `ruleIndex` for rule. It's used when sending diagnostics back to Rust.
ruleDetails.ruleIndex = i;

// Set `options` for rule
ruleDetails.options = allOptions[optionsIds[i]];

let { visitor } = ruleDetails;
if (visitor === null) {
// Rule defined with `create` method
Expand Down
14 changes: 3 additions & 11 deletions apps/oxlint/src-js/plugins/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getErrorMessage } from "../utils/utils.js";

import type { Writable } from "type-fest";
import type { Context } from "./context.ts";
import type { JsonValue } from "./json.ts";
import type { Options } from "./options.ts";
import type { RuleMeta } from "./rule_meta.ts";
import type { AfterHook, BeforeHook, Visitor, VisitorWithHooks } from "./types.ts";
import type { SetNullable } from "../utils/types.ts";
Expand Down Expand Up @@ -46,11 +46,6 @@ export interface CreateOnceRule {
createOnce: (context: Context) => VisitorWithHooks;
}

/**
* Options for a rule on a file.
*/
export type Options = JsonValue[];

/**
* Linter rule, context object, and other details of rule.
* If `rule` has a `createOnce` method, the visitor it returns is stored in `visitor` property.
Expand All @@ -64,7 +59,7 @@ interface RuleDetailsBase {
readonly messages: Readonly<Record<string, string>> | null;
// Updated for each file
ruleIndex: number;
options: Readonly<Options>;
options: Readonly<Options> | null; // Initially `null`, set to options object before linting a file
}

interface CreateRuleDetails extends RuleDetailsBase {
Expand All @@ -91,9 +86,6 @@ export const registeredRules: RuleDetails[] = [];
// `before` hook which makes rule never run.
const neverRunBeforeHook: BeforeHook = () => false;

// Default rule options
const DEFAULT_OPTIONS: Readonly<Options> = Object.freeze([]);

// Plugin details returned to Rust
interface PluginDetails {
// Plugin name
Expand Down Expand Up @@ -186,7 +178,7 @@ async function loadPluginImpl(path: string, packageName: string | null): Promise
isFixable,
messages,
ruleIndex: 0,
options: DEFAULT_OPTIONS,
options: null,
visitor: null,
beforeHook: null,
afterHook: null,
Expand Down
19 changes: 19 additions & 0 deletions apps/oxlint/src-js/plugins/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Options for rules.
*/

import type { JsonValue } from "./json.ts";

/**
* Options for a rule on a file.
*/
export type Options = JsonValue[];

// Default rule options
const DEFAULT_OPTIONS: Readonly<Options> = Object.freeze([]);

// All rule options
export const allOptions: Readonly<Options>[] = [DEFAULT_OPTIONS];

// Index into `allOptions` for default options
export const DEFAULT_OPTIONS_ID = 0;
Loading