private IntersectionScope( @NotNull GlobalSearchScope scope1, @NotNull GlobalSearchScope scope2, String displayName) { super(scope1.getProject() == null ? scope2.getProject() : scope1.getProject()); myScope1 = scope1; myScope2 = scope2; myDisplayName = displayName; }
@Nullable private HyperlinkInfo createHyperlinkInfo(@NotNull String line) { Project project = searchScope.getProject(); if (project == null) return null; StackTraceElement element = parseStackTraceLine(line); if (element == null) return null; // All true classes should be handled correctly in the default ExceptionFilter. Special cases: // - static facades; // - package facades / package parts (generated by pre-M13 compiled); // - local classes (and closures) in top-level function and property declarations. String fileName = element.getFileName(); // fullyQualifiedName is of format "package.Class$Inner" String fullyQualifiedName = element.getClassName(); int lineNumber = element.getLineNumber() - 1; String internalName = fullyQualifiedName.replace('.', '/'); JvmClassName jvmClassName = JvmClassName.byInternalName(internalName); JetFile file = DebuggerUtils.findSourceFileForClass(project, searchScope, jvmClassName, fileName); if (file == null) return null; VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) return null; return new OpenFileHyperlinkInfo(project, virtualFile, lineNumber); }
@Nullable private LocalSearchScope tryIntersectNonPhysicalWith(@NotNull GlobalSearchScope scope) { Project project = scope.getProject(); for (PsiElement element : myScope) { PsiFile containingFile = element.getContainingFile(); if (containingFile == null) continue; if (containingFile.getViewProvider().isPhysical()) return null; if (project != null && project != containingFile.getProject()) { return EMPTY; } } return this; }
@Override public void processQuery( @NotNull SearchParameters queryParameters, @NotNull final Processor<PsiReference> consumer) { if (!(queryParameters.getEffectiveSearchScope() instanceof GlobalSearchScope)) { return; } final GlobalSearchScope scope = (GlobalSearchScope) queryParameters.getEffectiveSearchScope(); final PsiElement target = queryParameters.getElementToSearch(); // Only class names can be prefixes in foreign ids of other nodes if (!(target instanceof PsiClass)) return; final SRepository repository = ProjectHelper.getProjectRepository(scope.getProject()); if (repository == null) { return; } repository .getModelAccess() .runReadAction( new Runnable() { @Override public void run() { final NodePtr nodePtr = JavaForeignIdBuilder.computeNodePtr(target); if (nodePtr == null) return; final SNodeReference mpsTarget = new SNodePointer(nodePtr.getSModelReference(), nodePtr.getNodeId()); // do we have this node? if (mpsTarget.resolve(MPSModuleRepository.getInstance()) == null) return; String prefix = nodePtr.getNodeId().toString(); final String prefixToSearch = (prefix.startsWith(Foreign.ID_PREFIX) ? prefix.substring(1) : prefix); final String prefixToSearchWithDot = prefixToSearch + "."; final Project project = target.getProject(); // first look into changed models SearchScope mpsSearchScope = new IdeaSearchScope(scope, true); CollectConsumer<VirtualFile> processedFilesConsumer = new CollectConsumer<VirtualFile>(); for (SModel model : mpsSearchScope.getModels()) { boolean changed = model instanceof EditableSModel && ((EditableSModel) model).isChanged(); if (!changed) continue; findInModel( model, prefixToSearch, processedFilesConsumer, new Consumer<SReference>() { @Override public void consume(SReference ref) { String role = ref.getRole(); SNode source = ref.getSourceNode(); PsiElement psiNode = MPSPsiProvider.getInstance(project).getPsi(source.getReference()); assert psiNode instanceof MPSPsiNode; consumer.process(new IdPrefixReference(mpsTarget, role, psiNode)); } }); } // now index final Collection<VirtualFile> filesOfChangedModels = processedFilesConsumer.getResult(); GlobalSearchScope truncatedScope = new DelegatingGlobalSearchScope(scope) { @Override public boolean contains(VirtualFile file) { if (filesOfChangedModels.contains(file)) return false; return super.contains(file); } }; ValueProcessor<Collection<Pair<SNodeDescriptor, String>>> sReferenceProcessor = new ValueProcessor<Collection<Pair<SNodeDescriptor, String>>>() { @Override public boolean process( VirtualFile file, Collection<Pair<SNodeDescriptor, String>> refs) { for (Pair<SNodeDescriptor, String> ref : refs) { SNodeReference nodeRef = ref.o1.getNodeReference(); String role = ref.o2; // index got out-of-date on this // unfortunately our indices are not always up-to-date, as we don't index // yet-unsaved changes if (nodeRef.resolve(repository) == null) continue; PsiElement psiNode = MPSPsiProvider.getInstance(project).getPsi(nodeRef); // original node came from MPS index, it must be converted to our PSI // element assert psiNode instanceof MPSPsiNode; consumer.process(new IdPrefixReference(mpsTarget, role, psiNode)); } return true; } }; FileBasedIndex.getInstance() .processValues( ForeignIdReferenceIndex.ID, prefixToSearchWithDot, null, sReferenceProcessor, truncatedScope); } }); }
@Override @NotNull public Filter create(@NotNull GlobalSearchScope searchScope) { return new GoExceptionFilter(searchScope.getProject()); }