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