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