package jetbrains.mps.ide.java.platform.refactorings; /*Generated by MPS */ import jetbrains.mps.ide.platform.refactoring.RefactoringDialog; import jetbrains.mps.baseLanguage.util.plugin.refactorings.InlineMethodModel; import org.jetbrains.mps.openapi.module.SRepository; import jetbrains.mps.openapi.editor.EditorContext; import org.jetbrains.mps.openapi.model.SNode; import jetbrains.mps.project.MPSProject; import jetbrains.mps.smodel.ModelAccessHelper; import jetbrains.mps.util.Computable; import org.jetbrains.annotations.Nullable; import javax.swing.JPanel; import javax.swing.BoxLayout; import javax.swing.border.EmptyBorder; import javax.swing.ButtonGroup; import javax.swing.JRadioButton; import java.awt.Component; import jetbrains.mps.baseLanguage.closures.runtime.Wrappers; import javax.swing.JOptionPane; import javax.swing.AbstractAction; import java.awt.event.ActionEvent; import javax.swing.JComponent; import java.awt.BorderLayout; import org.jetbrains.annotations.NotNull; import javax.swing.Action; import jetbrains.mps.ide.findusages.model.SearchResults; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.ProgressIndicator; import jetbrains.mps.baseLanguage.util.plugin.refactorings.MethodRefactoringUtils; import jetbrains.mps.ide.project.ProjectHelper; import jetbrains.mps.progress.ProgressMonitorAdapter; import javax.swing.JLabel; import jetbrains.mps.editor.runtime.commands.EditorCommand; import jetbrains.mps.ide.findusages.model.SearchResult; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.baseLanguage.util.plugin.refactorings.InlineMethodRefactoring; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.ide.platform.refactoring.RefactoringViewAction; import jetbrains.mps.ide.platform.refactoring.RefactoringViewItem; import jetbrains.mps.ide.platform.refactoring.RefactoringAccessEx; public class InlineMethodDialog extends RefactoringDialog { private InlineMethodModel myModel; private InlineMethodDialog.PreviewAction myPreviewAction; private boolean myForAll; private final SRepository myEditorRepo; private final EditorContext myEditorContext; public InlineMethodDialog(final SNode node, MPSProject project, EditorContext editorContext) { super(project.getProject(), true); myEditorContext = editorContext; myEditorRepo = myEditorContext.getRepository(); setTitle("Inline Method"); setResizable(false); myModel = new ModelAccessHelper(myEditorRepo).runReadAction(new Computable<InlineMethodModel>() { public InlineMethodModel compute() { return new InlineMethodModel(node); } }); init(); } @Nullable @Override protected String getHelpId() { return "refactoring.inlineMethod"; } private JPanel createCheckBoxes() { JPanel checkboxesPanel = new JPanel(); checkboxesPanel.setLayout(new BoxLayout(checkboxesPanel, BoxLayout.Y_AXIS)); checkboxesPanel.setBorder(new EmptyBorder(10, 0, 0, 0)); ButtonGroup group = new ButtonGroup(); JRadioButton button1 = this.createButton(group, checkboxesPanel, false, "Inline this invocation only and keep the method"); JRadioButton button2 = this.createButton(group, checkboxesPanel, true, "Inline all invocations and remove the method"); if (myModel.isRecusive()) { button2.setEnabled(false); } if (myModel.getMethodCall() != null) { button1.setSelected(true); myForAll = false; } else { button1.setEnabled(false); button2.setSelected(true); myForAll = true; } myPreviewAction.setEnabled(myForAll); return checkboxesPanel; } public void tryToShow(Component parentComponent) { final Wrappers._T<String> errors = new Wrappers._T<String>(); myEditorRepo.getModelAccess().runReadAction(new Runnable() { public void run() { errors.value = myModel.getErrors(); } }); if (errors.value == null) { show(); } else { JOptionPane.showMessageDialog(parentComponent, errors.value, "Can't perform refactoring", JOptionPane.ERROR_MESSAGE); } } private JRadioButton createButton(ButtonGroup group, JPanel checkboxesPanel, final boolean forAll, String text) { JRadioButton button1 = new JRadioButton(new AbstractAction(text) { @Override public void actionPerformed(ActionEvent e) { myForAll = forAll; myPreviewAction.setEnabled(forAll); } }); group.add(button1); checkboxesPanel.add(button1); return button1; } @Nullable @Override protected JComponent createCenterPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.add(createCheckBoxes(), BorderLayout.CENTER); return panel; } @Override protected void createDefaultActions() { super.createDefaultActions(); myPreviewAction = new InlineMethodDialog.PreviewAction(); } @Override @NotNull protected Action[] createActions() { return new Action[]{getRefactorAction(), myPreviewAction, getCancelAction()}; } /** * This method will be called on pressing "Refactor" button in dialog. * */ @Override protected void doRefactoringAction() { SearchResults<SNode> usages = findUssages(); if (canExecuteRefactoring(usages)) { performRefactoring(usages); } super.doRefactoringAction(); } private boolean canExecuteRefactoring(SearchResults<SNode> usages) { String problems = getProblems(usages); if (problems.length() == 0) { return true; } ProblemsDialog dialog = new ProblemsDialog(myProject, problems); dialog.show(); return dialog.getExitCode() == DialogWrapper.NEXT_USER_EXIT_CODE; } private SearchResults<SNode> findUssages() { if (!(myForAll)) { return null; } final Wrappers._T<SearchResults<SNode>> usages = new Wrappers._T<SearchResults<SNode>>(); ProgressManager.getInstance().run(new Task.Modal(getProject(), "Searching for ussages", true) { @Override public void run(@NotNull final ProgressIndicator indicator) { myEditorRepo.getModelAccess().runReadAction(new Runnable() { public void run() { usages.value = MethodRefactoringUtils.findMethodUsages(ProjectHelper.fromIdeaProject(getProject()).new ProjectScope(), myModel.getMethod(), new ProgressMonitorAdapter(indicator)); } }); } }); return usages.value; } private String getProblems(final SearchResults<SNode> usages) { final StringBuilder sb = new StringBuilder(); ProgressManager.getInstance().run(new Task.Modal(getProject(), "Search for overriding methods", true) { public void run(@NotNull final ProgressIndicator pi) { myEditorRepo.getModelAccess().runReadAction(new Runnable() { public void run() { InlineMethodRefactoringAnalyzer analyzer; if (myModel.getMethodCall() == null) { analyzer = new InlineMethodRefactoringAnalyzer(null, myModel.getMethod()); } else { analyzer = new InlineMethodRefactoringAnalyzer(myModel.getMethodCall().getNode(), myModel.getMethod()); } analyzer.appendProblems(ProjectHelper.fromIdeaProject(getProject()).new ProjectScope(), usages, sb, new ProgressMonitorAdapter(pi)); } }); } }); return sb.toString(); } @Nullable @Override protected JComponent createNorthPanel() { JLabel label = new JLabel(); label.setText(myModel.getMethodPresentation()); return label; } private void performRefactoring(final SearchResults<SNode> usages) { myEditorRepo.getModelAccess().executeCommand(new EditorCommand(myEditorContext) { protected void doExecute() { if (usages != null) { for (SearchResult<SNode> res : ListSequence.fromList(usages.getSearchResults())) { InlineMethodRefactoring ref = new InlineMethodRefactoring(res.getObject()); ref.doRefactor(); } SNodeOperations.deleteNode(myModel.getMethod()); } else { InlineMethodRefactoring ref = new InlineMethodRefactoring(myModel.getMethodCall().getNode()); ref.doRefactor(); } } }); } public class PreviewAction extends DialogWrapper.DialogWrapperAction { public PreviewAction() { super("Preview"); } @Override protected void doAction(ActionEvent event) { final SearchResults<SNode> usages = findUssages(); if (canExecuteRefactoring(usages)) { RefactoringViewAction refactoringViewAction = new RefactoringViewAction() { @Override public void performAction(RefactoringViewItem item) { item.close(); performRefactoring(usages); } }; RefactoringAccessEx.getInstance().showRefactoringView(getProject(), refactoringViewAction, usages, false, "refactoring"); } close(DialogWrapper.OK_EXIT_CODE); } } }