package jetbrains.mps.ide.ui.finders;
/*Generated by MPS */
import jetbrains.mps.ide.findusages.findalgorithm.finders.BaseFinder;
import jetbrains.mps.ide.findusages.model.SearchResults;
import jetbrains.mps.ide.findusages.model.SearchQuery;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import java.util.HashSet;
import org.jetbrains.mps.openapi.language.SLanguage;
import java.util.Collection;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.util.IterableUtil;
import jetbrains.mps.smodel.SModelStereotype;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SNodeUtil;
import jetbrains.mps.ide.findusages.model.SearchResult;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.module.SModuleReference;
import java.util.Collections;
import jetbrains.mps.project.DevKit;
import java.util.ArrayList;
import jetbrains.mps.smodel.Language;
import jetbrains.mps.smodel.adapter.MetaAdapterByDeclaration;
/**
* Look up nodes of particular language in scope models.
* Exact language match, no extended/extending languages are considered.
* I.e. if there's a node A of L1, and we look up L2 which extends L1, node A won't be considered as 'use' of L2. Same for node B of L2, and a search of L1.
*/
public class LanguageUsagesFinder extends BaseFinder {
private static final String NODES_IN_LANGUAGE = "nodes written in language";
public LanguageUsagesFinder() {
}
@Override
public String getDescription() {
return "Language Usages";
}
@Override
public SearchResults find(SearchQuery query, ProgressMonitor monitor) {
SearchResults searchResults = new SearchResults();
HashSet<SLanguage> languages = new HashSet<SLanguage>(getLanguageToLookUp(query));
searchResults.getSearchedNodes().addAll(languages);
Collection<SModel> models = IterableUtil.asCollection(query.getScope().getModels());
monitor.start("Look up instances of language concepts", models.size());
for (SModel model : models) {
if (monitor.isCanceled()) {
return searchResults;
}
if (!(SModelStereotype.isUserModel(model))) {
continue;
}
for (SNode node : SNodeUtil.getDescendants(model)) {
if (languages.contains(node.getConcept().getLanguage())) {
searchResults.add(new SearchResult<SNode>(node, NODES_IN_LANGUAGE));
}
}
monitor.advance(1);
}
monitor.done();
return searchResults;
}
/*package*/ static Collection<SLanguage> getLanguageToLookUp(SearchQuery query) {
Object value = query.getObjectHolder().getObject();
SModule searchedModule;
if (value instanceof SModule) {
searchedModule = ((SModule) value);
} else if (value instanceof SModuleReference) {
searchedModule = query.getScope().resolve(((SModuleReference) value));
} else if (value instanceof SLanguage) {
return Collections.singletonList(((SLanguage) value));
} else {
return Collections.emptyList();
}
// FIXME likely it's smarter to unwrap devkit at the caller's, wrapped with CompositeFinder
if (searchedModule instanceof DevKit) {
ArrayList<SLanguage> rv = new ArrayList<SLanguage>();
rv.addAll(IterableUtil.asCollection(((DevKit) searchedModule).getAllExportedLanguageIds()));
return rv;
}
if (searchedModule instanceof Language) {
return Collections.singletonList(MetaAdapterByDeclaration.getLanguage((Language) searchedModule));
}
return Collections.emptyList();
}
}