package jetbrains.mps.build.mps.util;
/*Generated by MPS */
import java.util.LinkedHashSet;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import jetbrains.mps.util.IterableUtil;
import jetbrains.mps.util.iterable.RecursiveIterator;
import java.util.Iterator;
import java.util.HashSet;
import jetbrains.mps.build.mps.behavior.BuildMps_Generator__BehaviorDescriptor;
import java.util.List;
public class MPSModulesClosure {
private LinkedHashSet<SNode> myModules = new LinkedHashSet<SNode>();
private Set<SNode> myDevkits = new LinkedHashSet<SNode>();
/**
* Language modules that have runtime : BuildMps_ModuleRuntime hodling anything but a solution.
*/
private LinkedHashSet<SNode> myLanguagesWithOddRuntime = new LinkedHashSet<SNode>();
private final Iterable<SNode> myInitialModules;
private final boolean myTrackDevkits;
public MPSModulesClosure(SNode initialModule, MPSModulesClosure.ModuleDependenciesOptions options) {
myInitialModules = Sequence.<SNode>singleton(initialModule);
myTrackDevkits = options.myTrackDevkits;
}
public MPSModulesClosure(Iterable<SNode> initialModules, MPSModulesClosure.ModuleDependenciesOptions options) {
myInitialModules = SNodeOperations.ofConcept(initialModules, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508331930cL, "jetbrains.mps.build.mps.structure.BuildMps_Module"));
SNode containingRoot = SNodeOperations.getContainingRoot(Sequence.fromIterable(initialModules).first());
for (SNode m : Sequence.fromIterable(initialModules)) {
if (containingRoot != SNodeOperations.getContainingRoot(m)) {
throw new IllegalArgumentException("all modules should be from the same root");
}
}
myTrackDevkits = options.myTrackDevkits;
}
private <T extends SNode> Iterable<T> withoutNull(Iterable<T> modules) {
return Sequence.fromIterable(modules).where(new IWhereFilter<T>() {
public boolean accept(T it) {
return it != null;
}
});
}
private Iterable<SNode> dependencies(SNode module) {
return ListSequence.fromList(SLinkOperations.getChildren(module, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508331930cL, 0x48e82d5083341cb8L, "dependencies"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return (SNodeOperations.isInstanceOf(it, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x64bd442e1cf7aaeeL, "jetbrains.mps.build.mps.structure.BuildMps_ExtractedModuleDependency")) ? SLinkOperations.getTarget(SNodeOperations.cast(it, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x64bd442e1cf7aaeeL, "jetbrains.mps.build.mps.structure.BuildMps_ExtractedModuleDependency")), MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x64bd442e1cf7aaeeL, 0x64bd442e1cf7aaefL, "dependency")) : it);
}
});
}
private Iterable<SNode> getDependencies(SNode module, final boolean reexportOnly) {
Iterable<SNode> dependencies = Sequence.fromIterable(SNodeOperations.ofConcept(dependencies(module), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnModule"))).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return (!(reexportOnly) || SPropertyOperations.getBoolean(it, MetaAdapterFactory.getProperty(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, 0x48e82d5083341cc1L, "reexport")));
}
}).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(it, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, 0x48e82d5083341cb9L, "module"));
}
});
// add extended langs
dependencies = Sequence.fromIterable(dependencies).concat(Sequence.fromIterable(SNodeOperations.ofConcept(dependencies(module), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x3b60c4a45c19032eL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyExtendLanguage"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(it, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x3b60c4a45c19032eL, 0x3b60c4a45c190330L, "language"));
}
}));
if (reexportOnly) {
return withoutNull(dependencies);
}
Iterable<SNode> usedDevkits = Sequence.fromIterable(includingExtended(usedDevkits(module))).toListSequence();
if (myTrackDevkits) {
SetSequence.fromSet(myDevkits).addSequence(Sequence.fromIterable(usedDevkits));
}
Iterable<SNode> solutionsFromDevkits = Sequence.fromIterable(usedDevkits).translate(new ITranslator2<SNode, SNode>() {
public Iterable<SNode> translate(SNode it) {
return Sequence.fromIterable(SNodeOperations.ofConcept(SLinkOperations.getChildren(it, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d2060eL, 0x4780308f5d29d82L, "exports")), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d29d7aL, "jetbrains.mps.build.mps.structure.BuildMps_DevKitExportSolution"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode iit) {
return SLinkOperations.getTarget(iit, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d29d7aL, 0x4780308f5d29d7bL, "solution"));
}
});
}
});
// "core" language is added in loadModules pre-script
return withoutNull(IterableUtil.distinct(IterableUtil.merge(dependencies, solutionsFromDevkits)));
}
private Iterable<SNode> getUsedLanguages(SNode module) {
Iterable<SNode> usedLangs = Sequence.fromIterable(SNodeOperations.ofConcept(dependencies(module), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643d2d2L, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyUseLanguage"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(it, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643d2d2L, 0x2c4467914643d2d3L, "language"));
}
});
Iterable<SNode> usedDevkits = Sequence.fromIterable(includingExtended(usedDevkits(module))).toListSequence();
if (myTrackDevkits) {
SetSequence.fromSet(myDevkits).addSequence(Sequence.fromIterable(usedDevkits));
}
Iterable<SNode> languagesFromDevkits = Sequence.fromIterable(usedDevkits).translate(new ITranslator2<SNode, SNode>() {
public Iterable<SNode> translate(SNode it) {
return Sequence.fromIterable(SNodeOperations.ofConcept(SLinkOperations.getChildren(it, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d2060eL, 0x4780308f5d29d82L, "exports")), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d29d6aL, "jetbrains.mps.build.mps.structure.BuildMps_DevKitExportLanguage"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode iit) {
return SLinkOperations.getTarget(iit, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d29d6aL, 0x4780308f5d29d73L, "language"));
}
});
}
});
// use "core" language is added in loadModules pre-script
return withoutNull(includingExtendedLanguages(IterableUtil.merge(usedLangs, languagesFromDevkits)));
}
private Iterable<SNode> usedDevkits(SNode module) {
return Sequence.fromIterable(SNodeOperations.ofConcept(dependencies(module), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d5bc49L, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnDevKit"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(it, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d5bc49L, 0x4780308f5d5bc4aL, "devkit"));
}
});
}
private Iterable<SNode> includingExtended(Iterable<SNode> devkits) {
return new RecursiveIterator<SNode>(devkits, false) {
@Override
protected Iterator<SNode> children(SNode node) {
return Sequence.fromIterable(SLinkOperations.collect(SLinkOperations.getChildren(node, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d2060eL, 0x4780308f5d23142L, "extends")), MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4780308f5d2313aL, 0x4780308f5d2313bL, "devkit"))).iterator();
}
};
}
private Iterable<SNode> includingExtendedLanguages(Iterable<SNode> langs) {
return new RecursiveIterator<SNode>(langs, false) {
@Override
protected Iterator<SNode> children(SNode node) {
return Sequence.fromIterable(SNodeOperations.ofConcept(dependencies(node), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x3b60c4a45c19032eL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyExtendLanguage"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(it, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x3b60c4a45c19032eL, 0x3b60c4a45c190330L, "language"));
}
}).iterator();
}
};
}
private Iterable<SNode> usedGenerators(Iterable<SNode> generators) {
return new RecursiveIterator<SNode>(generators, false) {
protected Iterator<SNode> children(SNode generator) {
return Sequence.fromIterable(SNodeOperations.ofConcept(SLinkOperations.collect(SNodeOperations.ofConcept(dependencies(generator), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnModule")), MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, 0x48e82d5083341cb9L, "module")), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4c6db07d2e56a8b4L, "jetbrains.mps.build.mps.structure.BuildMps_Generator"))).iterator();
}
};
}
private void collectDependencies(Iterable<SNode> sequence, boolean reexportOnly) {
if (Sequence.fromIterable(sequence).isEmpty()) {
return;
}
Set<SNode> dependencies = SetSequence.fromSet(new HashSet<SNode>());
for (SNode module : Sequence.fromIterable(sequence)) {
SetSequence.fromSet(dependencies).addSequence(Sequence.fromIterable(getDependencies(module, reexportOnly)));
}
SetSequence.fromSet(dependencies).removeSequence(SetSequence.fromSet(myModules));
myModules.addAll(dependencies);
collectDependencies(dependencies, reexportOnly);
}
/**
* For each module, collect execution-time dependencies, based on runtime solution of languages which were used to
* generate given module. Dependencies are transitive (i.e. include RTs for runtime solutions).
*
* Dependencies necessary to load RT solutions are also included. For an input module, DOES NOT include dependencies other than RT solutions.
*
* @param sequence input modules
*/
private void collectAllUsedLanguageRuntimesAndTheirDeps(Iterable<SNode> sequence) {
if (Sequence.fromIterable(sequence).isEmpty()) {
return;
}
Set<SNode> langs = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> langsWithOddRT = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> rtSolutions = SetSequence.fromSet(new HashSet<SNode>());
for (SNode module : Sequence.fromIterable(sequence)) {
fillUsedLanguageRuntimes(module, langs, langsWithOddRT, rtSolutions);
}
SetSequence.fromSet(rtSolutions).removeSequence(SetSequence.fromSet(myModules));
myModules.addAll(rtSolutions);
myLanguagesWithOddRuntime.addAll(langsWithOddRT);
collectDependencies(((Iterable<SNode>) rtSolutions), false);
collectAllUsedLanguageRuntimesAndTheirDeps(((Iterable<SNode>) rtSolutions));
}
private void collectGeneratorsDependendencies(Iterable<SNode> languages) {
if (Sequence.fromIterable(languages).isEmpty()) {
return;
}
Set<SNode> extraLangs = SetSequence.fromSet(new HashSet<SNode>());
for (SNode g : SLinkOperations.collect(languages, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c446791464290f8L, 0x7fae147806433827L, "generator"))) {
if (g == null) {
continue;
}
Iterable<SNode> deps = SLinkOperations.collect(SNodeOperations.ofConcept(dependencies(g), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnModule")), MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508334b11aL, 0x48e82d5083341cb9L, "module"));
Iterable<SNode> usedLangs = SLinkOperations.collect(SNodeOperations.ofConcept(dependencies(g), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643d2d2L, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyUseLanguage")), MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643d2d2L, 0x2c4467914643d2d3L, "language"));
// I'm not quite sure it's possible to depend directly from generator module.
// Instead introduce a dependency from generator's source language
SetSequence.fromSet(extraLangs).addSequence(Sequence.fromIterable(SNodeOperations.ofConcept(deps, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x4c6db07d2e56a8b4L, "jetbrains.mps.build.mps.structure.BuildMps_Generator"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return (SNode) BuildMps_Generator__BehaviorDescriptor.getSourceLanguage_id7YI57w6ZMdZ.invoke(it);
}
}).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return it != null;
}
}));
// any language generator depends from are better to be there, too.
SetSequence.fromSet(extraLangs).addSequence(Sequence.fromIterable(SNodeOperations.ofConcept(deps, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c446791464290f8L, "jetbrains.mps.build.mps.structure.BuildMps_Language"))));
SetSequence.fromSet(extraLangs).addSequence(Sequence.fromIterable(usedLangs));
myModules.addAll(Sequence.fromIterable(SNodeOperations.ofConcept(deps, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c446791464290f7L, "jetbrains.mps.build.mps.structure.BuildMps_Solution"))).toListSequence());
}
SetSequence.fromSet(extraLangs).removeSequence(SetSequence.fromSet(myModules));
myModules.addAll(extraLangs);
collectGeneratorsDependendencies(extraLangs);
}
/**
* To compile, module needs its direct dependencies, plus re-exported dependencies of those.
* RTs of used languages and their dependencies won't hurt either.
*/
public MPSModulesClosure closure() {
// get all direct dependencies abd runtimes, plus re-exported dependencies thereof.
Set<SNode> langs = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> langsWithOddRT = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> solutions = SetSequence.fromSet(new HashSet<SNode>());
for (SNode module : Sequence.fromIterable(myInitialModules)) {
List<SNode> firstLevelDeps = Sequence.fromIterable(getDependencies(module, false)).toListSequence();
collectDependencies(firstLevelDeps, true);
fillUsedLanguageRuntimes(module, langs, langsWithOddRT, solutions);
myModules.addAll(firstLevelDeps);
}
myModules.addAll(solutions);
myLanguagesWithOddRuntime.addAll(langsWithOddRT);
collectDependencies(((Iterable<SNode>) solutions), true);
myModules.removeAll(Sequence.fromIterable(myInitialModules).toListSequence());
return this;
}
/**
* To start, module needs all its dependencies plus RTs of languages it uses.
* However, its use in mps.build.mps generator is dubious, as it merely adds rt dependencies of specific module
* to the list of external (for the current project) modules.
*
* Its use in MPSModulesPartitioner is another way of saying "if I generate a model and there's a language, which has runtime coming from another build script, add it to dependencies"
* Although it's not clear why would one need language runtime during generation.
* XXX Perhaps, {@link jetbrains.mps.build.mps.util.MPSModulesClosure#generationDependenciesClosure() } shall collect module's dependencies (collectDependencies(false)) instead
*/
public MPSModulesClosure runtimeClosure() {
collectDependencies(myInitialModules, false);
collectAllUsedLanguageRuntimesAndTheirDeps(myInitialModules);
myModules.removeAll(Sequence.fromIterable(myInitialModules).toListSequence());
return this;
}
/**
* Looks like an attempt to replace MPSModulePartitioner.getExternal() + runtimeClosure() (i.e. expand external dependencies with dependencies from this project)
* We use this to populate libraries of Environment for our tasks (MpsWorker) to start MPS with specific set of modules (hence we need a closure of modules for MPS to start properly).
*/
public MPSModulesClosure designtimeClosure() {
// direct and indirect dependencies of the modules, languages used and their runtimes
collectDependencies(myInitialModules, false);
collectAllUsedLanguageRuntimesAndTheirDeps(myInitialModules);
for (SNode m : Sequence.fromIterable(myInitialModules)) {
Iterable<SNode> usedLanguages = getUsedLanguages(m);
collectDependencies(usedLanguages, false);
collectAllUsedLanguageRuntimesAndTheirDeps(usedLanguages);
myModules.addAll(Sequence.fromIterable(usedLanguages).toListSequence());
}
myModules.removeAll(Sequence.fromIterable(myInitialModules).toListSequence());
return this;
}
/**
* To generate a module, we need its languages and all their dependencies.
* Unlike {@link jetbrains.mps.build.mps.util.MPSModulesClosure#runtimeClosure() } or {@link jetbrains.mps.build.mps.util.MPSModulesClosure#designtimeClosure() }, dependencies of the module itself (aka classpath) doesn't look
* that imporant (although what if there's utility class in the generator, which depends on external module, and is queried during generation?)
*/
public MPSModulesClosure generationDependenciesClosure() {
// direct and indirect dependencies of used languages and their runtimes; source languages of generators involved
Set<SNode> usedLanguages = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> langsWithOddRT = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> solutions = SetSequence.fromSet(new HashSet<SNode>());
for (SNode m : Sequence.fromIterable(myInitialModules)) {
fillUsedLanguageRuntimes(m, usedLanguages, langsWithOddRT, solutions);
}
// need module of a used language AND anything this module would require to load
collectDependencies((Iterable<SNode>) usedLanguages, false);
// code, generated with a used language, might require runtime of the language, and anything this RT solution
// re-exports. However, without all dependencies (including non-reexported), solution won't load, hence include all.
collectDependencies((Iterable<SNode>) solutions, false);
// RT solutions might be generated with other set of languages with own set of RT dependencies, collect these, too.
collectAllUsedLanguageRuntimesAndTheirDeps((Iterable<SNode>) solutions);
// for employed languages, look at their generators and include their dependencies, too
collectGeneratorsDependendencies(usedLanguages);
myModules.addAll(usedLanguages);
myLanguagesWithOddRuntime.addAll(langsWithOddRT);
return this;
}
/**
* This is what we list as module dependencies in module.xml
* I have no idea why it's a list of runtime solutions of used languages.
* As long as we distribute (and process) original module descriptor in src.jar, it seems these dependencies
* (ModuleDescriptor.getDeploymentDescriptor().getDependencies()) are irrelevant.
*/
public MPSModulesClosure runtimeDependencies() {
// direct dependencies of used languages' runtime solutions
if (Sequence.fromIterable(myInitialModules).count() != 1) {
throw new IllegalStateException("cannot build runtime dependencies for several modules");
}
SNode initial = Sequence.fromIterable(myInitialModules).first();
Set<SNode> langs = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> langsWithOddRT = SetSequence.fromSet(new HashSet<SNode>());
Set<SNode> runtimes = SetSequence.fromSet(new HashSet<SNode>());
fillUsedLanguageRuntimes(initial, langs, langsWithOddRT, runtimes);
myModules.addAll(runtimes);
myLanguagesWithOddRuntime.addAll(langsWithOddRT);
return this;
}
/**
* Collects and analyzes used languages and their runtime solutions for the given module.
* Generally, shall be static and without side-effects, however, at the moment uses {@link jetbrains.mps.build.mps.util.MPSModulesClosure#getUsedLanguages(SNode) } which updates myDevkits field
* FIXME refactor, introduce fillUsedLanguages(module, set[languages])and make them static
*
* @param module given
* @param usedLanguages filled with used languages of the module
* @param languagesWithRuntime will be filled with the used languages that has runtime which IS NOT a regular runtime solution
* @param runtimeSolutions filled with runtime solutions found for used languages
*/
private void fillUsedLanguageRuntimes(SNode module, Set<SNode> usedLanguages, Set<SNode> languagesWithRuntime, Set<SNode> runtimeSolutions) {
List<SNode> ul = Sequence.fromIterable(getUsedLanguages(module)).toListSequence();
SetSequence.fromSet(usedLanguages).addSequence(ListSequence.fromList(ul));
for (SNode language : ul) {
boolean hasRuntime = false;
for (SNode rdep : SLinkOperations.getChildren(language, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c446791464290f8L, 0x2c4467914643be24L, "runtime"))) {
if (!(SNodeOperations.isInstanceOf(rdep, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914644b6e3L, "jetbrains.mps.build.mps.structure.BuildMps_ModuleSolutionRuntime")))) {
hasRuntime = true;
continue;
}
SNode runtimeSolution = SLinkOperations.getTarget(SNodeOperations.cast(rdep, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914644b6e3L, "jetbrains.mps.build.mps.structure.BuildMps_ModuleSolutionRuntime")), MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914644b6e3L, 0x2c4467914644b6e4L, "solution"));
if (runtimeSolution != null) {
SetSequence.fromSet(runtimeSolutions).addElement(runtimeSolution);
}
}
if (hasRuntime) {
SetSequence.fromSet(languagesWithRuntime).addElement(language);
}
}
}
public MPSModulesClosure.RequiredJavaModules getRequiredJava() {
Iterable<SNode> reexportedFromModuleDependencies = Sequence.fromIterable(getModules()).concat(Sequence.fromIterable(myInitialModules)).translate(new ITranslator2<SNode, SNode>() {
public Iterable<SNode> translate(SNode mod) {
return ListSequence.fromList(SLinkOperations.getChildren(mod, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508331930cL, 0x48e82d5083341cb8L, "dependencies"))).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return SNodeOperations.isInstanceOf(it, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnJavaModule")) && SPropertyOperations.getBoolean(SNodeOperations.cast(it, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnJavaModule")), MetaAdapterFactory.getProperty(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, 0x2c4467914643e8fcL, "reexport"));
}
}).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(SNodeOperations.cast(it, MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnJavaModule")), MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, 0x2c4467914643e8fdL, "module"));
}
});
}
});
Set<SNode> reexportMods = SetSequence.fromSet(new HashSet<SNode>());
for (SNode mod : reexportedFromModuleDependencies) {
SetSequence.fromSet(reexportMods).addElement(mod);
}
Iterable<SNode> directDeps = Sequence.fromIterable(SNodeOperations.ofConcept(Sequence.fromIterable(myInitialModules).translate(new ITranslator2<SNode, SNode>() {
public Iterable<SNode> translate(SNode it) {
return SLinkOperations.getChildren(it, MetaAdapterFactory.getContainmentLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x48e82d508331930cL, 0x48e82d5083341cb8L, "dependencies"));
}
}), MetaAdapterFactory.getConcept(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, "jetbrains.mps.build.mps.structure.BuildMps_ModuleDependencyOnJavaModule"))).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return SLinkOperations.getTarget(it, MetaAdapterFactory.getReferenceLink(0xcf935df46994e9cL, 0xa132fa109541cba3L, 0x2c4467914643e8fbL, 0x2c4467914643e8fdL, "module"));
}
});
return new MPSModulesClosure.RequiredJavaModules(Sequence.fromIterable(reexportedFromModuleDependencies).concat(Sequence.fromIterable(directDeps)), reexportMods);
}
public Iterable<SNode> getModules() {
return myModules;
}
public Iterable<SNode> getAllModules() {
return Sequence.fromIterable(((Iterable<SNode>) myModules)).concat(Sequence.fromIterable((Iterable<SNode>) myLanguagesWithOddRuntime)).concat(Sequence.fromIterable((Iterable<SNode>) myDevkits));
}
public SNode getInitial() {
return Sequence.fromIterable(myInitialModules).first();
}
public static class RequiredJavaModules {
private Iterable<SNode> modules;
private Set<SNode> reexported;
public RequiredJavaModules(Iterable<SNode> modules, Set<SNode> reexported) {
this.modules = modules;
this.reexported = reexported;
}
public Iterable<SNode> getModules() {
return modules;
}
public boolean isReexported(SNode mod) {
return SetSequence.fromSet(reexported).contains(mod);
}
}
public static class ModuleDependenciesOptions {
/*package*/ boolean myTrackDevkits = false;
public MPSModulesClosure.ModuleDependenciesOptions trackDevkits() {
myTrackDevkits = true;
return this;
}
}
}