package jetbrains.mps.smodel.search; /*Generated by MPS */ import jetbrains.mps.cache.AbstractCache; import jetbrains.mps.cache.DataSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SNode; import java.util.Set; import java.util.LinkedHashSet; import jetbrains.mps.smodel.SNodeUtil; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import java.util.HashSet; import jetbrains.mps.smodel.event.SModelChildEvent; import jetbrains.mps.smodel.event.SModelPropertyEvent; import java.util.Map; import java.util.List; import java.util.Collections; import java.util.ArrayList; import java.util.HashMap; import java.util.Arrays; import jetbrains.mps.util.FlattenIterable; import jetbrains.mps.kernel.model.SModelUtil; /*package*/ class Datasets { /*package*/ static final AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache> CONCEPTS_CACHE_CREATOR = new AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache>() { @Override public DataSet create(ConceptAndSuperConceptsCache ownerCache) { return new Datasets.ConceptsDataSet(ownerCache); } }; /*package*/ static final AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache> PROPDECL_CACHE_CREATOR = new AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache>() { @Override public DataSet create(ConceptAndSuperConceptsCache ownerCache) { return new Datasets.PropertyDeclarationsDataSet(ownerCache); } }; /*package*/ static final AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache> LINKDECL_CACHE_CREATOR = new AbstractCache.DataSetCreator<ConceptAndSuperConceptsCache>() { @Override public DataSet create(ConceptAndSuperConceptsCache ownerCache) { return new Datasets.LinkDeclarationsDataSet(ownerCache); } }; /*package*/ Datasets() { } private static void collectImplementedAndExtended(@NotNull SNode top, Set<SNode> result) { Set<SNode> frontier = new LinkedHashSet<SNode>(); Set<SNode> newFrontier = new LinkedHashSet<SNode>(); frontier.add(top); result.add(top); while (!(frontier.isEmpty())) { // AbstractConceptDeclaration for (SNode cd : frontier) { if (SNodeUtil.isInstanceOfInterfaceConceptDeclaration(cd)) { for (SNode interfaceDeclaration : SNodeUtil.getInterfaceConceptDeclaration_Extends(cd)) { if (interfaceDeclaration != null && !(result.contains(interfaceDeclaration))) { newFrontier.add(interfaceDeclaration); result.add(interfaceDeclaration); } } } else if (SNodeUtil.isInstanceOfConceptDeclaration(cd)) { SNode anExtends = SNodeUtil.getConceptDeclaration_Extends(cd); if (anExtends != null && !(result.contains(anExtends))) { newFrontier.add(anExtends); result.add(anExtends); } for (SNode interfaceDeclaration : SNodeUtil.getConceptDeclaration_Implements(cd)) { if (interfaceDeclaration != null && !(result.contains(interfaceDeclaration))) { newFrontier.add(interfaceDeclaration); result.add(interfaceDeclaration); } } } } frontier = newFrontier; newFrontier = new LinkedHashSet<SNode>(); } } /*package*/ static class ConceptsDataSet extends DataSet { public static final String ID = "CONCEPTS_DATASET"; @NotNull private final SNode myTopConcept; private SNode[] myConcepts; private Set<SNode> myDependsOnNodes; public ConceptsDataSet(ConceptAndSuperConceptsCache ownerCache) { super(ID, ownerCache, DataSet.DefaultNodeChangedProcessing.DROP_OWNER_CACHE); myTopConcept = ownerCache.getTopConcept(); } public SNode[] getConcepts() { return myConcepts; } @Override public Set<SNode> getDependsOnNodes() { return myDependsOnNodes; } @Override protected void init() { Set<SNode> result = new LinkedHashSet<SNode>(); Datasets.collectImplementedAndExtended(myTopConcept, result); result.add(SNodeOperations.getNode("r:00000000-0000-4000-0000-011c89590288(jetbrains.mps.lang.core.structure)", "1133920641626")); myConcepts = result.toArray(new SNode[result.size()]); // depends on concepts and implemented interface references myDependsOnNodes = new HashSet<SNode>(myConcepts.length * 2); for (SNode concept : myConcepts) { myDependsOnNodes.add(concept); if (SNodeUtil.isInstanceOfInterfaceConceptDeclaration(concept)) { for (SNode n : SNodeUtil.getInterfaceConceptDeclaration_ExtendsReferenceNodes(concept)) { if (n == null) { continue; } myDependsOnNodes.add(n); } } else if (SNodeUtil.isInstanceOfConceptDeclaration(concept)) { for (SNode n : SNodeUtil.getConceptDeclaration_ImplementsReferenceNodes(concept)) { if (n == null) { continue; } myDependsOnNodes.add(n); } } } } @Override public void childAdded(SModelChildEvent event) { // event handling if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) { // don't process adding of smth. to concept unless it is extended/implemented interface-concept if (isExtendsImplementsRole(event)) { super.childAdded(event); } } } @Override public void childRemoved(SModelChildEvent event) { if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) { // don't process removing of smth. from concept unless it is extended/implemented interface-concept if (isExtendsImplementsRole(event)) { super.childRemoved(event); } } } private boolean isExtendsImplementsRole(SModelChildEvent event) { String role = event.getChildRole(); return SNodeUtil.link_ConceptDeclaration_implements.getRoleName().equals(role) || SNodeUtil.link_ConceptDeclaration_extends.getRoleName().equals(role); } @Override public void propertyChanged(SModelPropertyEvent event) { } } /*package*/ static class PropertyDeclarationsDataSet extends DataSet { public static final String ID = "PROPERTY_DECLARATIONS_DATASET"; private Map<String, SNode> myPropertyByName = null; private List<SNode> myProperties = null; private Set<SNode> myDependsOnNodes; public PropertyDeclarationsDataSet(AbstractCache ownerCache) { super(ID, ownerCache, DataSet.DefaultNodeChangedProcessing.DROP_DATA_SET); } @Override public Set<SNode> getDependsOnNodes() { return myDependsOnNodes; } public SNode getPropertyDeclarationByName(String name) { return (myPropertyByName == null ? null : myPropertyByName.get(name)); } public List<SNode> getPropertyDeclarations() { return (myProperties == null ? Collections.<SNode>emptyList() : new ArrayList<SNode>(myProperties)); } @Override protected void init() { List<SNode> allProperties = new ArrayList<SNode>(); myPropertyByName = null; myProperties = null; SNode[] concepts = ((ConceptAndSuperConceptsCache) getOwnerCache()).getConcepts(); // iterate bottom-up for (int i = concepts.length - 1; i >= 0; i--) { Iterable<SNode> props = SNodeUtil.getConcept_PropertyDeclarations(concepts[i]); for (SNode prop : props) { allProperties.add(prop); String name = prop.getName(); if (name == null) { continue; } if (myPropertyByName != null && myPropertyByName.containsKey(name)) { // properties can not be "overridden" continue; } if (myProperties == null) { myProperties = new ArrayList<SNode>(1); } myProperties.add(prop); if (myPropertyByName == null) { myPropertyByName = new HashMap<String, SNode>(); } myPropertyByName.put(name, prop); } } // depends on concepts and link declarations myDependsOnNodes = new HashSet<SNode>(); myDependsOnNodes.addAll(Arrays.asList(concepts)); for (SNode prop : allProperties) { myDependsOnNodes.add(prop); } } @Override public void childAdded(SModelChildEvent event) { // ------event handling if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) { // don't process adding of smth. to concept unless it is property-declaration if (isPropertyDeclarationRole(event)) { super.childAdded(event); } } } @Override public void childRemoved(SModelChildEvent event) { if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) { // don't process removing of smth. from concept unless it is property-declaration if (isPropertyDeclarationRole(event)) { super.childRemoved(event); } } } private boolean isPropertyDeclarationRole(SModelChildEvent event) { String role = event.getChildRole(); return SNodeUtil.link_AbstractConceptDeclaration_propertyDeclaration.getRoleName().equals(role); } @Override public void propertyChanged(SModelPropertyEvent event) { // don't process unless it is property name if (SNodeUtil.isInstanceOfPropertyDeclaration(event.getNode())) { super.propertyChanged(event); } } } /*package*/ static class LinkDeclarationsDataSet extends DataSet { public static final String ID = "LINK_DECLARATIONS_DATASET"; private Map<String, SNode> myLinkByRole = null; private Map<SNode, SNode> myMostSpecificLinkBySpecializedLink = null; private List<SNode> myMostSpecificLinks = null; private Set<SNode> myDependsOnNodes; public LinkDeclarationsDataSet(AbstractCache ownerCache) { super(ID, ownerCache, DataSet.DefaultNodeChangedProcessing.DROP_DATA_SET); } @Override public Set<SNode> getDependsOnNodes() { return myDependsOnNodes; } public SNode getLinkDeclarationByRole(String role) { return (myLinkByRole == null ? null : myLinkByRole.get(role)); } public SNode getMostSpecificLinkDeclarationByRole(String role) { SNode linkDeclaration = getLinkDeclarationByRole(role); if (linkDeclaration == null) { return null; } if (myMostSpecificLinkBySpecializedLink == null) { return linkDeclaration; } SNode mostSpecificLinkDeclaration = myMostSpecificLinkBySpecializedLink.get(linkDeclaration); if (mostSpecificLinkDeclaration == null) { return linkDeclaration; } return mostSpecificLinkDeclaration; } public List<SNode> getLinkDeclarationsExcludingOverridden() { return (myMostSpecificLinks == null ? Collections.<SNode>emptyList() : new ArrayList<SNode>(myMostSpecificLinks)); } @Override protected void init() { myLinkByRole = null; SNode[] concepts = ((ConceptAndSuperConceptsCache) getOwnerCache()).getConcepts(); FlattenIterable<SNode> allLinks = new FlattenIterable<SNode>(new ArrayList<Iterable<SNode>>(concepts.length)); for (SNode concept : concepts) { Iterable<SNode> list = SNodeUtil.getConcept_LinkDeclarations((SNode) concept); allLinks.add(list); for (SNode link : list) { String role1 = SModelUtil.getLinkDeclarationRole(link); if (role1 == null) { continue; } if (myLinkByRole != null && myLinkByRole.containsKey(role1)) { continue; } if (myLinkByRole == null) { myLinkByRole = new HashMap<String, SNode>(); } myLinkByRole.put(role1, link); } } Map<SNode, SNode> specializedLinks = new HashMap<SNode, SNode>(); for (SNode link : allLinks) { SNode specializedLink = SModelUtil.getLinkDeclarationSpecializedLink(link); if (specializedLink != null) { specializedLinks.put(specializedLink, link); } } myMostSpecificLinkBySpecializedLink = null; myMostSpecificLinks = null; for (SNode link : allLinks) { SNode moreSpecificLink = specializedLinks.get(link); if (moreSpecificLink == null) { if (myMostSpecificLinks == null) { myMostSpecificLinks = new ArrayList<SNode>(5); } myMostSpecificLinks.add(link); } else { while (moreSpecificLink != null) { if (myMostSpecificLinkBySpecializedLink == null) { myMostSpecificLinkBySpecializedLink = new HashMap<SNode, SNode>(); } myMostSpecificLinkBySpecializedLink.put(link, moreSpecificLink); moreSpecificLink = specializedLinks.get(moreSpecificLink); } } } // depends on concepts and link declarations myDependsOnNodes = new HashSet<SNode>(); myDependsOnNodes.addAll(Arrays.asList(concepts)); for (SNode link : allLinks) { myDependsOnNodes.add(link); } } @Override public void childAdded(SModelChildEvent event) { // event handling if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) { // don't process adding of smth. to concept unless it is link-declaration if (isLinkDeclarationRole(event)) { super.childAdded(event); } } } @Override public void childRemoved(SModelChildEvent event) { if (SNodeUtil.isInstanceOfAbstractConceptDeclaration(event.getParent())) { // don't process removing of smth. from concept unless it is link-declaration if (isLinkDeclarationRole(event)) { super.childRemoved(event); } } } private boolean isLinkDeclarationRole(SModelChildEvent event) { String role = event.getChildRole(); return SNodeUtil.link_AbstractConceptDeclaration_linkDeclaration.getRoleName().equals(role); } @Override public void propertyChanged(SModelPropertyEvent event) { // don't process unless it is link's role if (!(SNodeUtil.property_LinkDeclaration_role.getName().equals(event.getPropertyName())) || !(SNodeUtil.isInstanceOfLinkDeclaration(event.getNode()))) { return; } String oldRole = event.getOldPropertyValue(); if (oldRole != null) { if (myLinkByRole != null) { myLinkByRole.remove(oldRole); } } String newRole = event.getNewPropertyValue(); if (newRole == null) { return; } if (myLinkByRole == null) { myLinkByRole = new HashMap<String, SNode>(); myLinkByRole.put(newRole, event.getNode()); } else if (!(myLinkByRole.containsKey(newRole))) { myLinkByRole.put(newRole, event.getNode()); } } } }