static void highlightTodos(@NotNull PsiFile file, @NotNull CharSequence text, int startOffset, int endOffset, @NotNull ProgressIndicator progress, @NotNull ProperTextRange priorityRange, @NotNull Collection<HighlightInfo> insideResult, @NotNull Collection<HighlightInfo> outsideResult) { PsiTodoSearchHelper helper = PsiTodoSearchHelper.SERVICE.getInstance(file.getProject()); if (helper == null) return; TodoItem[] todoItems = helper.findTodoItems(file, startOffset, endOffset); if (todoItems.length == 0) return; for (TodoItem todoItem : todoItems) { progress.checkCanceled(); TextRange range = todoItem.getTextRange(); String description = text.subSequence(range.getStartOffset(), range.getEndOffset()).toString(); TextAttributes attributes = todoItem.getPattern().getAttributes().getTextAttributes(); HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.TODO).range(range); builder.textAttributes(attributes); builder.descriptionAndTooltip(description); HighlightInfo info = builder.createUnconditionally(); (priorityRange.containsRange(info.getStartOffset(), info.getEndOffset()) ? insideResult : outsideResult).add(info); } }
@Nullable @Override public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) { final TodoItem[] todoItems = PsiTodoSearchHelper.SERVICE.getInstance(file.getProject()).findTodoItems(file); final List<ProblemDescriptor> result = new ArrayList<ProblemDescriptor>(); final THashSet<PsiComment> comments = new THashSet<PsiComment>(); for (TodoItem todoItem : todoItems) { final PsiComment comment = PsiTreeUtil.getParentOfType(file.findElementAt(todoItem.getTextRange().getStartOffset()), PsiComment.class, false); if (comment != null && comments.add(comment)) { result.add(manager.createProblemDescriptor(comment, InspectionsBundle.message("todo.comment.problem.descriptor"), isOnTheFly, null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)); } } return result.toArray(new ProblemDescriptor[result.size()]); }
private Collection<AbstractTreeNode> createListForSingleFile() { PsiFile psiFile = getValue(); TodoItem[] items= findAllTodos(psiFile, myBuilder.getTodoTreeStructure().getSearchHelper()); ArrayList<AbstractTreeNode> children=new ArrayList<AbstractTreeNode>(items.length); Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); if (document != null) { for (TodoItem todoItem : items) { if (todoItem.getTextRange().getEndOffset() < document.getTextLength() + 1) { SmartTodoItemPointer pointer = new SmartTodoItemPointer(todoItem, document); TodoFilter toDoFilter = getToDoFilter(); if (toDoFilter != null) { TodoItemNode itemNode = new TodoItemNode(getProject(), pointer, myBuilder); if (toDoFilter.contains(todoItem.getPattern())) { children.add(itemNode); } } else { children.add(new TodoItemNode(getProject(), pointer, myBuilder)); } } } } Collections.sort(children, SmartTodoItemPointerComparator.ourInstance); return children; }
public static TodoItem[] findAllTodos(final PsiFile psiFile, final PsiTodoSearchHelper helper) { final List<TodoItem> todoItems = new ArrayList<TodoItem>(Arrays.asList(helper.findTodoItems(psiFile))); psiFile.accept(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if (element instanceof PsiLanguageInjectionHost) { InjectedLanguageUtil.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { if (places.size() == 1) { Document document = PsiDocumentManager.getInstance(injectedPsi.getProject()).getCachedDocument(injectedPsi); if (!(document instanceof DocumentWindow)) return; for (TodoItem item : helper.findTodoItems(injectedPsi)) { TextRange rangeInHost = ((DocumentWindow)document).injectedToHost(item.getTextRange()); todoItems.add(new TodoItemImpl(psiFile, rangeInHost.getStartOffset(), rangeInHost.getEndOffset(), item.getPattern())); } } } }); } super.visitElement(element); } }); return todoItems.toArray(new TodoItem[todoItems.size()]); }
private Collection<AbstractTreeNode> createGeneralList() { ArrayList<AbstractTreeNode> children = new ArrayList<AbstractTreeNode>(); PsiFile psiFile = getValue(); final TodoItem[] items = findAllTodos(psiFile, myBuilder.getTodoTreeStructure().getSearchHelper()); final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile); if (document != null) { for (final TodoItem todoItem : items) { if (todoItem.getTextRange().getEndOffset() < document.getTextLength() + 1) { final SmartTodoItemPointer pointer = new SmartTodoItemPointer(todoItem, document); TodoFilter todoFilter = getToDoFilter(); if (todoFilter != null) { if (todoFilter.contains(todoItem.getPattern())) { children.add(new TodoItemNode(getProject(), pointer, myBuilder)); } } else { children.add(new TodoItemNode(getProject(), pointer, myBuilder)); } } } } Collections.sort(children, SmartTodoItemPointerComparator.ourInstance); return children; }
static void highlightTodos(@Nonnull PsiFile file, @Nonnull CharSequence text, int startOffset, int endOffset, @Nonnull ProgressIndicator progress, @Nonnull ProperTextRange priorityRange, @Nonnull Collection<HighlightInfo> insideResult, @Nonnull Collection<HighlightInfo> outsideResult) { PsiTodoSearchHelper helper = PsiTodoSearchHelper.getInstance(file.getProject()); if (helper == null || !shouldHighlightTodos(helper, file)) return; TodoItem[] todoItems = helper.findTodoItems(file, startOffset, endOffset); if (todoItems.length == 0) return; for (TodoItem todoItem : todoItems) { ProgressManager.checkCanceled(); TextRange range = todoItem.getTextRange(); TextAttributes attributes = todoItem.getPattern().getAttributes().getTextAttributes(); HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.TODO).range(range); builder.textAttributes(attributes); String description = text.subSequence(range.getStartOffset(), range.getEndOffset()).toString(); builder.description(description); builder.unescapedToolTip(StringUtil.shortenPathWithEllipsis(description, 1024)); HighlightInfo info = builder.createUnconditionally(); (priorityRange.containsRange(info.getStartOffset(), info.getEndOffset()) ? insideResult : outsideResult).add(info); } }
public static TodoItem[] findAllTodos(final PsiFile psiFile, final PsiTodoSearchHelper helper) { final List<TodoItem> todoItems = new ArrayList<TodoItem>(Arrays.asList(helper.findTodoItems(psiFile))); psiFile.accept(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if (element instanceof PsiLanguageInjectionHost) { InjectedLanguageUtil.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit(@Nonnull PsiFile injectedPsi, @Nonnull List<PsiLanguageInjectionHost.Shred> places) { if (places.size() == 1) { Document document = PsiDocumentManager.getInstance(injectedPsi.getProject()).getCachedDocument(injectedPsi); if (!(document instanceof DocumentWindow)) return; for (TodoItem item : helper.findTodoItems(injectedPsi)) { TextRange rangeInHost = ((DocumentWindow)document).injectedToHost(item.getTextRange()); todoItems.add(new TodoItemImpl(psiFile, rangeInHost.getStartOffset(), rangeInHost.getEndOffset(), item.getPattern())); } } } }); } super.visitElement(element); } }); return todoItems.toArray(new TodoItem[todoItems.size()]); }
@Override @NotNull public TodoItem[] findTodoItems(@NotNull PsiFile file, int startOffset, int endOffset) { final Collection<IndexPatternOccurrence> occurrences = IndexPatternSearch.search(file, TodoIndexPatternProvider.getInstance()).findAll(); if (occurrences.isEmpty()) { return EMPTY_TODO_ITEMS; } return processTodoOccurences(startOffset, endOffset, occurrences); }
@NotNull private static TodoItem[] processTodoOccurences(int startOffset, int endOffset, Collection<IndexPatternOccurrence> occurrences) { List<TodoItem> items = new ArrayList<TodoItem>(occurrences.size()); TextRange textRange = new TextRange(startOffset, endOffset); final TodoItemsCreator todoItemsCreator = new TodoItemsCreator(); for(IndexPatternOccurrence occurrence: occurrences) { TextRange occurrenceRange = occurrence.getTextRange(); if (textRange.contains(occurrenceRange)) { items.add(todoItemsCreator.createTodo(occurrence)); } } return items.toArray(new TodoItem[items.size()]); }
@NotNull @Override public TodoItem[] findTodoItemsLight(@NotNull PsiFile file, int startOffset, int endOffset) { final Collection<IndexPatternOccurrence> occurrences = LightIndexPatternSearch.SEARCH.createQuery(new IndexPatternSearch.SearchParameters(file, TodoIndexPatternProvider.getInstance())).findAll(); if (occurrences.isEmpty()) { return EMPTY_TODO_ITEMS; } return processTodoOccurences(startOffset, endOffset, occurrences); }
@Override public int getTodoItemsCount(@NotNull PsiFile file, @NotNull TodoPattern pattern) { int count = TodoCacheManager.SERVICE.getInstance(myManager.getProject()).getTodoCount(file.getVirtualFile(), pattern.getIndexPattern()); if (count != -1) return count; TodoItem[] items = findTodoItems(file); count = 0; for (TodoItem item : items) { if (item.getPattern().equals(pattern)) count++; } return count; }
@Override protected TodoItemData[] getTodoItems() { final TodoItemData[] items = (TodoItemData[])myGetter.get(); if (items != null) return items; final TodoItem[] todoItems = getTodoForText(PsiTodoSearchHelper.SERVICE.getInstance(myProject)); if (todoItems != null) { final TodoItemData[] arr = convertTodo(todoItems); mySaver.consume(arr); return arr; } return null; }
public static TodoItemData[] convertTodo(TodoItem[] todoItems) { final List<TodoItemData> list = new ArrayList<TodoItemData>(); for (TodoItem item : todoItems) { final TextRange range = item.getTextRange(); final TodoItemData data = new TodoItemData(range.getStartOffset(), range.getEndOffset(), item.getPattern()); list.add(data); } return list.toArray(new TodoItemData[list.size()]); }
protected TodoItem[] getTodoForText(PsiTodoSearchHelper helper) { final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() { @Override public PsiFile compute() { return PsiFileFactory.getInstance(myProject).createFileFromText((myOldRevision ? "old" : "") + myFileName, myFileType, myText); } }); return helper.findTodoItemsLight(psiFile); }
public TodoCheckinHandlerWorker(final Project project, final Collection<Change> changes, final TodoFilter todoFilter, final boolean includePattern) { this.changes = changes; myTodoFilter = todoFilter; myIncludePattern = includePattern; myPsiManager = PsiManager.getInstance(project); mySearchHelper = PsiTodoSearchHelper.SERVICE.getInstance(project); myAddedOrEditedTodos = new ArrayList<TodoItem>(); myInChangedTodos = new ArrayList<TodoItem>(); mySkipped = new SmartList<Pair<FilePath,String>>(); myEditedFileProcessor = new MyEditedFileProcessor(project, new Acceptor() { @Override public void skipped(Pair<FilePath, String> pair) { mySkipped.add(pair); } @Override public void addedOrEdited(TodoItem todoItem) { myAddedOrEditedTodos.add(todoItem); } @Override public void inChanged(TodoItem todoItem) { myInChangedTodos.add(todoItem); } }, myTodoFilter); }
public void execute() { for (Change change : changes) { ProgressManager.checkCanceled(); if (change.getAfterRevision() == null) continue; final VirtualFile afterFile = getFileWithRefresh(change.getAfterRevision().getFile()); if (afterFile == null || afterFile.isDirectory() || afterFile.getFileType().isBinary()) continue; myPsiFile = null; if (afterFile.isValid()) { myPsiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() { @Override public PsiFile compute() { return myPsiManager.findFile(afterFile); } }); } if (myPsiFile == null) { mySkipped.add(Pair.create(change.getAfterRevision().getFile(), ourInvalidFile)); continue; } myNewTodoItems = new ArrayList<TodoItem>(Arrays.asList( ApplicationManager.getApplication().runReadAction(new Computable<TodoItem[]>() { @Override public TodoItem[] compute() { return mySearchHelper.findTodoItems(myPsiFile); } }))); applyFilterAndRemoveDuplicates(myNewTodoItems, myTodoFilter); if (change.getBeforeRevision() == null) { // take just all todos if (myNewTodoItems.isEmpty()) continue; myAddedOrEditedTodos.addAll(myNewTodoItems); } else { myEditedFileProcessor.process(change, myNewTodoItems); } } }
private static void applyFilterAndRemoveDuplicates(final List<TodoItem> todoItems, final TodoFilter filter) { TodoItem previous = null; for (Iterator<TodoItem> iterator = todoItems.iterator(); iterator.hasNext(); ) { final TodoItem next = iterator.next(); if (filter != null && ! filter.contains(next.getPattern())) { iterator.remove(); continue; } if (previous != null && next.getTextRange().equals(previous.getTextRange())) { iterator.remove(); } else { previous = next; } } }
public CustomChangelistTodosTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project, final String title, final List<TodoItem> list) { super(tree, treeModel, project); myProject = project; myTitle = title; myMap = new MultiMap<PsiFile, TodoItem>(); myIncludedFiles = new HashSet<PsiFile>(); myChangeListManager = ChangeListManager.getInstance(myProject); initMap(list); initHelper(); }
private static void highlightTodos(@NotNull PsiFile file, @NotNull CharSequence text, int startOffset, int endOffset, @NotNull ProgressIndicator progress, @NotNull ProperTextRange priorityRange, @NotNull Collection<HighlightInfo> result, @NotNull Collection<HighlightInfo> outsideResult) { PsiTodoSearchHelper helper = PsiTodoSearchHelper.SERVICE.getInstance(file.getProject()); TodoItem[] todoItems = helper.findTodoItems(file, startOffset, endOffset); if (todoItems.length == 0) return; for (TodoItem todoItem : todoItems) { progress.checkCanceled(); TextRange range = todoItem.getTextRange(); String description = text.subSequence(range.getStartOffset(), range.getEndOffset()).toString(); TextAttributes attributes = todoItem.getPattern().getAttributes().getTextAttributes(); HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.TODO).range(range); if (attributes != null) { builder.textAttributes(attributes); } builder.descriptionAndTooltip(description); HighlightInfo info = builder.createUnconditionally(); if (priorityRange.containsRange(info.getStartOffset(), info.getEndOffset())) { result.add(info); } else { outsideResult.add(info); } } }
public void execute() { for (Change change : changes) { ProgressManager.checkCanceled(); if (change.getAfterRevision() == null) continue; VirtualFile afterFile = change.getAfterRevision().getFile().getVirtualFile(); if (afterFile == null) { afterFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(change.getAfterRevision().getFile().getIOFile()); } if (afterFile == null || afterFile.isDirectory() || afterFile.getFileType().isBinary()) continue; myPsiFile = null; if (afterFile.isValid()) { myPsiFile = myPsiManager.findFile(afterFile); } if (myPsiFile == null) { mySkipped.add(new Pair<FilePath, String>(change.getAfterRevision().getFile(), ourInvalidFile)); continue; } myNewTodoItems = new ArrayList<TodoItem>(Arrays.asList(mySearchHelper.findTodoItems(myPsiFile))); applyFilterAndRemoveDuplicates(myNewTodoItems, myTodoFilter); if (change.getBeforeRevision() == null) { // take just all todos if (myNewTodoItems.isEmpty()) continue; myAddedOrEditedTodos.addAll(myNewTodoItems); } else { myEditedFileProcessor.process(change, myNewTodoItems); } } }
private TodoItem[] processTodoOccurences(int startOffset, int endOffset, Collection<IndexPatternOccurrence> occurrences) { List<TodoItem> items = new ArrayList<TodoItem>(occurrences.size()); TextRange textRange = new TextRange(startOffset, endOffset); final TodoItemsCreator todoItemsCreator = new TodoItemsCreator(); for(IndexPatternOccurrence occurrence: occurrences) { TextRange occurrenceRange = occurrence.getTextRange(); if (textRange.contains(occurrenceRange)) { items.add(todoItemsCreator.createTodo(occurrence)); } } return items.toArray(new TodoItem[items.size()]); }
public static boolean isTodoComment(PsiComment comment) { final PsiFile file = comment.getContainingFile(); final PsiTodoSearchHelper searchHelper = PsiTodoSearchHelper.SERVICE.getInstance(comment.getProject()); final TodoItem[] todoItems = searchHelper.findTodoItems(file); for (final TodoItem todoItem : todoItems) { final TextRange commentTextRange = comment.getTextRange(); final TextRange todoTextRange = todoItem.getTextRange(); if (commentTextRange.contains(todoTextRange)) { return true; } } return false; }
@Override @Nonnull public TodoItem[] findTodoItems(@Nonnull PsiFile file, int startOffset, int endOffset) { final Collection<IndexPatternOccurrence> occurrences = IndexPatternSearch.search(file, TodoIndexPatternProvider.getInstance()).findAll(); if (occurrences.isEmpty()) { return EMPTY_TODO_ITEMS; } return processTodoOccurences(startOffset, endOffset, occurrences); }
@Nonnull private static TodoItem[] processTodoOccurences(int startOffset, int endOffset, Collection<IndexPatternOccurrence> occurrences) { List<TodoItem> items = new ArrayList<>(occurrences.size()); TextRange textRange = new TextRange(startOffset, endOffset); final TodoItemsCreator todoItemsCreator = new TodoItemsCreator(); for(IndexPatternOccurrence occurrence: occurrences) { TextRange occurrenceRange = occurrence.getTextRange(); if (textRange.contains(occurrenceRange)) { items.add(todoItemsCreator.createTodo(occurrence)); } } return items.toArray(new TodoItem[items.size()]); }
@Nonnull @Override public TodoItem[] findTodoItemsLight(@Nonnull PsiFile file, int startOffset, int endOffset) { final Collection<IndexPatternOccurrence> occurrences = LightIndexPatternSearch.SEARCH.createQuery(new IndexPatternSearch.SearchParameters(file, TodoIndexPatternProvider.getInstance())).findAll(); if (occurrences.isEmpty()) { return EMPTY_TODO_ITEMS; } return processTodoOccurences(startOffset, endOffset, occurrences); }
@Override public int getTodoItemsCount(@Nonnull PsiFile file, @Nonnull TodoPattern pattern) { int count = TodoCacheManager.getInstance(myManager.getProject()).getTodoCount(file.getVirtualFile(), pattern.getIndexPattern()); if (count != -1) return count; TodoItem[] items = findTodoItems(file); count = 0; for (TodoItem item : items) { if (item.getPattern().equals(pattern)) count++; } return count; }