package jetbrains.mps.ide.actions; /*Generated by MPS */ import java.util.List; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.module.SRepository; import jetbrains.mps.project.Project; import org.jetbrains.annotations.NotNull; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import jetbrains.mps.internal.collections.runtime.ITranslator2; import jetbrains.mps.plugins.relations.RelationDescriptor; import jetbrains.mps.plugins.projectplugins.ProjectPluginManager; import jetbrains.mps.ide.project.ProjectHelper; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes; import jetbrains.mps.ide.projectPane.ProjectPane; import java.util.Iterator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.ProgressIndicator; import java.util.Set; import jetbrains.mps.ide.findusages.model.SearchResult; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.HashSet; import jetbrains.mps.internal.collections.runtime.IVisitor; import jetbrains.mps.ide.findusages.model.SearchResults; import jetbrains.mps.ide.findusages.view.FindUtils; import jetbrains.mps.progress.EmptyProgressMonitor; import jetbrains.mps.ide.findusages.model.scopes.GlobalScope; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.internal.collections.runtime.ISelector; import com.intellij.openapi.application.ApplicationManager; import jetbrains.mps.ide.platform.refactoring.RefactoringAccessEx; import jetbrains.mps.ide.platform.refactoring.RefactoringViewAction; import jetbrains.mps.ide.platform.refactoring.RefactoringViewItem; public class DeleteNodesHelper { private List<SNode> myNodesToDelete; private SRepository myRepository; private Project myProject; public DeleteNodesHelper(List<SNode> nodes, @NotNull Project project) { myProject = project; myRepository = myProject.getRepository(); myNodesToDelete = ListSequence.fromListWithValues(new ArrayList<SNode>(), nodes); } public boolean hasOptions() { return ListSequence.fromList(myNodesToDelete).translate(new ITranslator2<SNode, RelationDescriptor>() { public Iterable<RelationDescriptor> translate(final SNode node) { List<RelationDescriptor> tabs = ProjectPluginManager.getApplicableTabs(ProjectHelper.toIdeaProject(myProject), node); return ListSequence.fromList(tabs).where(new IWhereFilter<RelationDescriptor>() { public boolean accept(RelationDescriptor it) { return it.isApplicable(node) && !(it.getNodes(node).isEmpty()); } }); } }).isNotEmpty(); } public void deleteNodes(final boolean safe, final boolean aspects, final boolean fromProjectPane) { assert !(myRepository.getModelAccess().canRead()) : "can lead to deadlock"; final com.intellij.openapi.project.Project ideaProject = ProjectHelper.toIdeaProject(myProject); final _FunctionTypes._void_P0_E0 performer = new _FunctionTypes._void_P0_E0() { public void invoke() { ProjectPane projectPane = ProjectPane.getInstance(ideaProject); for (Iterator<SNode> iterator = myNodesToDelete.iterator(); iterator.hasNext();) { SNode sNode = iterator.next(); if (!(iterator.hasNext()) && fromProjectPane) { projectPane.rebuildTree(); projectPane.selectNextNode(sNode); } if (sNode.getModel() == null) { continue; } sNode.delete(); } } }; myRepository.getModelAccess().runReadAction(new Runnable() { public void run() { if (aspects) { List<SNode> addNodes = ListSequence.fromList(myNodesToDelete).translate(new ITranslator2<SNode, SNode>() { public Iterable<SNode> translate(final SNode node) { List<RelationDescriptor> tabs = ProjectPluginManager.getApplicableTabs(ideaProject, node); return ListSequence.fromList(tabs).where(new IWhereFilter<RelationDescriptor>() { public boolean accept(RelationDescriptor it) { return it.isApplicable(node); } }).translate(new ITranslator2<RelationDescriptor, SNode>() { public Iterable<SNode> translate(final RelationDescriptor tab) { List<SNode> nodes = tab.getNodes(node); return ListSequence.fromList(nodes).where(new IWhereFilter<SNode>() { public boolean accept(SNode it) { return tab.getBaseNode(it) == node; } }); } }); } }).toListSequence(); ListSequence.fromList(myNodesToDelete).addSequence(ListSequence.fromList(addNodes)); } } }); if (!(safe)) { myRepository.getModelAccess().executeCommand(new Runnable() { public void run() { performer.invoke(); } }); return; } ProgressManager.getInstance().run(new Task.Modal(ideaProject, "Finding Usages", true) { @Override public void run(@NotNull final ProgressIndicator pi) { final Set<SearchResult<SNode>> results = SetSequence.fromSet(new HashSet<SearchResult<SNode>>()); myRepository.getModelAccess().runReadAction(new Runnable() { public void run() { ListSequence.fromList(myNodesToDelete).visitAll(new IVisitor<SNode>() { public void visit(SNode it) { SearchResults<SNode> usages = FindUtils.getSearchResults(new EmptyProgressMonitor(), it, new GlobalScope(), "jetbrains.mps.lang.structure.findUsages.NodeAndDescendantsUsages_Finder"); SetSequence.fromSet(results).addSequence(ListSequence.fromList(usages.getSearchResults())); if (pi.isCanceled()) { return; } if (SNodeOperations.isInstanceOf(it, MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0x1103553c5ffL, "jetbrains.mps.lang.structure.structure.AbstractConceptDeclaration"))) { SearchResults<SNode> instances = FindUtils.getSearchResults(new EmptyProgressMonitor(), it, new GlobalScope(), "jetbrains.mps.lang.structure.findUsages.ConceptInstances_Finder"); SetSequence.fromSet(results).addSequence(ListSequence.fromList(instances.getSearchResults())); } if (pi.isCanceled()) { return; } } }); if (pi.isCanceled()) { return; } Set<SNode> nodes = SetSequence.fromSetWithValues(new HashSet<SNode>(), SetSequence.fromSet(results).select(new ISelector<SearchResult<SNode>, SNode>() { public SNode select(SearchResult<SNode> it) { return it.getObject(); } })); for (SearchResult<SNode> searchResult : ListSequence.fromListWithValues(new ArrayList<SearchResult<SNode>>(), results)) { SNode resultNode = searchResult.getObject(); for (SNode anc : ListSequence.fromList(SNodeOperations.getNodeAncestors(resultNode, null, false))) { if (SetSequence.fromSet(nodes).contains(anc)) { SetSequence.fromSet(results).removeElement(searchResult); break; } } } } }); if (pi.isCanceled()) { return; } final SearchResults sr = new SearchResults<SNode>(SetSequence.fromSetWithValues(new HashSet<SNode>(), myNodesToDelete), SetSequence.fromSet(results).toListSequence()); ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { RefactoringAccessEx.getInstance().showRefactoringView(ideaProject, new RefactoringViewAction() { @Override public void performAction(RefactoringViewItem refactoringViewItem) { myRepository.getModelAccess().executeCommand(new Runnable() { public void run() { performer.invoke(); } }); refactoringViewItem.close(); } }, sr, false, "Safe Delete"); } }); } }); } }