2016-04-03 5 views
0

Я пытаюсь создать плагин IntelliJ (в основном для обучения). Моя цель состоит в том, что, нажимая комбинацию клавиш, плагин будет генерировать соответствующий тестовый метод тестирования модуля PHP в тестовом файле.Плагин: Как вставить новый метод в существующий класс 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, но как мне получить PsiClass от PsiFile? Также как сохранить изменения?

ответ

1

Всего несколько простых шагов.

  1. Найти PhpClass вы хотите вставить новый метод в. Как вы уже PsiFile вы можете пройти дерево вручную или использовать PhpElementVisitor.

    1.1. Чтобы трассировать дерево вручную, вы можете использовать метод PsiTreeUtil#findChildOfType. В вашем случае вам нужно сначала найти GroupStatement, а затем класс, который вам нужен.

    1.2. Invoke PsiElement#accept (PsiFile - пример PsiElement) с PhpElementVisitor с переопределенным #visitPhpGroupStatement и #visitPhpClass методов.

  2. Используйте PhpPsiElementFactory#createMethod, чтобы создать новый метод из текста. Обратите внимание, что этот класс не является частью публичного API, поэтому теоретически его можно легко изменить/переместить/удалить/в будущем.

  3. Использование PsiElement#add (PhpClass также является экземпляром PsiElement), чтобы вставить метод в класс.

Это все. Вам не нужно явно сохранять изменения.

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; 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^