package jetbrains.mps.ide.make.actions; /*Generated by MPS */ import org.jetbrains.annotations.NotNull; import jetbrains.mps.project.Project; import jetbrains.mps.ide.save.SaveRepositoryCommand; import jetbrains.mps.make.MakeSession; import jetbrains.mps.ide.make.DefaultMakeMessageHandler; import jetbrains.mps.make.IMakeService; import java.util.List; import jetbrains.mps.make.resources.IResource; import java.util.ArrayList; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.smodel.ModelAccessHelper; import jetbrains.mps.util.Computable; import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.internal.collections.runtime.ITranslator2; import jetbrains.mps.smodel.resources.MResource; import jetbrains.mps.ide.generator.GenerationCheckHelper; public class MakeActionImpl { private MakeActionParameters myParams; public MakeActionImpl(@NotNull MakeActionParameters params) { this.myParams = params; } /** * should be called outside of command */ public void executeAction() { final Project project = myParams.getProject(); if (project.getModelAccess().isCommandAction()) { throw new IllegalStateException("should be called outside of command"); } // save all before launching make new SaveRepositoryCommand(project.getRepository()).execute(); MakeSession session = new MakeSession(project, new DefaultMakeMessageHandler(project), myParams.isCleanMake()); if (IMakeService.INSTANCE.get().openNewSession(session)) { // empty collection is fine, it's up to make service to report there's nothing to do (odd, but fine for now. Action could have do that instead) // // ModelValidatorAdapter needs to be refactored not to mix model checking code with UI, which might request // write access e.g. on focus lost and eventually lead to 'write from read' issue like // FIXME https://youtrack.jetbrains.com/issue/MPS-24020. Proper fix is to split model check into read, and results reporting into EDT. // For 3.4 RC, we decided to go with a hack and let SModel instances cross model read boundary List<IResource> inputRes = null; final ArrayList<SModel> models = new ArrayList<SModel>(); try { inputRes = new ModelAccessHelper(project.getModelAccess()).runReadAction(new Computable<List<IResource>>() { public List<IResource> compute() { List<IResource> rv = Sequence.fromIterable(myParams.collectInput()).toListSequence(); models.addAll(ListSequence.fromList(rv).translate(new ITranslator2<IResource, SModel>() { public Iterable<SModel> translate(IResource it) { return ((MResource) it).models(); } }).toListSequence()); return rv; } }); if (!(new GenerationCheckHelper().checkModelsBeforeGenerationIfNeeded(project, models))) { inputRes = null; // fall-through to close make session } } catch (RuntimeException e) { IMakeService.INSTANCE.get().closeSession(session); throw e; } if (inputRes != null) { IMakeService.INSTANCE.get().make(session, inputRes); } else { IMakeService.INSTANCE.get().closeSession(session); } } } }