package fr.adrienbrault.idea.symfony2plugin.form.action.generator;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.actions.CodeInsightAction;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementVisitor;
import com.jetbrains.php.lang.psi.PhpCodeEditUtil;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import fr.adrienbrault.idea.symfony2plugin.Symfony2InterfacesUtil;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.form.util.FormUtil;
import fr.adrienbrault.idea.symfony2plugin.util.MethodMatcher;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class FormTypeConstantMigrationAction extends CodeInsightAction {
@Override
public void update(AnActionEvent event) {
super.update(event);
boolean enabled = Symfony2ProjectComponent.isEnabled(event.getProject());
event.getPresentation().setVisible(enabled);
event.getPresentation().setEnabled(enabled);
}
@Override
protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
PhpClass classAtCaret = PhpCodeEditUtil.findClassAtCaret(editor, file);
return
classAtCaret != null &&
PhpElementsUtil.isInstanceOf(classAtCaret, "Symfony\\Component\\Form\\FormTypeInterface")
;
}
@NotNull
@Override
protected CodeInsightActionHandler getHandler() {
return new MyCodeInsightActionHandler();
}
private class MyCodeInsightActionHandler implements CodeInsightActionHandler {
@Override
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile psiFile) {
PhpClass phpClass = PhpCodeEditUtil.findClassAtCaret(editor, psiFile);
if(phpClass == null) {
HintManager.getInstance().showErrorHint(editor, "No class context found");
return;
}
final Collection<StringLiteralExpression> formTypes = new ArrayList<>();
phpClass.acceptChildren(new FormTypeStringElementVisitor(formTypes));
if(formTypes.size() == 0) {
HintManager.getInstance().showErrorHint(editor, "Nothing to do for me");
return;
}
for (StringLiteralExpression formType : formTypes) {
try {
FormUtil.replaceFormStringAliasWithClassConstant(formType);
} catch (Exception ignored) {
}
}
}
@Override
public boolean startInWriteAction() {
return true;
}
private class FormTypeStringElementVisitor extends PsiRecursiveElementVisitor {
private final Collection<StringLiteralExpression> formTypes;
public FormTypeStringElementVisitor(Collection<StringLiteralExpression> formTypes) {
this.formTypes = formTypes;
}
@Override
public void visitElement(PsiElement element) {
if (!(element instanceof StringLiteralExpression)) {
super.visitElement(element);
return;
}
String contents = ((StringLiteralExpression) element).getContents();
if (StringUtils.isBlank(contents)) {
super.visitElement(element);
return;
}
if (null == new MethodMatcher.StringParameterMatcher(element, 1)
.withSignature(Symfony2InterfacesUtil.getFormBuilderInterface())
.match()) {
super.visitElement(element);
return;
}
formTypes.add((StringLiteralExpression) element);
super.visitElement(element);
}
}
}
}