/* * Copyright 2003-2016 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.generator.impl; import jetbrains.mps.generator.IGeneratorLogger.ProblemDescription; import jetbrains.mps.generator.impl.reference.PostponedReference; import jetbrains.mps.generator.impl.reference.ReferenceInfo_CopiedInputNode; import jetbrains.mps.generator.runtime.TemplateContext; import jetbrains.mps.smodel.CopyUtil; import jetbrains.mps.smodel.language.LanguageRegistry; import jetbrains.mps.smodel.language.LanguageRuntime; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.model.SModelReference; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.model.SNodeReference; import org.jetbrains.mps.openapi.model.SReference; import java.util.HashMap; /** * Responsible to "adopt" a child node to output model * @author Artem Tikhomirov */ public class ChildAdopter { private final TemplateGenerator myGenerator; public ChildAdopter(TemplateGenerator generator) { myGenerator = generator; } public void checkIsExpectedLanguage(@NotNull Iterable<SNode> nodes, @NotNull SNodeReference templateNode, @NotNull TemplateContext templateContext) { HashMap<SLanguage, SNode> langToReport = new HashMap<SLanguage, SNode>(); for (SNode node : nodes) { SLanguage lang = node.getConcept().getLanguage(); if (!myGenerator.getGenerationPlan().isCountedLanguage(lang)) { LanguageRuntime lr = LanguageRegistry.getInstance().getLanguage(lang); if (lr != null && !lr.getGenerators().isEmpty()) { langToReport.put(lang, node); } } } if (langToReport.isEmpty()) { return; } for (SLanguage lang : langToReport.keySet()) { String hint = String.format("workaround: add the language '%s' to list of 'Languages Engaged On Generation' in model '%s'", lang.getQualifiedName(), myGenerator.getGeneratorSessionContext().getOriginalInputModel().getName()); myGenerator.getLogger().error(templateNode, String.format("language of output node is '%s' - this language did not show up when computing generation steps!", lang.getQualifiedName()), GeneratorUtil.describeInput(templateContext), GeneratorUtil.describe(langToReport.get(lang), "output"), new ProblemDescription(hint)); } } public SNode adopt(@NotNull SNode child, @NotNull TemplateContext templateContext) { if (child.getModel() != null) { // must be "in air" child = CopyUtil.copy(child); } // replace references back to input model validateReferences(child, templateContext.getInput()); return child; } private void validateReferences(SNode node, final SNode inputNode) { SModelReference inputModelRef = myGenerator.getInputModel().getReference(); for (SReference ref : node.getReferences()) { // reference to input model - illegal if (inputModelRef.equals(ref.getTargetSModelReference())) { // replace ReferenceInfo_CopiedInputNode refInfo = new ReferenceInfo_CopiedInputNode(inputNode, ref.getTargetNode()); new PostponedReference(ref.getLink(), node, refInfo).registerWith(myGenerator); } } for (SNode child : node.getChildren()) { validateReferences(child, inputNode); } } }