Files
oxc-project__oxc/apps/oxlint/test/fixtures/selector/plugin.ts
overlookmotel 9de9385fd1 refactor(linter/plugins): rename oxlint/plugin to oxlint/plugins (#18792)
Part of #18610.

Our intent is to move `definePlugin`, `defineRule`, and `eslintCompatPlugin` to a separate package `@oxlint/plugins` (plural to avoid confusion with naming convention for plugins `oxlint-plugin-xxx`).

So rename the current entry point which exports these functions from `oxlint/plugin` to `oxlint/plugins` (plural).
2026-02-01 13:23:14 +00:00

93 lines
2.8 KiB
TypeScript

import type { ESTree, Plugin, Visitor } from "#oxlint/plugins";
const plugin: Plugin = {
meta: {
name: "selectors",
},
rules: {
check: {
create(context) {
const keys = [
// Wildcard
"*",
// Node type
"Identifier",
// Attributes
"Identifier[name=a]",
"Identifier[name=d]",
// :matches
":matches(Identifier, FunctionDeclaration)",
":matches(Identifier[name=a], FunctionDeclaration[id.name=foo])",
// :not
":not(Identifier)",
// class
":statement",
":Declaration",
":paTTern",
":expression",
":FUNCTION",
":function > Identifier",
// Child
"Property > Identifier",
"ObjectExpression > Identifier", // does not match
"ObjectExpression > Property > Identifier",
"ObjectExpression > Property > Identifier[name=a]",
"ObjectExpression > Property > Identifier[name=b]", // does not match
"ArrayExpression > Identifier",
"ArrayExpression > Identifier[name=c]",
"Program > VariableDeclaration > VariableDeclarator > ObjectExpression > Property > ArrayExpression > Identifier",
"Program > FunctionDeclaration",
// Descendent
"ObjectExpression Identifier",
"ObjectExpression ArrayExpression",
"ArrayExpression Identifier",
"ArrayExpression Identifier[name=b]",
// Sibling
"Identifier ~ Identifier",
"Property ~ [type]",
"VariableDeclaration ~ FunctionDeclaration",
"VariableDeclaration + FunctionDeclaration",
// Combination
":matches(ObjectExpression > SpreadElement, FunctionDeclaration)",
":matches(ObjectExpression > SpreadElement, FunctionDeclaration[id.name=bar])",
// Wildcard
"*:exit",
];
const visitor: Visitor = {};
const visits: { key: string; node: ESTree.Node }[] = [];
for (const key of keys) {
visitor[key] = (node) => {
visits.push({ key, node });
};
}
visitor["Program:exit"] = (program) => {
const visitLog = visits
.map(({ key, node }) => {
const { type } = node;
let nodeDescription = type;
if (type === "Identifier") {
nodeDescription += `(${node.name})`;
} else if (type === "FunctionDeclaration") {
nodeDescription += `(${node.id?.name})`;
}
return `${key}: ${nodeDescription}`;
})
.join("\n");
context.report({
message: `\n${visitLog}`,
node: program,
});
};
return visitor;
},
},
},
};
export default plugin;