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);
}
}
}