package fr.adrienbrault.idea.symfony2plugin.codeInspection.quickfix;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.jetbrains.php.lang.PhpCodeUtil;
import com.jetbrains.php.lang.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import fr.adrienbrault.idea.symfony2plugin.util.CodeUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class CreateMethodQuickFix implements LocalQuickFix {
@NotNull
private SmartPsiElementPointer<PhpClass> smartPhpClass;
@NotNull
private final String functionName;
@NotNull
private final InsertStringInterface stringInterface;
public CreateMethodQuickFix(@NotNull PhpClass phpClass, @NotNull String functionName, @NotNull InsertStringInterface stringInterface) {
this.smartPhpClass = SmartPointerManager.getInstance(phpClass.getProject()).createSmartPsiElementPointer(phpClass);
this.functionName = functionName;
this.stringInterface = stringInterface;
}
@NotNull
@Override
public String getName() {
return "Create Method";
}
@NotNull
@Override
public String getFamilyName() {
return "Routing";
}
@Override
public void applyFix(final @NotNull Project project, @NotNull ProblemDescriptor problemDescriptor) {
PhpClass phpClass = smartPhpClass.getElement();
if(phpClass == null) {
return;
}
final Method methodCreated = PhpCodeUtil.createMethodFromTemplate(
phpClass, project, this.stringInterface.getStringBuilder(problemDescriptor, phpClass, functionName).toString()
);
if(methodCreated == null) {
return;
}
final Editor editor = FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, phpClass.getContainingFile().getVirtualFile()), true);
if(editor == null) {
return;
}
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
final int insertPos = CodeUtil.getMethodInsertPosition(phpClass, functionName);
if(insertPos == -1) {
return;
}
new WriteCommandAction(project) {
@Override
protected void run(@NotNull Result result) throws Throwable {
StringBuffer textBuf = new StringBuffer();
textBuf.append("\n");
textBuf.append(methodCreated.getText());
editor.getDocument().insertString(insertPos, textBuf);
final int endPos = insertPos + textBuf.length();
CodeStyleManager.getInstance(project).reformatText(phpClass.getContainingFile(), insertPos, endPos);
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
Method insertedMethod = phpClass.findMethodByName(functionName);
if(insertedMethod != null) {
editor.getCaretModel().moveToOffset(insertedMethod.getTextRange().getStartOffset());
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
}
@Override
public String getGroupID() {
return "Create Method";
}
}.execute();
}
public interface InsertStringInterface {
@NotNull
StringBuilder getStringBuilder(@NotNull ProblemDescriptor problemDescriptor, @NotNull PhpClass phpClass, @NotNull String functionName);
}
}