@Override public void findUsages( Collection<SModel> scope, Set<SNode> nodes, Consumer<SReference> consumer, Consumer<SModel> processedConsumer) { MultiMap<SModel, SNode> candidates = findCandidates(scope, nodes, processedConsumer, key -> new NodeUse(key.getNodeId())); for (Entry<SModel, Collection<SNode>> candidate : candidates.entrySet()) { new NodeUsageFinder(candidate.getValue(), consumer).collectUsages(candidate.getKey()); } }
@Override public void findModelUsages( Collection<SModel> scope, Set<SModelReference> modelReferences, Consumer<SModel> consumer, Consumer<SModel> processedConsumer) { MultiMap<SModel, SModelReference> candidates = findCandidates(scope, modelReferences, processedConsumer, key -> new ModelUse(key)); for (Entry<SModel, Collection<SModelReference>> candidate : candidates.entrySet()) { if (FindUsagesUtil.hasModelUsages(candidate.getKey(), candidate.getValue())) { consumer.consume(candidate.getKey()); } } }
@Override public void findInstances( Collection<SModel> scope, Set<SAbstractConcept> concepts, Consumer<SNode> consumer, Consumer<SModel> processedConsumer) { MultiMap<SModel, SAbstractConcept> candidates = findCandidates( scope, concepts, processedConsumer, key -> new ConceptInstance(MetaIdHelper.getConcept(key))); for (Entry<SModel, Collection<SAbstractConcept>> candidate : candidates.entrySet()) { FindUsagesUtil.collectInstances(candidate.getKey(), candidate.getValue(), consumer); } }
private <T> MultiMap<SModel, T> findCandidates( Collection<SModel> models, Set<T> elems, Consumer<SModel> processedModels, Function<T, UsageEntry> id) { // get all files in scope final ManyToManyMap<SModel, VirtualFile> scopeFiles = new ManyToManyMap<SModel, VirtualFile>(); for (final SModel sm : models) { if (sm instanceof EditableSModel && ((EditableSModel) sm).isChanged()) { continue; } DataSource source = sm.getSource(); // these are data sources this participant knows about if (!(source instanceof FileDataSource || source instanceof FilePerRootDataSource)) { continue; } /* This is a tmp fix for MPS-24151. See the issue to learn about the correct fix */ if (!(sm instanceof DefaultSModelDescriptor)) { continue; } Collection<IFile> modelFiles = getDataSourceFiles(source); for (IFile modelFile : modelFiles) { String ext = FileUtil.getExtension(modelFile.getName()); if (ext == null || modelFile.isDirectory()) { continue; } VirtualFile vf = VirtualFileUtils.getOrCreateVirtualFile(modelFile); if (vf == null) { LogManager.getLogger(MPSModelsFastFindSupport.class) .warn( String.format( "Model %s: virtual file not found for model file. Model file: %s", sm.getName(), modelFile.getPath())); continue; } processedModels.consume(sm); scopeFiles.addLink(sm, vf); } } // filter files with usages ConcreteFilesGlobalSearchScope allFiles = new ConcreteFilesGlobalSearchScope(scopeFiles.getSecond()); // process indexes MultiMap<SModel, T> result = new SetBasedMultiMap<SModel, T>(); for (T elem : elems) { UsageEntry entry = id.apply(elem); Collection<VirtualFile> matchingFiles; try { matchingFiles = MPSModelsIndexer.getContainingFiles(entry, allFiles); } catch (ProcessCanceledException ce) { matchingFiles = Collections.emptyList(); } // back-transform for (VirtualFile file : matchingFiles) { for (SModel m : scopeFiles.getBySecond(file)) { result.putValue(m, elem); } } } return result; }