package jetbrains.mps.make.dependencies;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.make.MakeSession;
import jetbrains.mps.smodel.language.LanguageRegistry;
import jetbrains.mps.make.resources.IResource;
import java.util.List;
import jetbrains.mps.smodel.resources.MResource;
import jetbrains.mps.internal.collections.runtime.Sequence;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.internal.collections.runtime.ISequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import java.util.ArrayList;
import org.jetbrains.mps.openapi.language.SLanguage;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import jetbrains.mps.smodel.language.GeneratorRuntime;
import java.util.Queue;
import jetbrains.mps.internal.collections.runtime.QueueSequence;
import java.util.LinkedList;
import jetbrains.mps.smodel.language.LanguageRuntime;
import jetbrains.mps.generator.runtime.TemplateModule;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
public class ModulesClusterizer {
private static Logger LOG = LogManager.getLogger(ModulesCluster.class);
private final MakeSession mySession;
private final LanguageRegistry myLanguageRegistry;
/*package*/ ModulesClusterizer(MakeSession makeSession) {
mySession = makeSession;
myLanguageRegistry = LanguageRegistry.getInstance(mySession.getProject().getRepository());
}
public Iterable<Cluster> clusterize(Iterable<? extends IResource> res) {
final List<MResource> mres = Sequence.fromIterable(res).ofType(MResource.class).toListSequence();
Iterable<SModule> mods = ListSequence.fromList(mres).select(new ISelector<MResource, SModule>() {
public SModule select(MResource r) {
return r.module();
}
});
Iterable<IResource> rest = Sequence.fromIterable(((Iterable<IResource>) res)).subtract(ListSequence.fromList(mres));
ModulesCluster clst = new ModulesCluster(mods, myLanguageRegistry);
clst.collectRequired(mods);
Iterable<? extends Iterable<SModule>> moduleBuildOrder = clst.buildOrder();
Iterable<? extends Iterable<MResource>> mresBuildOrder = Sequence.fromIterable(moduleBuildOrder).select(new ISelector<Iterable<SModule>, ISequence<MResource>>() {
public ISequence<MResource> select(final Iterable<SModule> cl) {
return ListSequence.fromList(mres).where(new IWhereFilter<MResource>() {
public boolean accept(MResource r) {
return Sequence.fromIterable(cl).contains(r.module());
}
});
}
});
List<Cluster> result = ListSequence.fromList(new ArrayList<Cluster>());
for (Iterable<MResource> s : mresBuildOrder) {
ListSequence.fromList(result).addElement(new Cluster(s, allLanguagesToActivateFacets(s, clst), myLanguageRegistry));
}
if (Sequence.fromIterable(rest).isNotEmpty()) {
ListSequence.fromList(result).addElement(new Cluster(rest, ListSequence.fromList(new ArrayList<SLanguage>()), myLanguageRegistry));
}
return result;
}
private Iterable<SLanguage> allLanguagesToActivateFacets(Iterable<MResource> cluster, final ModulesCluster builder) {
Iterable<SLanguage> usedLanguages = Sequence.fromIterable(cluster).translate(new ITranslator2<MResource, SLanguage>() {
public Iterable<SLanguage> translate(MResource r) {
return builder.usedLanguage(r.module());
}
});
Set<SLanguage> namespaces = SetSequence.fromSet(new HashSet<SLanguage>());
Set<GeneratorRuntime> seen = SetSequence.fromSet(new HashSet<GeneratorRuntime>());
Queue<SLanguage> nsq = QueueSequence.fromQueue(new LinkedList<SLanguage>());
QueueSequence.fromQueue(nsq).addSequence(Sequence.fromIterable(usedLanguages).distinct());
// We need to care about used languages of employed generators as we need to respect
// all facets of all languages that may appear during generation of a model/module in the make script
while (QueueSequence.fromQueue(nsq).isNotEmpty()) {
SLanguage ns = QueueSequence.fromQueue(nsq).removeFirstElement();
if (SetSequence.fromSet(namespaces).contains(ns)) {
continue;
}
SetSequence.fromSet(namespaces).addElement(ns);
LanguageRuntime lr = myLanguageRegistry.getLanguage(ns);
if (lr == null) {
LOG.debug("Deployed language not found for namespace " + ns);
continue;
}
for (GeneratorRuntime gr : lr.getGenerators()) {
if (gr instanceof TemplateModule == false) {
continue;
}
if (!(SetSequence.fromSet(seen).contains(gr))) {
QueueSequence.fromQueue(nsq).addSequence(CollectionSequence.fromCollection(((TemplateModule) gr).getTargetLanguages()));
SetSequence.fromSet(seen).addElement(gr);
}
}
}
return namespaces;
}
}