/* * Copyright 2003-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.nodeEditor.cellMenu; import jetbrains.mps.openapi.editor.EditorContext; import jetbrains.mps.openapi.editor.cells.DefaultSubstituteInfo; import jetbrains.mps.openapi.editor.cells.EditorCell; import jetbrains.mps.openapi.editor.cells.SubstituteAction; import jetbrains.mps.smodel.CopyUtil; import jetbrains.mps.smodel.NodeReadAccessCasterInEditor; import jetbrains.mps.smodel.SModelOperations; import jetbrains.mps.smodel.SModelUtil_new; import jetbrains.mps.smodel.SNodeUtil; import jetbrains.mps.smodel.action.DefaultSChildSetter; import jetbrains.mps.smodel.action.DefaultSChildSubstituteAction; import jetbrains.mps.smodel.action.ModelActions; import jetbrains.mps.smodel.constraints.ModelConstraints; import jetbrains.mps.smodel.presentation.ReferenceConceptUtil; import jetbrains.mps.typesystem.inference.InequalitySystem; import jetbrains.mps.typesystem.inference.TypeChecker; import org.jetbrains.mps.openapi.language.SAbstractConcept; import org.jetbrains.mps.openapi.language.SConcept; import org.jetbrains.mps.openapi.language.SContainmentLink; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.language.SReferenceLink; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.model.SNode; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; public class DefaultSChildSubstituteInfo extends AbstractNodeSubstituteInfo implements DefaultSubstituteInfo { private SNode myParentNode; private SNode myCurrentChild; private SContainmentLink myLink; private SAbstractConcept myTargetConcept; public DefaultSChildSubstituteInfo(final SNode parentNode, final SContainmentLink link, final EditorContext editorContext) { super(editorContext); myLink = link; NodeReadAccessCasterInEditor.runReadTransparentAction(new Runnable() { @Override public void run() { myParentNode = parentNode; Iterable<? extends SNode> ch = parentNode.getChildren(myLink); myCurrentChild = ch.iterator().hasNext() ? ch.iterator().next() : null; } }); myTargetConcept = link.getTargetConcept(); } public DefaultSChildSubstituteInfo(final SNode parentNode, final SNode currChildNode, final SContainmentLink link, final EditorContext editorContext) { super(editorContext); myParentNode = parentNode; myCurrentChild = currChildNode; myLink = link; myTargetConcept = link.getTargetConcept(); } @Override public List<SubstituteAction> createActions() { return ModelActions.createChildNodeSubstituteActions(myParentNode, myCurrentChild, myLink, myTargetConcept, createDefaultNodeSetter(), getEditorContext()); } @Override protected InequalitySystem getInequalitiesSystem(EditorCell contextCell) { HashMap<SNode, SNode> mapping = new HashMap<>(); final SNode copy = CopyUtil.copy(Arrays.asList(myParentNode.getContainingRoot()), mapping).get(0); getModelForTypechecking().addRootNode(copy); final SAbstractConcept concept = myLink.getTargetConcept(); boolean holeIsAType = concept.isSubConceptOf(SNodeUtil.concept_IType); SNode parent = mapping.get(myParentNode); SNode hole = SModelUtil_new.instantiateConceptDeclaration(SNodeUtil.concept_BaseConcept, null, null, true); if (myCurrentChild != null) { SNode child = mapping.get(myCurrentChild); parent.insertChildBefore(myLink, hole, child); parent.removeChild(child); } else { parent.addChild(myLink, hole); } InequalitySystem inequationsForHole = TypeChecker.getInstance().getInequalitiesForHole(hole, holeIsAType); inequationsForHole.replaceRefs(mapping); return inequationsForHole; } protected DefaultSChildSetter createDefaultNodeSetter() { return new DefaultSChildSetter(myLink); } protected SContainmentLink getLink() { return myLink; } }