0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-08 07:16:56 -05:00
denoland-deno/cli/tools/lint/lint.js

92 lines
2 KiB
JavaScript
Raw Normal View History

2024-12-02 02:27:30 +01:00
import { op_lint_get_rule, op_lint_report } from "ext:core/ops";
2024-12-01 04:53:47 +01:00
export class Context {
id;
fileName;
constructor(id, fileName) {
this.id = id;
this.fileName = fileName;
}
2024-12-02 02:27:30 +01:00
report(data) {
2024-12-03 03:11:26 +01:00
// TODO(bartlomieju): if there's `node` then convert position automatically
// otherwise lookup `location`
let start, end;
if (data.node) {
start = data.node.span.start - 1;
end = data.node.span.end - 1;
} else if (data.span) {
start = data.span.start - 1;
end = data.span.end - 1;
} else {
throw new Error(
"Either `node` or `span` must be provided when reporting an error",
);
}
2024-12-02 18:29:30 +01:00
op_lint_report(
this.id,
this.fileName,
data.message,
2024-12-03 03:11:26 +01:00
start,
end,
2024-12-02 18:29:30 +01:00
);
2024-12-01 04:53:47 +01:00
}
}
2024-12-02 19:20:12 +01:00
export function runPluginRule(fileName, pluginName, ruleName, serializedAst) {
2024-12-01 04:53:47 +01:00
const id = `${pluginName}/${ruleName}`;
const ctx = new Context(id, fileName);
const rule = op_lint_get_rule(pluginName, ruleName);
2024-12-01 14:26:15 +01:00
const visitor = rule(ctx);
2024-12-03 02:51:29 +01:00
const ast = JSON.parse(serializedAst, (key, value) => {
if (key === "ctxt") {
return undefined;
}
return value;
});
2024-12-03 03:38:43 +01:00
// console.log("ast", ast);
2024-12-03 02:51:29 +01:00
traverse(ast, visitor);
2024-12-01 05:14:46 +01:00
}
2024-12-03 02:51:29 +01:00
function traverse(ast, visitor, parent = null) {
if (!ast || typeof ast !== "object") {
return;
2024-12-01 05:14:46 +01:00
}
2024-12-03 02:51:29 +01:00
// Get node type, accounting for SWC's type property naming
const nodeType = ast.type || (ast.nodeType ? ast.nodeType : null);
// Skip if not a valid AST node
if (!nodeType) {
return;
2024-12-01 05:14:46 +01:00
}
2024-12-03 02:51:29 +01:00
ast.parent = parent;
// Call visitor if it exists for this node type
if (visitor[nodeType] && typeof visitor[nodeType] === "function") {
2024-12-03 03:11:26 +01:00
visitor[nodeType](ast);
2024-12-01 05:14:46 +01:00
}
2024-12-03 02:51:29 +01:00
// Traverse child nodes
for (const key in ast) {
2024-12-03 03:11:26 +01:00
if (key === "parent" || key === "type") {
2024-12-03 02:51:29 +01:00
continue;
2024-12-01 05:14:46 +01:00
}
2024-12-03 02:51:29 +01:00
const child = ast[key];
if (Array.isArray(child)) {
child.forEach((item) => traverse(item, visitor, ast));
} else if (child && typeof child === "object") {
traverse(child, visitor, ast);
2024-12-01 05:14:46 +01:00
}
}
2024-12-01 04:53:47 +01:00
}