package jetbrains.mps.ide.hierarchy; /*Generated by MPS */ import java.util.Map; import org.jetbrains.mps.openapi.model.SNode; import java.util.Set; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.HashMap; import org.jetbrains.mps.openapi.module.SRepository; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.HashSet; import java.util.List; import jetbrains.mps.smodel.behaviour.BHReflection; import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations; import java.util.Collections; import jetbrains.mps.ide.ui.tree.MPSTreeNode; import jetbrains.mps.smodel.Language; import jetbrains.mps.smodel.ModuleRepositoryFacade; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.internal.collections.runtime.ISelector; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModuleOperations; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.internal.collections.runtime.ITranslator2; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations; import jetbrains.mps.internal.collections.runtime.IVisitor; import jetbrains.mps.internal.collections.runtime.ListSequence; /** * This works on concept nodes */ public class ConceptHierarchyTree extends AbstractHierarchyTree { private Map<SNode, Set<SNode>> myDescendantsCache = MapSequence.fromMap(new HashMap<SNode, Set<SNode>>()); public ConceptHierarchyTree(SRepository repo, boolean isParentHierarchy) { super(repo); setParentHierarchy(isParentHierarchy); } @Override protected Set<SNode> getParents(SNode node, Set<SNode> visited) throws CircularHierarchyException { if (visited.contains(node)) { throw new CircularHierarchyException(node, "circular concept hierarchy"); } return SetSequence.fromSetWithValues(new HashSet<SNode>(), ((List<SNode>) BHReflection.invoke(node, SMethodTrimmedId.create("getImmediateSuperconcepts", null, "hMuxyK2")))); } @Override protected SNode getParent(SNode node) { if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0xf979ba0450L, "jetbrains.mps.lang.structure.structure.ConceptDeclaration"))) { SNode concept = SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0xf979ba0450L, "jetbrains.mps.lang.structure.structure.ConceptDeclaration")); SNode extendsConcept = SLinkOperations.getTarget(concept, MetaAdapterFactory.getReferenceLink(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0xf979ba0450L, 0xf979be93cfL, "extends")); if (extendsConcept == null && concept != SNodeOperations.getNode("r:00000000-0000-4000-0000-011c89590288(jetbrains.mps.lang.core.structure)", "1133920641626")) { extendsConcept = SNodeOperations.getNode("r:00000000-0000-4000-0000-011c89590288(jetbrains.mps.lang.core.structure)", "1133920641626"); } return extendsConcept; } else { return null; } } @Override protected Set<SNode> getDescendants(SNode conceptNode, Set<SNode> visited) throws CircularHierarchyException { if (visited.contains(conceptNode)) { throw new CircularHierarchyException(conceptNode, "circular concept hierarchy"); } Set<SNode> result = MapSequence.fromMap(myDescendantsCache).get(conceptNode); return (result == null ? Collections.<SNode>emptySet() : result); } @Override protected String noNodeString() { return "(no concept)"; } @Override protected MPSTreeNode rebuildParentHierarchy() { buildCaches(); return super.rebuildParentHierarchy(); } private void buildCaches() { MapSequence.fromMap(myDescendantsCache).clear(); Iterable<Language> languages = ModuleRepositoryFacade.getInstance().getAllModules(Language.class); Iterable<SModel> structures = Sequence.fromIterable(languages).select(new ISelector<Language, SModel>() { public SModel select(Language it) { return SModuleOperations.getAspect(it, "structure"); } }).where(new IWhereFilter<SModel>() { public boolean accept(SModel it) { return it != null; } }); Iterable<SNode> concepts = Sequence.fromIterable(structures).translate(new ITranslator2<SModel, SNode>() { public Iterable<SNode> translate(SModel it) { return SModelOperations.roots(it, MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0x1103553c5ffL, "jetbrains.mps.lang.structure.structure.AbstractConceptDeclaration")); } }); Sequence.fromIterable(concepts).visitAll(new IVisitor<SNode>() { public void visit(final SNode child) { List<SNode> immediate = ((List<SNode>) BHReflection.invoke(child, SMethodTrimmedId.create("getImmediateSuperconcepts", null, "hMuxyK2"))); ListSequence.fromList(immediate).visitAll(new IVisitor<SNode>() { public void visit(SNode parent) { Set<SNode> desc = MapSequence.fromMap(myDescendantsCache).get(parent); if (desc == null) { desc = SetSequence.fromSet(new HashSet<SNode>()); MapSequence.fromMap(myDescendantsCache).put(parent, desc); } SetSequence.fromSet(desc).addElement(child); } }); } }); } }