static boolean processElementsAtOffsets(@Nonnull PsiElement scope, @Nonnull StringSearcher searcher, boolean processInjectedPsi, @Nonnull ProgressIndicator progress, int[] offsetsInScope, @Nonnull TextOccurenceProcessor processor) { if (offsetsInScope.length == 0) return true; Project project = scope.getProject(); TreeElement lastElement = null; for (int offset : offsetsInScope) { progress.checkCanceled(); lastElement = processTreeUp(project, processor, scope, searcher, offset, processInjectedPsi, progress, lastElement); if (lastElement == null) return false; } return true; }
private static Boolean processInjectedFile(PsiElement element, final TextOccurenceProcessor processor, final StringSearcher searcher, ProgressIndicator progress, InjectedLanguageManager injectedLanguageManager) { if (!(element instanceof PsiLanguageInjectionHost)) return null; if (injectedLanguageManager == null) return null; List<Pair<PsiElement,TextRange>> list = injectedLanguageManager.getInjectedPsiFiles(element); if (list == null) return null; for (Pair<PsiElement, TextRange> pair : list) { final PsiElement injected = pair.getFirst(); if (!processElementsContainingWordInElement(processor, injected, searcher, false, progress)) return Boolean.FALSE; } return Boolean.TRUE; }
public static boolean processElementsContainingWordInElement(@NotNull final TextOccurenceProcessor processor, @NotNull final PsiElement scope, @NotNull final StringSearcher searcher, final boolean processInjectedPsi, final ProgressIndicator progress) { if (progress != null) progress.checkCanceled(); PsiFile file = scope.getContainingFile(); FileViewProvider viewProvider = file.getViewProvider(); final CharSequence buffer = viewProvider.getContents(); TextRange range = scope.getTextRange(); if (range == null) { LOG.error("Element " + scope + " of class " + scope.getClass() + " has null range"); return true; } final int scopeStart = range.getStartOffset(); final int startOffset = scopeStart; int endOffset = range.getEndOffset(); if (endOffset > buffer.length()) { diagnoseInvalidRange(scope, file, viewProvider, buffer, range); return true; } final Project project = file.getProject(); final TreeElement[] lastElement = {null}; return processTextOccurrences(buffer, startOffset, endOffset, searcher, progress, new TIntProcedure() { @Override public boolean execute(int offset) { if (progress != null) progress.checkCanceled(); lastElement[0] = processTreeUp(project, processor, scope, searcher, offset - scopeStart, processInjectedPsi, progress, lastElement[0]); return lastElement[0] != null; } }); }
private static Set<String> calcDevPatternClassNames(@NotNull final Project project) { final List<String> roots = ContainerUtil.createLockFreeCopyOnWriteList(); JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); PsiClass beanClass = psiFacade.findClass(PatternClassBean.class.getName(), GlobalSearchScope.allScope(project)); if (beanClass != null) { GlobalSearchScope scope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), StdFileTypes.XML); final TextOccurenceProcessor occurenceProcessor = new TextOccurenceProcessor() { @Override public boolean execute(@NotNull PsiElement element, int offsetInElement) { XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class); String className = tag == null ? null : tag.getAttributeValue("className"); if (StringUtil.isNotEmpty(className) && tag.getLocalName().endsWith("patternClass")) { roots.add(className); } return true; } }; final StringSearcher searcher = new StringSearcher("patternClass", true, true); CacheManager.SERVICE.getInstance(beanClass.getProject()).processFilesWithWord(new Processor<PsiFile>() { @Override public boolean process(PsiFile psiFile) { LowLevelSearchUtil.processElementsContainingWordInElement(occurenceProcessor, psiFile, searcher, true, new EmptyProgressIndicator()); return true; } }, searcher.getPattern(), UsageSearchContext.IN_FOREIGN_LANGUAGES, scope, searcher.isCaseSensitive()); } return ContainerUtil.newHashSet(roots); }
public static boolean processElementsContainingWordInElement(@NotNull TextOccurenceProcessor processor, @NotNull final PsiElement scope, @NotNull StringSearcher searcher, final boolean processInjectedPsi, ProgressIndicator progress) { if (progress != null) progress.checkCanceled(); PsiFile file = scope.getContainingFile(); final CharSequence buffer = file.getViewProvider().getContents(); TextRange range = scope.getTextRange(); if (range == null) { throw new AssertionError("Element " + scope + " of class " + scope.getClass() + " has null range"); } int scopeStart = range.getStartOffset(); int startOffset = scopeStart; int endOffset = range.getEndOffset(); if (endOffset > buffer.length()) { LOG.error("Range for element: '"+scope+"' = "+range+" is out of file '" + file + "' range: " + file.getTextLength()); } final char[] bufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer); Project project = file.getProject(); do { if (progress != null) progress.checkCanceled(); startOffset = searchWord(buffer, bufferArray, startOffset, endOffset, searcher, progress); if (startOffset < 0) { return true; } if (!processTreeUp(project, processor, scope, searcher, startOffset - scopeStart, processInjectedPsi, progress)) return false; startOffset++; } while (startOffset < endOffset); return true; }
private static List<PsiElement> getRootsByClassNames(PsiFile file, String type) { final List<PsiElement> roots = ContainerUtil.createLockFreeCopyOnWriteList(); final Project project = file.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiClass beanClass = psiFacade.findClass(PatternClassBean.class.getName(), GlobalSearchScope.allScope(project)); if (beanClass != null) { final GlobalSearchScope scope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), StdFileTypes.XML); final TextOccurenceProcessor occurenceProcessor = new TextOccurenceProcessor() { @Override public boolean execute(PsiElement element, int offsetInElement) { final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class); final String className = tag == null ? null : tag.getAttributeValue("className"); if (className != null && tag.getLocalName().endsWith("patternClass")) { ContainerUtil.addIfNotNull(psiFacade.findClass(className, GlobalSearchScope.allScope(project)), roots); } return true; } }; final StringSearcher searcher = new StringSearcher("patternClass", true, true); CacheManager.SERVICE.getInstance(beanClass.getProject()).processFilesWithWord(new Processor<PsiFile>() { @Override public boolean process(PsiFile psiFile) { LowLevelSearchUtil .processElementsContainingWordInElement(occurenceProcessor, psiFile, searcher, true, new EmptyProgressIndicator()); return true; } }, searcher.getPattern(), UsageSearchContext.IN_FOREIGN_LANGUAGES, scope, searcher.isCaseSensitive()); } final Class[] classes = PatternCompilerFactory.getFactory().getPatternClasses(type); if (classes.length != 0) { roots.add(getRootByClasses(classes, project)); } return roots; }
private static Boolean processInjectedFile(PsiElement element, final TextOccurenceProcessor processor, final StringSearcher searcher, @Nonnull ProgressIndicator progress, InjectedLanguageManager injectedLanguageManager) { if (!(element instanceof PsiLanguageInjectionHost)) return null; if (injectedLanguageManager == null) return null; List<Pair<PsiElement, TextRange>> list = injectedLanguageManager.getInjectedPsiFiles(element); if (list == null) return null; for (Pair<PsiElement, TextRange> pair : list) { final PsiElement injected = pair.getFirst(); if (!processElementsContainingWordInElement(processor, injected, searcher, false, progress)) return Boolean.FALSE; } return Boolean.TRUE; }
@RequiredReadAction public static boolean processElementsContainingWordInElement(@Nonnull final TextOccurenceProcessor processor, @Nonnull final PsiElement scope, @Nonnull final StringSearcher searcher, boolean processInjectedPsi, @Nonnull ProgressIndicator progress) { int[] occurrences = getTextOccurrencesInScope(scope, searcher, progress); return processElementsAtOffsets(scope, searcher, processInjectedPsi, progress, occurrences, processor); }
private static boolean processIdentifiers(PsiSearchHelper helper, @NotNull final PsiElementProcessor<PsiIdentifier> processor, @NotNull final String identifier, @NotNull SearchScope searchScope, short searchContext) { TextOccurenceProcessor processor1 = new TextOccurenceProcessor() { public boolean execute(PsiElement element, int offsetInElement) { return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element); } }; return helper.processElementsWithWord(processor1, searchScope, identifier, searchContext, true); }
private static boolean processTreeUp(@NotNull Project project, @NotNull TextOccurenceProcessor processor, @NotNull PsiElement scope, @NotNull StringSearcher searcher, final int offset, final boolean processInjectedPsi, ProgressIndicator progress) { final int scopeStartOffset = scope.getTextRange().getStartOffset(); final int patternLength = searcher.getPatternLength(); ASTNode scopeNode = scope.getNode(); boolean useTree = scopeNode != null; assert scope.isValid(); int start; TreeElement leafNode = null; PsiElement leafElement = null; if (useTree) { leafNode = (LeafElement)scopeNode.findLeafElementAt(offset); if (leafNode == null) return true; start = offset - leafNode.getStartOffset() + scopeStartOffset; } else { if (scope instanceof PsiFile) { leafElement = ((PsiFile)scope).getViewProvider().findElementAt(offset, scope.getLanguage()); } else { leafElement = scope.findElementAt(offset); } if (leafElement == null) return true; assert leafElement.isValid(); start = offset - leafElement.getTextRange().getStartOffset() + scopeStartOffset; } if (start < 0) { LOG.error("offset=" + offset + " scopeStartOffset=" + scopeStartOffset + " leafElement=" + leafElement + " scope=" + scope); } boolean contains = false; PsiElement prev = null; TreeElement prevNode = null; PsiElement run = null; InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(project); while (run != scope) { if (progress != null) progress.checkCanceled(); if (useTree) { start += prevNode == null ? 0 : prevNode.getStartOffsetInParent(); prevNode = leafNode; run = leafNode.getPsi(); } else { start += prev == null ? 0 : prev.getStartOffsetInParent(); prev = run; run = leafElement; } if (!contains) contains = run.getTextLength() - start >= patternLength; //do not compute if already contains if (contains) { if (processInjectedPsi) { Boolean result = processInjectedFile(run, processor, searcher, progress, injectedLanguageManager); if (result != null) { return result.booleanValue(); } } if (!processor.execute(run, start)) { return false; } } if (useTree) { leafNode = leafNode.getTreeParent(); if (leafNode == null) break; } else { leafElement = leafElement.getParent(); if (leafElement == null) break; } } assert run == scope: "Malbuilt PSI: scopeNode="+scope+"; leafNode="+run+"; isAncestor="+ PsiTreeUtil.isAncestor(scope, run, false); return true; }
@Override public boolean execute(@NotNull final MethodReferencesSearch.SearchParameters parameters, @NotNull final Processor<PsiReference> consumer) { final PsiMethod method = parameters.getMethod(); final Ref<String> name = Ref.create(null); final Ref<Project> project = Ref.create(null); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { if(!method.isValid()) { return; } project.set(method.getProject()); name.set(VelocityNamingUtil.getPropertyNameFromAccessor(method)); } }); String nameRefValue = name.get(); if(StringUtil.isEmpty(nameRefValue)) { return true; } SearchScope searchScope = parameters.getScope(); if(searchScope instanceof GlobalSearchScope) { searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope) searchScope, VtlFileType.INSTANCE); } final TextOccurenceProcessor processor = new TextOccurenceProcessor() { @Override public boolean execute(PsiElement element, int offsetInElement) { final PsiReference[] refs = element.getReferences(); for(PsiReference ref : refs) { if(ref.getRangeInElement().contains(offsetInElement) && ref.isReferenceTo(method)) { return consumer.process(ref); } } return true; } }; final PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(project.get()); return helper.processElementsWithWord(processor, searchScope, nameRefValue, UsageSearchContext.IN_FOREIGN_LANGUAGES, false); }