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