我正在尝试创建一个IntelliJ插件(主要用于学习目的)。我的目标是通过按键盘快捷键,插件将在测试文件中生成相应的PHP单元测试方法存根。
因此,假设Db.php
已打开,按下Ctrl+Shift+U
插件将在DbTest.php
中创建单元测试存根。
到目前为止,我已经找到了如何在光标处获取方法名称以及如何将相应的单元测试文件(即Db
=> DbTest
)定位为PsiFile
。
PsiFile[] search = FilenameIndex.getFilesByName(project, testFileName, scope); //scope is the test directory
PsiFile testFile = search[0];
我无法弄清楚如何在testFile
中插入生成的新方法存根,然后保存更改?
P.S。我看到存在createMethodFromText
函数,但如何从PsiFile获取PsiClass?另外如何保存更改?
答案 0 :(得分:1)
只需几个简单的步骤。
查找要插入新方法的PhpClass
。如您已经PsiFile
,您可以手动遍历树或使用PhpElementVisitor
。
1.1。要手动遍历树,您可以使用PsiTreeUtil#findChildOfType
方法。在您的情况下,您需要首先找到GroupStatement
,然后找到您需要的课程。
1.2。通过PsiElement#accept
方式调用PsiFile
方法(PsiElement
是PhpElementVisitor
的一个实例),其中包含已覆盖的#visitPhpGroupStatement
和#visitPhpClass
方法。
使用PhpPsiElementFactory#createMethod
从文本创建新方法。请注意,此类不是公共API的一部分,因此从理论上讲,它可以在将来轻松更改/移动/删除/无论如何。
使用PsiElement#add
(PhpClass
也是PsiElement
的实例)将方法插入到课程中。
这就是全部。您无需明确保存更改。
答案 1 :(得分:0)
这最终对我有用。谢谢大家的帮助
for (int i = 0; i < found.getTextLength(); i++) {
PsiElement ele = found.findElementAt(i);
PhpClass phpClass = PsiTreeUtil.getParentOfType(ele, PhpClass.class);
if (phpClass != null) {
Method methodExists = findMethod(phpClass, methodName);
if (methodExists == null) {
new WriteCommandAction.Simple(phpClass.getProject(), phpClass.getContainingFile()) {
@Override
protected void run() throws Throwable {
PsiElement brace = phpClass.getLastChild();
if (brace != null) {
Method method = PhpPsiElementFactory.createMethod(phpClass.getProject(), "public function " + methodName + "() {\n\n}");
CodeStyleManager styleManager = CodeStyleManager.getInstance(getProject());
styleManager.reformat(method);
PsiElement newMethod = phpClass.addBefore(method, brace);
PsiNavigateUtil.navigate(newMethod);
}
}
}.execute();
} else {
PsiNavigateUtil.navigate(methodExists);
}
break;
}
}