package jetbrains.mps.ide.migration.check;
/*Generated by MPS */
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import com.intellij.openapi.progress.ProgressIndicator;
import jetbrains.mps.ide.migration.ScriptApplied;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
import java.util.Collection;
import jetbrains.mps.lang.migration.runtime.base.Problem;
import jetbrains.mps.internal.collections.runtime.Sequence;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import org.jetbrains.mps.openapi.module.SearchScope;
import jetbrains.mps.lang.smodel.query.runtime.CommandUtil;
import jetbrains.mps.internal.collections.runtime.ISelector;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.lang.smodel.query.runtime.QueryExecutionContext;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import jetbrains.mps.lang.migration.runtime.base.MigrateManually;
import jetbrains.mps.lang.migration.runtime.base.MigrationScriptReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import java.util.Set;
import org.jetbrains.mps.openapi.language.SLanguage;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.mps.openapi.language.SConceptFeature;
import jetbrains.mps.util.NameUtil;
import org.jetbrains.mps.openapi.model.EditableSModel;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.project.validation.ValidationUtil;
import org.jetbrains.mps.openapi.util.Processor;
import jetbrains.mps.project.validation.ValidationProblem;
import jetbrains.mps.project.validation.LanguageMissingError;
import jetbrains.mps.project.validation.ConceptMissingError;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.project.validation.ConceptFeatureMissingError;
import jetbrains.mps.project.validation.BrokenReferenceError;
import jetbrains.mps.module.ReloadableModule;
import jetbrains.mps.classloading.ModuleClassLoaderSupport;
import org.jetbrains.mps.openapi.module.SDependency;
public class MigrationCheckUtil {
public static _FunctionTypes._void_P1_E0<? super Double> progressIndicatorToCallback(final ProgressIndicator progressIndicator, final double start, final double stop) {
progressIndicator.setIndeterminate(false);
progressIndicator.setFraction(0);
return new _FunctionTypes._void_P1_E0<Double>() {
public void invoke(Double fraction) {
progressIndicator.setFraction(start + fraction * (stop - start));
}
};
}
public static boolean haveNotMigrated(Iterable<ScriptApplied> migrationsToCheck, @Nullable _FunctionTypes._void_P1_E0<? super Double> progressCallback) {
return CollectionSequence.fromCollection(getNotMigrated(migrationsToCheck, progressCallback, 1)).isNotEmpty();
}
public static Collection<Problem> getNotMigrated(Iterable<ScriptApplied> migrationsToCheck, @Nullable _FunctionTypes._void_P1_E0<? super Double> progressCallback, int maxErrors) {
final int allSteps = Sequence.fromIterable(migrationsToCheck).count();
int stepsPassed = 0;
final List<Problem> result = ListSequence.fromList(new ArrayList<Problem>());
// todo show only annotations left by our run migrations
{
final SearchScope scope = CommandUtil.createScope(Sequence.fromIterable(migrationsToCheck).select(new ISelector<ScriptApplied, SModule>() {
public SModule select(ScriptApplied it) {
return it.getModule();
}
}).distinct());
QueryExecutionContext context = new QueryExecutionContext() {
public SearchScope getDefaultSearchScope() {
return scope;
}
};
CollectionSequence.fromCollection(CommandUtil.instances(CommandUtil.createConsoleScope(null, false, context), MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x2274019e61f0c2c8L, "jetbrains.mps.lang.core.structure.MigrationAnnotation"), false)).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return ((boolean) (Boolean) BHReflection.invoke(it, SMethodTrimmedId.create("showInResults", null, "29O0pTxWdmG")));
}
}).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
ListSequence.fromList(result).addElement(new MigrateManually(it));
}
});
}
if (ListSequence.fromList(result).count() >= maxErrors) {
return result;
}
for (ScriptApplied sa : Sequence.fromIterable(migrationsToCheck).where(new IWhereFilter<ScriptApplied>() {
public boolean accept(ScriptApplied it) {
return it.getScriptReference() instanceof MigrationScriptReference;
}
})) {
progressCallback.invoke(0.1 + 0.9 * stepsPassed++ / allSteps);
ListSequence.fromList(result).addSequence(Sequence.fromIterable(((MigrationScriptReference) sa.getScriptReference()).resolve(false).check(sa.getModule())));
if (ListSequence.fromList(result).count() >= maxErrors) {
return result;
}
}
return result;
}
public static boolean haveProblems(Iterable<SModule> modules, @NotNull ProgressMonitor pm) {
return CollectionSequence.fromCollection(getProblems(modules, pm, 1)).isNotEmpty();
}
public static Collection<Problem> getProblems(Iterable<SModule> modules, @NotNull ProgressMonitor pm, final int maxErrors) {
pm.start("Checking...", 10 + Sequence.fromIterable(modules).count());
final List<Problem> result = ListSequence.fromList(new ArrayList<Problem>());
Collection<DependencyProblem> badModuleProblems = findBadModules(modules, maxErrors);
ListSequence.fromList(result).addSequence(CollectionSequence.fromCollection(badModuleProblems));
if (ListSequence.fromList(result).count() >= maxErrors) {
return result;
}
pm.advance(10);
final Set<SLanguage> missingLangs = SetSequence.fromSet(new HashSet<SLanguage>());
final Set<SAbstractConcept> missingConcepts = SetSequence.fromSet(new HashSet<SAbstractConcept>());
final Set<SConceptFeature> missingFeatures = SetSequence.fromSet(new HashSet<SConceptFeature>());
for (SModule module : Sequence.fromIterable(modules)) {
pm.step(NameUtil.compactNamespace(module.getModuleName()));
// find missing concepts, when language's not missing
// find missing concept features when concept's not missing
for (EditableSModel model : Sequence.fromIterable(((Iterable<SModel>) module.getModels())).ofType(EditableSModel.class)) {
ValidationUtil.validateModelContent(model.getRootNodes(), new Processor<ValidationProblem>() {
public boolean process(ValidationProblem vp) {
if (vp instanceof LanguageMissingError) {
LanguageMissingError err = (LanguageMissingError) vp;
if (SetSequence.fromSet(missingLangs).contains(err.getLanguage())) {
return true;
}
SetSequence.fromSet(missingLangs).addElement(err.getLanguage());
if (err.isCompletelyAbsent()) {
ListSequence.fromList(result).addElement(new LanguageAbsentInRepoProblem(err.getLanguage(), err.getNode()));
} else {
ListSequence.fromList(result).addElement(new LanguageNotLoadedProblem(err.getLanguage(), err.getNode()));
}
} else if (vp instanceof ConceptMissingError) {
ConceptMissingError err = (ConceptMissingError) vp;
SConcept concept = err.getConcept();
if (SetSequence.fromSet(missingLangs).contains(concept.getLanguage()) || SetSequence.fromSet(missingConcepts).contains(concept)) {
return true;
}
SetSequence.fromSet(missingConcepts).addElement(concept);
ListSequence.fromList(result).addElement(new ConceptMissingProblem(concept, err.getNode()));
} else if (vp instanceof ConceptFeatureMissingError) {
ConceptFeatureMissingError err = (ConceptFeatureMissingError) vp;
SAbstractConcept concept = err.getFeature().getOwner();
if (SetSequence.fromSet(missingLangs).contains(concept.getLanguage()) || SetSequence.fromSet(missingConcepts).contains(concept) || SetSequence.fromSet(missingFeatures).contains(err.getFeature())) {
return true;
}
SetSequence.fromSet(missingFeatures).addElement(err.getFeature());
ListSequence.fromList(result).addElement(new ConceptFeatureMissingProblem(err.getFeature(), err.getNode(), err.getMessage()));
} else if (vp instanceof BrokenReferenceError) {
BrokenReferenceError err = (BrokenReferenceError) vp;
ListSequence.fromList(result).addElement(new BrokenReferenceProblem(err.getReference(), err.getMessage()));
} else {
// ignore other errors
return true;
}
return ListSequence.fromList(result).count() < maxErrors;
}
});
pm.advance(1);
if (ListSequence.fromList(result).count() >= maxErrors) {
pm.done();
return result;
}
}
}
pm.done();
return result;
}
private static Collection<DependencyProblem> findBadModules(Iterable<SModule> modules, int maxErrors) {
final List<DependencyProblem> rv = ListSequence.fromList(new ArrayList<DependencyProblem>());
Sequence.fromIterable(modules).ofType(ReloadableModule.class).where(new IWhereFilter<ReloadableModule>() {
public boolean accept(ReloadableModule it) {
return ModuleClassLoaderSupport.canCreate(it);
}
}).visitAll(new IVisitor<ReloadableModule>() {
public void visit(final ReloadableModule module) {
Iterable<SDependency> deps = module.getDeclaredDependencies();
Sequence.fromIterable(deps).where(new IWhereFilter<SDependency>() {
public boolean accept(SDependency it) {
return it.getTarget() == null;
}
}).visitAll(new IVisitor<SDependency>() {
public void visit(SDependency dep) {
ListSequence.fromList(rv).addElement(new DependencyProblem(module, String.format("Unresolved dependency in module %s: Module %s not found in repository", module.getModuleName(), dep.getTargetModule().getModuleName())));
}
});
}
});
return ListSequence.fromList(rv).take(maxErrors).toListSequence();
}
}