diff --git a/napi/oxlint2/src-js/index.js b/napi/oxlint2/src-js/index.js index 4db69f2c11ec4..7e27701ca1d8d 100644 --- a/napi/oxlint2/src-js/index.js +++ b/napi/oxlint2/src-js/index.js @@ -50,17 +50,14 @@ async function loadPluginImpl(path) { registeredPluginPaths.add(path); // TODO: Use a validation library to assert the shape of the plugin, and of rules + const pluginName = plugin.meta.name; let ruleId = registeredRules.length; const ruleNames = []; - const ret = { - name: plugin.meta.name, - offset: ruleId, - ruleNames, - }; + const ret = { name: pluginName, offset: ruleId, ruleNames }; for (const [ruleName, rule] of Object.entries(plugin.rules)) { ruleNames.push(ruleName); - registeredRules.push({ rule, context: new Context(ruleId) }); + registeredRules.push({ rule, context: new Context(ruleId, `${pluginName}/${ruleName}`) }); ruleId++; } @@ -75,15 +72,19 @@ async function loadPluginImpl(path) { class Context { // Rule ID. Index into `registeredRules` array. #ruleId; + // Full rule name, including plugin name e.g. `my-plugin/my-rule`. + id; // Absolute path of file being linted. Set before calling `rule`'s `create` method. physicalFilename; /** * @constructor * @param {number} ruleId - Rule ID + * @param {string} fullRuleName - Rule name, in form `/` */ - constructor(ruleId) { + constructor(ruleId, fullRuleName) { this.#ruleId = ruleId; + this.id = fullRuleName; } /** diff --git a/napi/oxlint2/test/__snapshots__/e2e.test.ts.snap b/napi/oxlint2/test/__snapshots__/e2e.test.ts.snap index 50c7fcb320b40..931853a05b2a8 100644 --- a/napi/oxlint2/test/__snapshots__/e2e.test.ts.snap +++ b/napi/oxlint2/test/__snapshots__/e2e.test.ts.snap @@ -322,6 +322,36 @@ Found 20 warnings and 20 errors. Finished in Xms on 20 files using X threads." `; +exports[`oxlint2 CLI > should receive data via \`context\` 1`] = ` +" + x context-plugin(log-context): id: context-plugin/log-context + ,-[files/1.js:1:1] + 1 | let x; + : ^ + \`---- + + x context-plugin(log-context): physicalFilename: files/1.js + ,-[files/1.js:1:1] + 1 | let x; + : ^ + \`---- + + x context-plugin(log-context): id: context-plugin/log-context + ,-[files/2.js:1:1] + 1 | let y; + : ^ + \`---- + + x context-plugin(log-context): physicalFilename: files/2.js + ,-[files/2.js:1:1] + 1 | let y; + : ^ + \`---- + +Found 0 warnings and 4 errors. +Finished in Xms on 2 files using X threads." +`; + exports[`oxlint2 CLI > should report an error if a custom plugin cannot be loaded 1`] = ` "Failed to parse configuration file. diff --git a/napi/oxlint2/test/e2e.test.ts b/napi/oxlint2/test/e2e.test.ts index 7fdfc1d7c82d5..5ad8eaf78076a 100644 --- a/napi/oxlint2/test/e2e.test.ts +++ b/napi/oxlint2/test/e2e.test.ts @@ -101,4 +101,13 @@ describe('oxlint2 CLI', () => { expect(exitCode).toBe(1); expect(normalizeOutput(stdout)).toMatchSnapshot(); }); + + it('should receive data via `context`', async () => { + const { stdout, exitCode } = await runOxlint( + 'test/fixtures/context_properties', + ); + + expect(exitCode).toBe(1); + expect(normalizeOutput(stdout)).toMatchSnapshot(); + }); }); diff --git a/napi/oxlint2/test/fixtures/context_properties/.oxlintrc.json b/napi/oxlint2/test/fixtures/context_properties/.oxlintrc.json new file mode 100644 index 0000000000000..f25a30f276243 --- /dev/null +++ b/napi/oxlint2/test/fixtures/context_properties/.oxlintrc.json @@ -0,0 +1,8 @@ +{ + "plugins": ["./test_plugin"], + "categories": {"correctness": "off"}, + "rules": { + "context-plugin/log-context": "error" + }, + "ignorePatterns": ["test_plugin"] +} diff --git a/napi/oxlint2/test/fixtures/context_properties/files/1.js b/napi/oxlint2/test/fixtures/context_properties/files/1.js new file mode 100644 index 0000000000000..2756c24c45775 --- /dev/null +++ b/napi/oxlint2/test/fixtures/context_properties/files/1.js @@ -0,0 +1 @@ +let x; diff --git a/napi/oxlint2/test/fixtures/context_properties/files/2.js b/napi/oxlint2/test/fixtures/context_properties/files/2.js new file mode 100644 index 0000000000000..a5c1e6463879f --- /dev/null +++ b/napi/oxlint2/test/fixtures/context_properties/files/2.js @@ -0,0 +1 @@ +let y; diff --git a/napi/oxlint2/test/fixtures/context_properties/test_plugin/index.js b/napi/oxlint2/test/fixtures/context_properties/test_plugin/index.js new file mode 100644 index 0000000000000..42aaa206bc4df --- /dev/null +++ b/napi/oxlint2/test/fixtures/context_properties/test_plugin/index.js @@ -0,0 +1,32 @@ +import { dirname, sep } from 'node:path'; + +const SPAN = { start: 0, end: 0 }; + +const PARENT_DIR_PATH_LEN = dirname(import.meta.dirname).length + 1; + +const relativePath = sep === '/' + ? path => path.slice(PARENT_DIR_PATH_LEN) + : path => path.slice(PARENT_DIR_PATH_LEN).replace(/\\/g, '/'); + +export default { + meta: { + name: "context-plugin", + }, + rules: { + "log-context": { + create(context) { + context.report({ + message: `id: ${context.id}`, + node: SPAN, + }); + + context.report({ + message: `physicalFilename: ${relativePath(context.physicalFilename)}`, + node: SPAN, + }); + + return {}; + }, + }, + }, +};