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