private void queueElement( @NotNull PsiElement child, final boolean whitespaceOptimizationAllowed, @NotNull PsiTreeChangeEvent event) { ApplicationManager.getApplication().assertIsDispatchThread(); PsiFile file = event.getFile(); if (file == null) file = child.getContainingFile(); if (file == null) { myFileStatusMap.markAllFilesDirty(child); return; } if (!child.isValid()) return; PsiDocumentManagerImpl pdm = (PsiDocumentManagerImpl) PsiDocumentManager.getInstance(myProject); Document document = pdm.getCachedDocument(file); if (document != null) { if (pdm.getSynchronizer().getTransaction(document) == null) { // content reload, language level change or some other big change myFileStatusMap.markAllFilesDirty(child); return; } List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document); if (toUpdate == null) { toUpdate = new SmartList<>(); changedElements.put(document, toUpdate); } toUpdate.add(Pair.create(child, whitespaceOptimizationAllowed)); } }
private void updateByChange( @NotNull PsiElement child, @NotNull final Document document, final boolean whitespaceOptimizationAllowed) { ApplicationManager.getApplication().assertIsDispatchThread(); final PsiFile file; try { file = child.getContainingFile(); } catch (PsiInvalidElementAccessException e) { myFileStatusMap.markAllFilesDirty(e); return; } if (file == null || file instanceof PsiCompiledElement) { myFileStatusMap.markAllFilesDirty(child); return; } VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile != null && shouldBeIgnored(virtualFile)) { // ignore workspace.xml return; } int fileLength = file.getTextLength(); if (!file.getViewProvider().isPhysical()) { myFileStatusMap.markFileScopeDirty( document, new TextRange(0, fileLength), fileLength, "Non-physical file update: " + file); return; } PsiElement element = whitespaceOptimizationAllowed && UpdateHighlightersUtil.isWhitespaceOptimizationAllowed(document) ? child : child.getParent(); while (true) { if (element == null || element instanceof PsiFile || element instanceof PsiDirectory) { myFileStatusMap.markAllFilesDirty("Top element: " + element); return; } final PsiElement scope = getChangeHighlightingScope(element); if (scope != null) { myFileStatusMap.markFileScopeDirty( document, scope.getTextRange(), fileLength, "Scope: " + scope); return; } element = element.getParent(); } }
public GeneralHighlightingPass( @NotNull Project project, @NotNull PsiFile file, @NotNull Document document, int startOffset, int endOffset, boolean updateAll, @NotNull ProperTextRange priorityRange, @Nullable Editor editor) { super(project, document, PRESENTABLE_NAME, file, true); myStartOffset = startOffset; myEndOffset = endOffset; myUpdateAll = updateAll; myPriorityRange = priorityRange; myEditor = editor; LOG.assertTrue(file.isValid()); setId(Pass.UPDATE_ALL); myHasErrorElement = !isWholeFileHighlighting() && Boolean.TRUE.equals(myFile.getUserData(HAS_ERROR_ELEMENT)); FileStatusMap fileStatusMap = ((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(myProject)).getFileStatusMap(); myErrorFound = !isWholeFileHighlighting() && fileStatusMap.wasErrorFound(myDocument); myApplyCommand = new Runnable() { @Override public void run() { ProperTextRange range = new ProperTextRange(myStartOffset, myEndOffset); MarkupModel model = DocumentMarkupModel.forDocument(myDocument, myProject, true); UpdateHighlightersUtil.cleanFileLevelHighlights(myProject, Pass.UPDATE_ALL, myFile); final EditorColorsScheme colorsScheme = getColorsScheme(); UpdateHighlightersUtil.setHighlightersInRange( myProject, myDocument, range, colorsScheme, myHighlights, (MarkupModelEx) model, Pass.UPDATE_ALL); } }; // initial guess to show correct progress in the traffic light icon setProgressLimit(document.getTextLength() / 2); // approx number of PSI elements = file length/2 myGlobalScheme = EditorColorsManager.getInstance().getGlobalScheme(); }
@Override public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) { // this event sent always before every PSI change, even not significant one (like after quick // typing/backspacing char) // mark file dirty just in case PsiFile psiFile = event.getFile(); if (psiFile != null) { myFileStatusMap.markFileScopeDirtyDefensively(psiFile, event); } }
@Override public void propertyChanged(@NotNull PsiTreeChangeEvent event) { String propertyName = event.getPropertyName(); if (!propertyName.equals(PsiTreeChangeEvent.PROP_WRITABLE)) { Object oldValue = event.getOldValue(); if (oldValue instanceof VirtualFile && shouldBeIgnored((VirtualFile) oldValue)) { // ignore workspace.xml return; } myFileStatusMap.markAllFilesDirty(event); } }