package jetbrains.mps.ide.modelchecker.platform.actions; /*Generated by MPS */ import jetbrains.mps.ide.findusages.findalgorithm.finders.BaseFinder; import java.util.List; import java.util.Arrays; import jetbrains.mps.ide.findusages.model.SearchResults; import jetbrains.mps.ide.findusages.model.SearchQuery; import org.jetbrains.mps.openapi.util.ProgressMonitor; import jetbrains.mps.internal.collections.runtime.ListSequence; import org.jetbrains.mps.openapi.module.SModule; import org.jetbrains.mps.openapi.util.SubProgressKind; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.ide.findusages.model.SearchResult; import java.util.ArrayList; import jetbrains.mps.checkers.ErrorReportUtil; import jetbrains.mps.internal.collections.runtime.IVisitor; import jetbrains.mps.ide.findusages.model.holders.IHolder; import org.jetbrains.mps.openapi.module.SearchScope; import jetbrains.mps.ide.findusages.model.holders.ModelsHolder; import org.jetbrains.mps.openapi.model.SModelReference; import org.jetbrains.mps.openapi.module.SModuleReference; public class ModelCheckerIssueFinder extends BaseFinder { private final List<SpecificChecker> myExtraCheckers; public ModelCheckerIssueFinder(List<SpecificChecker> extraCheckers) { myExtraCheckers = extraCheckers; } public ModelCheckerIssueFinder(SpecificChecker... extraCheckers) { this(Arrays.asList(extraCheckers)); } protected final List<SpecificChecker> getSpecificCheckers() { return myExtraCheckers; } @Override public SearchResults<ModelCheckerIssue> find(SearchQuery searchQuery, ProgressMonitor monitor) { ModelCheckerIssueFinder.ItemsToCheck itemsToCheck = getItemsToCheck(searchQuery); int work = ListSequence.fromList(itemsToCheck.modules).count() + ListSequence.fromList(itemsToCheck.models).count() + 1; monitor.start("Checking", work); try { final SearchResults<ModelCheckerIssue> rv = new SearchResults<ModelCheckerIssue>(); ModuleChecker moduleChecker = new ModuleChecker(); for (SModule module : ListSequence.fromList(itemsToCheck.modules)) { moduleChecker.checkModule(module, monitor.subTask(1, SubProgressKind.REPLACING)); if (monitor.isCanceled()) { break; } } rv.addAll(moduleChecker.getSearchResults()); ModelChecker modelChecker = new ModelChecker(getSpecificCheckers()); for (SModel modelDescriptor : ListSequence.fromList(itemsToCheck.models)) { modelChecker.checkModel(modelDescriptor, monitor.subTask(1, SubProgressKind.REPLACING)); if (monitor.isCanceled()) { break; } } rv.addAll(modelChecker.getSearchResults()); // filter out suppressed List<SearchResult<ModelCheckerIssue>> toRemove = ListSequence.fromList(new ArrayList<SearchResult<ModelCheckerIssue>>()); for (SearchResult<ModelCheckerIssue> result : ListSequence.fromList(rv.getSearchResults())) { if (result.getObject() instanceof ModelCheckerIssue.NodeIssue) { ModelCheckerIssue.NodeIssue mci = (ModelCheckerIssue.NodeIssue) result.getObject(); if (!(ErrorReportUtil.shouldReportError(mci.getNode()))) { ListSequence.fromList(toRemove).addElement(result); } } } ListSequence.fromList(toRemove).visitAll(new IVisitor<SearchResult<ModelCheckerIssue>>() { public void visit(SearchResult<ModelCheckerIssue> it) { rv.remove(it); } }); return rv; } finally { monitor.done(); } } private static class ItemsToCheck { public List<SModel> models = ListSequence.fromList(new ArrayList<SModel>()); public List<SModule> modules = ListSequence.fromList(new ArrayList<SModule>()); } private ModelCheckerIssueFinder.ItemsToCheck getItemsToCheck(SearchQuery searchQuery) { IHolder objectHolder = searchQuery.getObjectHolder(); final SearchScope scope = searchQuery.getScope(); ModelCheckerIssueFinder.ItemsToCheck itemsToCheck = new ModelCheckerIssueFinder.ItemsToCheck(); // FIXME IT'S PLAIN WRONG TO PASS SET OF MODELS/MODULES TO CHECK THROUGH IHolder. // SearchScope tells where to look for, SearchQuery.getObjectHolder tells what to look for // That's why I didn't change scope.resolve here to use query.getSearchObjectResolver()! if (objectHolder instanceof ModelsHolder) { ModelsHolder modelsHolder = (ModelsHolder) objectHolder; for (SModelReference ref : modelsHolder.getObject()) { SModel resolved = scope.resolve(ref); if (resolved != null) { ListSequence.fromList(itemsToCheck.models).addElement(resolved); } } } else if (objectHolder.getObject() instanceof SModuleReference) { SModuleReference mr = (SModuleReference) objectHolder.getObject(); SModule resolved = scope.resolve(mr); if (resolved != null) { ListSequence.fromList(itemsToCheck.modules).addElement(resolved); ListSequence.fromList(itemsToCheck.models).addSequence(ListSequence.fromList(ModelCheckerUtils.getModelDescriptors(resolved))); } } else if (objectHolder.getObject() instanceof SModelReference) { SModelReference mr = (SModelReference) objectHolder.getObject(); SModel resolved = scope.resolve(mr); if (resolved != null) { ListSequence.fromList(itemsToCheck.models).addElement(resolved); } } else { throw new IllegalArgumentException(); } return itemsToCheck; } }