private void doSetTodoPatterns(@NotNull TodoPattern[] todoPatterns, final boolean shouldNotifyIndices) { TodoPattern[] oldTodoPatterns = myTodoPatterns; IndexPattern[] oldIndexPatterns = myIndexPatterns; myTodoPatterns = todoPatterns; buildIndexPatterns(); // only trigger index refresh actual index patterns have changed if (shouldNotifyIndices && !Arrays.deepEquals(myIndexPatterns, oldIndexPatterns)) { final PropertyChangeEvent event = new PropertyChangeEvent(this, IndexPatternProvider.PROP_INDEX_PATTERNS, oldTodoPatterns, todoPatterns); myMessageBus.syncPublisher(IndexPatternProvider.INDEX_PATTERNS_CHANGED).propertyChange(event); } // only trigger gui and code daemon refresh when either the index patterns or presentation attributes have changed if (!Arrays.deepEquals(myTodoPatterns, oldTodoPatterns)) { final PropertyChangeListener multicaster = myPropertyChangeMulticaster.getMulticaster(); multicaster.propertyChange(new PropertyChangeEvent(this, PROP_TODO_PATTERNS, oldTodoPatterns, todoPatterns)); } }
@Override @Nonnull public PsiFile[] getFilesWithTodoItems() { if (myProject.isDefault()) { return PsiFile.EMPTY_ARRAY; } final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); final Set<PsiFile> allFiles = new HashSet<>(); final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final Collection<VirtualFile> files = fileBasedIndex.getContainingFiles( TodoIndex.NAME, new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), GlobalSearchScope.allScope(myProject)); ApplicationManager.getApplication().runReadAction(() -> { for (VirtualFile file : files) { if (projectFileIndex.isInContent(file)) { final PsiFile psiFile = myPsiManager.findFile(file); if (psiFile != null) { allFiles.add(psiFile); } } } }); } return allFiles.isEmpty() ? PsiFile.EMPTY_ARRAY : PsiUtilCore.toPsiFileArray(allFiles); }
protected static boolean executeImpl(IndexPatternSearch.SearchParameters queryParameters, Processor<IndexPatternOccurrence> consumer) { final IndexPatternProvider patternProvider = queryParameters.getPatternProvider(); final PsiFile file = queryParameters.getFile(); TIntArrayList commentStarts = new TIntArrayList(); TIntArrayList commentEnds = new TIntArrayList(); final CharSequence chars = file.getViewProvider().getContents(); findCommentTokenRanges(file, chars, queryParameters.getRange(), commentStarts, commentEnds); TIntArrayList occurrences = new TIntArrayList(1); IndexPattern[] patterns = patternProvider != null ? patternProvider.getIndexPatterns() : null; for (int i = 0; i < commentStarts.size(); i++) { int commentStart = commentStarts.get(i); int commentEnd = commentEnds.get(i); occurrences.resetQuick(); if (patternProvider != null) { for (int j = patterns.length - 1; j >=0; --j) { if (!collectPatternMatches(patterns[j], chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer, occurrences)) { return false; } } } else { if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer, occurrences)) { return false; } } } return true; }
private static boolean collectPatternMatches(IndexPattern indexPattern, CharSequence chars, int commentStart, int commentEnd, PsiFile file, TextRange range, Processor<IndexPatternOccurrence> consumer, TIntArrayList matches ) { Pattern pattern = indexPattern.getPattern(); if (pattern != null) { ProgressManager.checkCanceled(); CharSequence input = new CharSequenceSubSequence(chars, commentStart, commentEnd); Matcher matcher = pattern.matcher(input); while (true) { //long time1 = System.currentTimeMillis(); boolean found = matcher.find(); //long time2 = System.currentTimeMillis(); //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms")); if (!found) break; int start = matcher.start() + commentStart; int end = matcher.end() + commentStart; if (start != end) { if ((range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) && matches.indexOf(start) == -1) { matches.add(start); if (!consumer.process(new IndexPatternOccurrenceImpl(file, start, end, indexPattern))) { return false; } } } ProgressManager.checkCanceled(); } } return true; }
@NotNull private TodoPattern mapPattern(@NotNull IndexPattern pattern) { for(TodoPattern todoPattern: myTodoPatterns) { if (todoPattern.getIndexPattern() == pattern) { return todoPattern; } } LOG.error("Could not find matching TODO pattern for index pattern " + pattern.getPatternString()); return null; }
@Override @NotNull public PsiFile[] getFilesWithTodoItems() { if (myProject.isDefault()) { return PsiFile.EMPTY_ARRAY; } final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); final Set<PsiFile> allFiles = new HashSet<PsiFile>(); final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final Collection<VirtualFile> files = fileBasedIndex.getContainingFiles( TodoIndex.NAME, new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), GlobalSearchScope.allScope(myProject)); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { for (VirtualFile file : files) { if (projectFileIndex.isInContent(file)) { final PsiFile psiFile = myPsiManager.findFile(file); if (psiFile != null) { allFiles.add(psiFile); } } } } }); } return allFiles.isEmpty() ? PsiFile.EMPTY_ARRAY : PsiUtilCore.toPsiFileArray(allFiles); }
@Override public int getTodoCount(@NotNull final VirtualFile file, @NotNull final IndexPatternProvider patternProvider) { if (myProject.isDefault()) { return 0; } if (file instanceof VirtualFileWindow) return -1; final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); int count = 0; for (IndexPattern indexPattern : patternProvider.getIndexPatterns()) { count += fetchCount(fileBasedIndex, file, indexPattern); } return count; }
@Override public int getTodoCount(@NotNull final VirtualFile file, @NotNull final IndexPattern pattern) { if (myProject.isDefault()) { return 0; } if (file instanceof VirtualFileWindow) return -1; return fetchCount(FileBasedIndex.getInstance(), file, pattern); }
public static ScanContent scanContent(FileContent content, IdAndToDoScannerBasedOnFilterLexer indexer) { ScanContent data = content.getUserData(scanContentKey); if (data != null) { content.putUserData(scanContentKey, null); return data; } final boolean needTodo = content.getFile().isInLocalFileSystem(); // same as TodoIndex.getFilter().isAcceptable final boolean needIdIndex = IdTableBuilding.getFileTypeIndexer(content.getFileType()) instanceof LexerBasedIdIndexer; final IdDataConsumer consumer = needIdIndex? new IdDataConsumer():null; final OccurrenceConsumer todoOccurrenceConsumer = new OccurrenceConsumer(consumer, needTodo); final Lexer filterLexer = indexer.createLexer(todoOccurrenceConsumer); filterLexer.start(content.getContentAsText()); while (filterLexer.getTokenType() != null) filterLexer.advance(); Map<TodoIndexEntry,Integer> todoMap = null; if (needTodo) { for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final int count = todoOccurrenceConsumer.getOccurrenceCount(indexPattern); if (count > 0) { if (todoMap == null) todoMap = new THashMap<TodoIndexEntry, Integer>(); todoMap.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count); } } } data = new ScanContent( consumer != null? consumer.getResult():Collections.<IdIndexEntry, Integer>emptyMap(), todoMap != null ? todoMap: Collections.<TodoIndexEntry,Integer>emptyMap() ); if (needIdIndex && needTodo) content.putUserData(scanContentKey, data); return data; }
public static IndexPattern[] getIndexPatterns() { IndexPattern[] result = new IndexPattern[getIndexPatternCount()]; int destIndex = 0; for(IndexPatternProvider provider: getIndexPatternProviders()) { for(IndexPattern pattern: provider.getIndexPatterns()) { result [destIndex++] = pattern; } } return result; }
public void incTodoOccurrence(final IndexPattern pattern) { if (myTodoOccurrences == null) { myTodoOccurrences = new TObjectIntHashMap<IndexPattern>(); for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { myTodoOccurrences.put(indexPattern, 0); } } myTodoOccurrences.adjustValue(pattern, 1); }
public static ScanContent scanContent(FileContent content, IdAndToDoScannerBasedOnFilterLexer indexer) { ScanContent data = content.getUserData(scanContentKey); if (data != null) { content.putUserData(scanContentKey, null); return data; } final boolean needTodo = content.getFile().getFileSystem().getProtocol().equals(StandardFileSystems.FILE_PROTOCOL); final boolean needIdIndex = IdTableBuilding.getFileTypeIndexer(content.getFileType()) instanceof LexerBasedIdIndexer; final IdDataConsumer consumer = needIdIndex? new IdDataConsumer():null; final OccurrenceConsumer todoOccurrenceConsumer = new OccurrenceConsumer(consumer, needTodo); final Lexer filterLexer = indexer.createLexer(todoOccurrenceConsumer); filterLexer.start(content.getContentAsText()); while (filterLexer.getTokenType() != null) filterLexer.advance(); Map<TodoIndexEntry,Integer> todoMap = null; if (needTodo) { for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final int count = todoOccurrenceConsumer.getOccurrenceCount(indexPattern); if (count > 0) { if (todoMap == null) todoMap = new THashMap<TodoIndexEntry, Integer>(); todoMap.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count); } } } data = new ScanContent( consumer != null? consumer.getResult():Collections.<IdIndexEntry, Integer>emptyMap(), todoMap != null ? todoMap: Collections.<TodoIndexEntry,Integer>emptyMap() ); if (needIdIndex && needTodo) content.putUserData(scanContentKey, data); return data; }
public static TodoScanningData[] advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningData[] todoScanningData) { if (todoScanningData == null) { IndexPattern[] patterns = IndexPatternUtil.getIndexPatterns(); todoScanningData = new TodoScanningData[patterns.length]; for (int i = 0; i < patterns.length; ++i) { IndexPattern indexPattern = patterns[i]; Pattern pattern = indexPattern.getPattern(); if (pattern != null) { todoScanningData [i] = new TodoScanningData(indexPattern, pattern.matcher("")); } } } for (TodoScanningData data:todoScanningData) { if (data == null) continue; Matcher matcher = data.matcher; matcher.reset(input); while (matcher.find()) { if (matcher.start() != matcher.end()) { consumer.incTodoOccurrence(data.pattern); } } } return todoScanningData; }
protected static boolean executeImpl(IndexPatternSearch.SearchParameters queryParameters, Processor<IndexPatternOccurrence> consumer) { final IndexPatternProvider patternProvider = queryParameters.getPatternProvider(); final PsiFile file = queryParameters.getFile(); TIntArrayList commentStarts = new TIntArrayList(); TIntArrayList commentEnds = new TIntArrayList(); final CharSequence chars = file.getViewProvider().getContents(); findCommentTokenRanges(file, chars, queryParameters.getRange(), commentStarts, commentEnds); for (int i = 0; i < commentStarts.size(); i++) { int commentStart = commentStarts.get(i); int commentEnd = commentEnds.get(i); if (patternProvider != null) { for (final IndexPattern pattern : patternProvider.getIndexPatterns()) { if (!collectPatternMatches(pattern, chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer)) { return false; } } } else { if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer)) { return false; } } } return true; }
private static boolean collectPatternMatches(IndexPattern indexPattern, CharSequence chars, int commentStart, int commentEnd, PsiFile file, TextRange range, Processor<IndexPatternOccurrence> consumer) { Pattern pattern = indexPattern.getPattern(); if (pattern != null) { ProgressManager.checkCanceled(); CharSequence input = new CharSequenceSubSequence(chars, commentStart, commentEnd); Matcher matcher = pattern.matcher(input); while (true) { //long time1 = System.currentTimeMillis(); boolean found = matcher.find(); //long time2 = System.currentTimeMillis(); //System.out.println("scanned text of length " + (lexer.getTokenEnd() - lexer.getTokenStart() + " in " + (time2 - time1) + " ms")); if (!found) break; int start = matcher.start() + commentStart; int end = matcher.end() + commentStart; if (start != end) { if (range == null || range.getStartOffset() <= start && end <= range.getEndOffset()) { if (!consumer.process(new IndexPatternOccurrenceImpl(file, start, end, indexPattern))) { return false; } } } ProgressManager.checkCanceled(); } } return true; }
private TodoPattern mapPattern(final IndexPattern pattern) { for(TodoPattern todoPattern: myTodoPatterns) { if (todoPattern.getIndexPattern() == pattern) { return todoPattern; } } LOG.error("Could not find matching TODO pattern for index pattern " + pattern.getPatternString()); return null; }
@Override public int getTodoCount(@NotNull final VirtualFile file, final IndexPatternProvider patternProvider) { if (myProject.isDefault()) { return 0; } if (file instanceof VirtualFileWindow) return -1; final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); int count = 0; for (IndexPattern indexPattern : patternProvider.getIndexPatterns()) { count += fetchCount(fileBasedIndex, file, indexPattern); } return count; }
@Override public int getTodoCount(@NotNull final VirtualFile file, final IndexPattern pattern) { if (myProject.isDefault()) { return 0; } if (file instanceof VirtualFileWindow) return -1; return fetchCount(FileBasedIndex.getInstance(), file, pattern); }
public static ScanContent scanContent(FileContent content, IdAndToDoScannerBasedOnFilterLexer indexer) { ScanContent data = content.getUserData(scanContentKey); if (data != null) { content.putUserData(scanContentKey, null); return data; } final boolean needTodo = content.getFile().getFileSystem() instanceof LocalFileSystem; final boolean needIdIndex = IdTableBuilding.getFileTypeIndexer(content.getFileType()) instanceof LexerBasedIdIndexer; final IdDataConsumer consumer = needIdIndex? new IdDataConsumer():null; final OccurrenceConsumer todoOccurrenceConsumer = new OccurrenceConsumer(consumer, needTodo); final Lexer filterLexer = indexer.createLexer(todoOccurrenceConsumer); filterLexer.start(content.getContentAsText()); while (filterLexer.getTokenType() != null) filterLexer.advance(); Map<TodoIndexEntry,Integer> todoMap = null; if (needTodo) { for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final int count = todoOccurrenceConsumer.getOccurrenceCount(indexPattern); if (count > 0) { if (todoMap == null) todoMap = new THashMap<TodoIndexEntry, Integer>(); todoMap.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count); } } } data = new ScanContent( consumer != null? consumer.getResult():Collections.<IdIndexEntry, Integer>emptyMap(), todoMap != null ? todoMap: Collections.<TodoIndexEntry,Integer>emptyMap() ); if (needIdIndex && needTodo) content.putUserData(scanContentKey, data); return data; }
@Override public int getTodoCount(@Nonnull final VirtualFile file, @Nonnull final IndexPattern pattern) { if (myProject.isDefault()) { return 0; } if (file instanceof VirtualFileWindow) return -1; return fetchCount(FileBasedIndex.getInstance(), file, pattern); }
private int fetchCount(@Nonnull FileBasedIndex fileBasedIndex, @Nonnull VirtualFile file, @Nonnull IndexPattern indexPattern) { final int[] count = {0}; fileBasedIndex.processValues( TodoIndex.NAME, new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), file, (file1, value) -> { count[0] += value.intValue(); return true; }, GlobalSearchScope.fileScope(myProject, file)); return count[0]; }
public IndexPatternOccurrenceImpl(PsiFile file, int startOffset, int endOffset, IndexPattern pattern) { myFile = file; myStartOffset = startOffset; myEndOffset = endOffset; myPattern = pattern; }
@Override @NotNull public IndexPattern getPattern() { return myPattern; }
@Override protected int getOccurrencesCountImpl(@NotNull PsiFile file, @NotNull IndexPattern pattern) { int count = TodoCacheManager.SERVICE.getInstance(file.getProject()).getTodoCount(file.getVirtualFile(), pattern); if (count != -1) return count; return search(file, pattern).findAll().size(); }
@Override @NotNull public IndexPattern[] getIndexPatterns() { return myConfiguration.getIndexPatterns(); }
public TodoScanningState(IndexPattern[] patterns, Matcher[] matchers) { myPatterns = patterns; myMatchers = matchers; myOccurences = new TIntArrayList(1); }
public int getOccurrenceCount(IndexPattern pattern) { if (myTodoOccurrences == null) return 0; return myTodoOccurrences.get(pattern); }
public SearchParameters(@NotNull PsiFile file, @NotNull IndexPattern pattern) { this(file, pattern,null); }
public SearchParameters(@NotNull PsiFile file, @NotNull IndexPattern pattern, TextRange range) { myFile = file; myRange = range; myPatternProvider = null; myPattern = pattern; }
public IndexPattern getPattern() { return myPattern; }
public TodoScanningData(IndexPattern pattern, Matcher matcher) { this.matcher = matcher; this.pattern = pattern; }