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(); } }