2016-04-03 11 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. createMethodFromText機能がありますが、PsiClassからPsiClassを取得するにはどうすればよいですか?また、どのように変更を保存するのですか?

答えて

1

簡単な手順がいくつかあります。

  1. は、あなたが新しいメソッドを挿入したいPhpClassを検索します。あなたはすでにあなたが手動でツリーをトラバースまたはPhpElementVisitorを使用することができますいずれかPsiFileを持っていたよう。

    1.1。ツリーを手動でトラバースするには、PsiTreeUtil#findChildOfTypeメソッドを使用できます。あなたの場合は、最初にGroupStatementを見つけてから、必要なクラスを見つける必要があります。

    1.2。 PsiElement#acceptメソッド(PsiFilePsiElementのインスタンス)を呼び出すには、PhpElementVisitorで、#visitPhpGroupStatementおよび#visitPhpClassのメソッドをオーバーライドして呼び出します。

  2. PhpPsiElementFactory#createMethodを使用して、テキストから新しいメソッドを作成します。このクラスはパブリックAPIの一部ではないため、理論的には簡単に変更/移動/削除/将来の変更が可能です。

  3. PsiElement#addPhpClassPsiElementのインスタンスです)を使用して、クラスにメソッドを挿入します。

それだけです。変更を明示的に保存する必要はありません。

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; 
    } 
} 
関連する問題