package jetbrains.mps.tool.builder.make;
/*Generated by MPS */
import jetbrains.mps.tool.builder.MpsWorker;
import jetbrains.mps.tool.common.Script;
import jetbrains.mps.project.Project;
import jetbrains.mps.tool.common.GeneratorProperties;
import jetbrains.mps.generator.IModifiableGenerationSettings;
import jetbrains.mps.generator.GenerationSettingsProvider;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.smodel.resources.MResource;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.make.MakeSession;
import jetbrains.mps.internal.make.cfg.JavaCompileFacetInitializer;
import jetbrains.mps.make.script.IScriptController;
import java.util.concurrent.Future;
import jetbrains.mps.make.script.IResult;
import jetbrains.mps.progress.EmptyProgressMonitor;
import java.util.concurrent.ExecutionException;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.smodel.Language;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import java.util.List;
import jetbrains.mps.generator.GenerationFacade;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import jetbrains.mps.smodel.resources.ModelsToResources;
import jetbrains.mps.make.resources.IResource;
import jetbrains.mps.messages.IMessageHandler;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.messages.IMessage;
public abstract class BaseGeneratorWorker extends MpsWorker {
private final BaseGeneratorWorker.MyMessageHandler myMessageHandler = new BaseGeneratorWorker.MyMessageHandler();
public BaseGeneratorWorker(Script whatToDo, MpsWorker.AntLogger logger) {
super(whatToDo, logger);
}
protected BaseGeneratorWorker.MyMessageHandler getMyMessageHandler() {
return myMessageHandler;
}
@Override
protected void executeTask(final Project project, MpsWorker.ObjectsToProcess go) {
setGenerationProperties();
if (go.hasAnythingToGenerate()) {
generate(project, go);
}
}
protected void setGenerationProperties() {
GeneratorProperties gp = new GeneratorProperties(myWhatToDo);
IModifiableGenerationSettings settings = GenerationSettingsProvider.getInstance().getGenerationSettings();
boolean strictMode = gp.isStrictMode();
boolean parallelMode = gp.isParallelMode();
boolean inplace = gp.isInplaceTransform();
boolean warnings = !(gp.isHideWarnings());
int threadCount = gp.getParallelThreads();
final boolean useStaticRefs = gp.isCreateStaticRefs();
settings.setStrictMode(strictMode);
if (strictMode) {
settings.setParallelGenerator(parallelMode);
if (parallelMode) {
settings.setNumberOfParallelThreads(threadCount);
}
}
String[] onoff = new String[]{"on", "off"};
settings.enableInplaceTransformations(inplace);
settings.setShowBadChildWarning(warnings);
settings.setCreateStaticReferences(useStaticRefs);
// incremental generation for Ant build doesn't make sense as we have no way to ensure 'unchanged' artifacts are still there
settings.setIncremental(false);
settings.setIncrementalUseCache(false);
settings.setCheckModelsBeforeGeneration(false);
info(String.format("Generating: strict mode is %s, parallel generation is %s (%d threads), in-place is %s, warnings are %s, static references to replace dynamic is %s", onoff[(strictMode ? 0 : 1)], onoff[(parallelMode ? 0 : 1)], (parallelMode ? threadCount : 1), onoff[(inplace ? 0 : 1)], onoff[(warnings ? 0 : 1)], onoff[(useStaticRefs ? 0 : 1)]));
}
@Override
protected void showStatistic() {
failBuild("generation");
}
protected void generate(Project project, MpsWorker.ObjectsToProcess go) {
StringBuffer s = new StringBuffer("Generating:");
for (Project p : go.getProjects()) {
s.append("\n ");
s.append(p);
}
for (SModule m : go.getModules()) {
s.append("\n ");
s.append(m);
}
for (SModel m : go.getModels()) {
s.append("\n ");
s.append(m);
}
info(s.toString());
Iterable<MResource> resources = Sequence.fromIterable(collectResources(project, go)).toListSequence();
myEnvironment.flushAllEvents();
final MakeSession session = new MakeSession(project, myMessageHandler, true);
JavaCompileFacetInitializer jcfi = new JavaCompileFacetInitializer().skipCompilation(mySkipCompilation).setJavaCompileOptions(myJavaCompilerOptions);
IScriptController controller = new IScriptController.Stub2(session, jcfi);
Future<IResult> res = new BuildMakeService().make(session, resources, null, controller, new EmptyProgressMonitor());
try {
if (!(res.get().isSucessful())) {
myErrors.add("Make was not successful");
}
} catch (InterruptedException e) {
myErrors.add(e.toString());
} catch (ExecutionException e) {
myErrors.add(e.toString());
}
myEnvironment.flushAllEvents();
}
private Iterable<SModule> withGenerators(Iterable<SModule> modules) {
return Sequence.fromIterable(modules).concat(Sequence.fromIterable(modules).where(new IWhereFilter<SModule>() {
public boolean accept(SModule it) {
return it instanceof Language;
}
}).translate(new ITranslator2<SModule, SModule>() {
public Iterable<SModule> translate(SModule it) {
return (List<SModule>) (List) ((Language) it).getGenerators();
}
}));
}
private Iterable<SModel> getModelsToGenerate(SModule mod) {
return Sequence.fromIterable(((Iterable<SModel>) mod.getModels())).where(new IWhereFilter<SModel>() {
public boolean accept(SModel it) {
return GenerationFacade.canGenerate(it);
}
}).select(new ISelector<SModel, SModel>() {
public SModel select(SModel it) {
return (SModel) it;
}
});
}
protected Iterable<MResource> collectResources(Project project, final MpsWorker.ObjectsToProcess go) {
final Wrappers._T<Iterable<SModel>> models = new Wrappers._T<Iterable<SModel>>(null);
project.getModelAccess().runReadAction(new Runnable() {
public void run() {
for (Project p : go.getProjects()) {
for (SModule mod : withGenerators((Iterable<SModule>) p.getModules())) {
models.value = Sequence.fromIterable(models.value).concat(Sequence.fromIterable((getModelsToGenerate(mod))));
}
}
for (SModule mod : withGenerators(go.getModules())) {
models.value = Sequence.fromIterable(models.value).concat(Sequence.fromIterable(getModelsToGenerate(mod)));
}
if (go.getModels() != null) {
models.value = Sequence.fromIterable(models.value).concat(SetSequence.fromSet(go.getModels()));
}
}
});
return Sequence.fromIterable(new ModelsToResources(Sequence.fromIterable(models.value).where(new IWhereFilter<SModel>() {
public boolean accept(SModel smd) {
return GenerationFacade.canGenerate(smd);
}
})).resources(false)).select(new ISelector<IResource, MResource>() {
public MResource select(IResource r) {
return (MResource) r;
}
});
}
private class MyMessageHandler implements IMessageHandler {
/*package*/ MyMessageHandler() {
}
@Override
public void handle(@NotNull IMessage msg) {
switch (msg.getKind()) {
case ERROR:
if (msg.getException() != null) {
BaseGeneratorWorker.this.error(MpsWorker.extractStackTrace(msg.getException()).toString());
} else {
BaseGeneratorWorker.this.error(msg.getText());
}
break;
case WARNING:
BaseGeneratorWorker.this.warning(msg.getText());
break;
case INFORMATION:
BaseGeneratorWorker.this.info(msg.getText());
break;
default:
}
}
}
}