我有一个用例,我想替换变量函数调用,特别是 foo.value.toString()
来使用辅助函数 getStringValue(foo)
。如果我找到它,我可以使用修复程序替换 CallExpression
节点上的文本,因此我的规则修复程序当前如下所示:
fixer => fixer.replaceText(node, `getStringValue(${identifierNode.getText()})`);
以这种方式自动修复此错误的问题是 getStringValue
可能已导入到文件中,也可能尚未导入到文件中。我希望这个修复程序具有以下行为:
据我从文档中了解到,没有简单的方法可以使用 fixer
或 context
对象访问根 ESTree 节点。最接近的是 SourceCode.getText()
,这意味着我必须解析源文本才能解析导入 - 我宁愿直接与整个 AST 交互。执行此自动导入过程的最佳方法是什么?
P粉5961619152024-03-29 00:56:42
如果您想在这里稍微不安全,您可以假设用户没有在其文件中本地重新定义 getStringValue
函数(如果您拥有此规则所适用的代码库,通常是一个安全的假设)。
在这种情况下,最好的方法是使用选择器来检查导入,例如:
module.exports = { create(context) { let hasImport = false; let lastImport = null; return { ImportDeclaration(node) { lastImport = node; if (isImportICareAbout(node)) { hasImport = true; } }, "My Selector For Other Linting Logic"(node) { // ... context.report({ messageId: "myReport", fix(fixer) { const fixes = [ fixer.replaceText(node, `getStringValue(${identifierNode.name})`), ]; if (!hasImport) { const newImport = 'import { getStringValue } from "module";'; if (lastImport) { // insert after the last import decl fixes.push(fixer.insertTextBefore(lastImport, newImport)); } else { // insert at the start of the file fixes.push(fixer.insertTextAfterRange([0, 0], newImport)); } } return fixes; }, }); }, }; }, };
P粉0989790482024-03-29 00:43:02
事实证明,有一种简单的方法可以从 context
对象中提取 AST 根节点。它位于 context.getSourceCode().ast
。我用以下逻辑重写了我的修复程序:
fixer => { fixer.replaceText(node, `getStringValue(${identifierNode.getText()})`); const body = context.getSourceCode().ast; const importDeclarations = body.filter(statement => statement.type === AST_NODE_TYPES.ImportDeclaration); ... // Check if the declaration has the import and add the appropriate imports if necessary }