package jetbrains.mps.ide.ui.finders; /*Generated by MPS */ import jetbrains.mps.ide.findusages.findalgorithm.finders.BaseFinder; import jetbrains.mps.ide.findusages.findalgorithm.finders.IFinder; import jetbrains.mps.ide.findusages.model.SearchResults; import jetbrains.mps.ide.findusages.model.SearchQuery; import org.jetbrains.mps.openapi.util.ProgressMonitor; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.module.SearchScope; import org.jetbrains.mps.openapi.module.SModule; import jetbrains.mps.project.Solution; import jetbrains.mps.smodel.Language; import jetbrains.mps.smodel.Generator; import jetbrains.mps.project.DevKit; import jetbrains.mps.ide.findusages.model.SearchResult; import jetbrains.mps.smodel.adapter.MetaAdapterByDeclaration; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.smodel.SModelStereotype; import jetbrains.mps.smodel.SModelOperations; /** * Look up language uses in scope module's imports and their models. * Name of the class might not be precise (yet - if we decide to split look up in imports and in models). * SearchResult include both modules and models. * * Note, this finder looks up SLanguage, not a Language module uses, thus it shall not be used when * we care about module dependencies. * * Unlike {@link jetbrains.mps.ide.ui.finders.LanguageModelImportFinder }, this finder focuses on modules. I'm not confident we need * both finders, though. * * FIXME perhaps, shall either use LanguageUsageFinder for uses in models (i.e. build another scope from caller and pass to LUF), or * shall respect scope's models here (not only/in addition to models of scope modules). Note, LUF looks up nodes, while this shall stop at model's level. */ public class LanguageImportFinder extends BaseFinder implements IFinder { private static final String MODELS_WRITTEN_IN_LANGUAGE = "models written in language"; private static final String EXPORTED_BY = "exported by"; public LanguageImportFinder() { } @Override public String getDescription() { return "Language Imports"; } @Override public SearchResults find(SearchQuery query, ProgressMonitor monitor) { SearchResults searchResults = new SearchResults(); for (SLanguage lang : LanguageUsagesFinder.getLanguageToLookUp(query)) { searchResults.getSearchedNodes().add(lang); SearchScope scope = query.getScope(); for (SModule module : scope.getModules()) { if (monitor.isCanceled()) { return searchResults; } if (module instanceof Solution) { collectUsagesInSolution(lang, (Solution) module, searchResults); } if (module instanceof Language) { collectUsagesInLanguage(lang, (Language) module, searchResults); for (Generator g : ((Language) module).getGenerators()) { collectUsagesInGenerator(lang, g, searchResults); } } if (module instanceof DevKit) { collectUsagesInDevKit(lang, (DevKit) module, searchResults); } } } return searchResults; } /*package*/ void collectUsagesInSolution(SLanguage searchLanguage, Solution solution, SearchResults searchResults) { if (solution.getUsedLanguages().contains(searchLanguage)) { searchResults.add(new SearchResult<Solution>(solution, ModuleUsagesFinder.USED_BY)); collectUsagesInModels(searchLanguage, solution, searchResults); } } /*package*/ void collectUsagesInLanguage(SLanguage searchedLanguage, Language language, SearchResults searchResults) { if (language.getUsedLanguages().contains(searchedLanguage)) { searchResults.add(new SearchResult<Language>(language, ModuleUsagesFinder.USED_BY)); collectUsagesInModels(searchedLanguage, language, searchResults); } } /*package*/ void collectUsagesInGenerator(SLanguage searchedLanguage, Generator generator, SearchResults searchResults) { if (generator.getUsedLanguages().contains(searchedLanguage)) { searchResults.add(new SearchResult<Generator>(generator, ModuleUsagesFinder.USED_BY)); collectUsagesInModels(searchedLanguage, generator, searchResults); } } /*package*/ void collectUsagesInDevKit(SLanguage searchLanguage, DevKit devKit, SearchResults searchResults) { if (searchLanguage == null) { return; } for (Language l : devKit.getExportedLanguages()) { if (searchLanguage.equals(MetaAdapterByDeclaration.getLanguage(l))) { searchResults.add(new SearchResult<DevKit>(devKit, EXPORTED_BY)); break; } } } /*package*/ void collectUsagesInModels(SLanguage searchedLanguage, SModule owner, SearchResults searchResults) { for (SModel model : owner.getModels()) { if (!(SModelStereotype.isUserModel(model))) { continue; } // FIXME rest of the class relies on plain (no unwraped devkits and extended languages) imports, // perhaps, shall revert to SModel.getUsedLanguages() here as well? if (SModelOperations.getAllLanguageImports(model).contains(searchedLanguage)) { searchResults.add(new SearchResult<SModel>(model, MODELS_WRITTEN_IN_LANGUAGE)); } } } }