package jetbrains.mps.ide.actions.nodes; /*Generated by MPS */ import java.util.Collection; import javax.swing.Action; import jetbrains.mps.project.Project; import org.jetbrains.mps.openapi.model.SNode; import java.util.List; import java.util.Collections; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import jetbrains.mps.ide.icons.IconManager; import jetbrains.mps.smodel.Language; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModuleOperations; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.module.SModule; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations; import jetbrains.mps.smodel.behaviour.BHReflection; import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId; import javax.swing.AbstractAction; import org.jetbrains.mps.openapi.model.SNodeReference; import javax.swing.Icon; import java.awt.event.ActionEvent; import jetbrains.mps.openapi.navigation.EditorNavigator; public final class GoToRulesHelper { private GoToRulesHelper() { } public static Collection<Action> getRuleNavigateActions(Project mpsProject, SNode concept) { List<SNode> rules = getRules(concept, false); if (rules.size() == 1) { SNode nodeToSelect = rules.get(0); if ((nodeToSelect != null)) { return Collections.<Action>singleton(new GoToRulesHelper.NavigateAction(mpsProject, SNodeOperations.getPointer(nodeToSelect), "", null)); } return Collections.emptyList(); } if (ListSequence.fromList(rules).isEmpty()) { return Collections.emptyList(); } ArrayList<Action> rv = new ArrayList<Action>(); for (final SNode node : rules) { if (node == null) { continue; } String nodeName = node.getName(); nodeName = String.format("%s (%s)", (nodeName == null || nodeName.equals("") ? node.getConcept().getName() : nodeName)); rv.add(new GoToRulesHelper.NavigateAction(mpsProject, node.getReference(), nodeName, IconManager.getIconFor(node))); } return rv; } public static List<SNode> getRules(final SNode concept, final boolean exactConcept) { Language language = getDeclaringLanguage(concept); if (language == null) { return Collections.emptyList(); } SModel typesystem = SModuleOperations.getAspect(language, "typesystem"); if (typesystem == null) { return Collections.emptyList(); } // todo: populate rules from other typesystem models! List<SNode> rules = ListSequence.fromList(SModelOperations.roots(typesystem, MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e7b5c73L, "jetbrains.mps.lang.typesystem.structure.AbstractRule"))).where(new IWhereFilter<SNode>() { public boolean accept(SNode node) { return isApplicable(node, concept, exactConcept); } }).toListSequence(); return rules; } private static Language getDeclaringLanguage(@NotNull SNode concept) { SModel model = concept.getModel(); assert model != null : "This editor has had to be closed as the concept node was already removed"; SModule module = model.getModule(); if (module instanceof Language) { return (Language) module; } return null; } private static boolean isApplicable(SNode rule, SNode concept, boolean exactConcept) { if ((rule == null) || (concept == null)) { return false; } SNode applicableConcept = getApplicableConcept(SLinkOperations.getTarget(rule, MetaAdapterFactory.getContainmentLink(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e7b5c73L, 0x1117e7b9c40L, "applicableNode"))); if (applicableConcept == null) { return false; } if (exactConcept) { return concept == applicableConcept; } return ((boolean) (Boolean) BHReflection.invoke(concept, SMethodTrimmedId.create("isSubconceptOf", MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0x1103553c5ffL, "jetbrains.mps.lang.structure.structure.AbstractConceptDeclaration"), "73yVtVlWOga"), applicableConcept)); } private static SNode getApplicableConcept(SNode applicableNode) { if (SNodeOperations.isInstanceOf(applicableNode, MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e2a88b3L, "jetbrains.mps.lang.typesystem.structure.ConceptReference"))) { return SLinkOperations.getTarget(SNodeOperations.cast(applicableNode, MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e2a88b3L, "jetbrains.mps.lang.typesystem.structure.ConceptReference")), MetaAdapterFactory.getReferenceLink(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e2a88b3L, 0x1117e2ab6c9L, "concept")); } else if (SNodeOperations.isInstanceOf(applicableNode, MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e2c3e68L, "jetbrains.mps.lang.typesystem.structure.PatternCondition"))) { return ((SNode) BHReflection.invoke(SNodeOperations.cast(applicableNode, MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x1117e2c3e68L, "jetbrains.mps.lang.typesystem.structure.PatternCondition")), SMethodTrimmedId.create("getApplicableConcept", null, "hEwIszL"))); } else { return null; } } private static class NavigateAction extends AbstractAction { private SNodeReference myNode; private Project myProject; /*package*/ NavigateAction(Project mpsProject, SNodeReference nodeRef, String name, Icon icon) { super(name, icon); myNode = nodeRef; myProject = mpsProject; } public void actionPerformed(ActionEvent event) { new EditorNavigator(myProject).shallFocus(true).selectIfChild().open(myNode); } } }