void (@NotNull PsiElement child, @NotNull Document document, boolean whitespaceOptimizationAllowed) { ApplicationManager.getApplication().assertWriteIntentLockAcquired(); 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; } TextRange existingDirtyScope = myFileStatusMap.getFileDirtyScopeForAllPassesCombined(document); 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; } PsiElement scope = getChangeHighlightingScope(element); if (scope != null) { TextRange scopeRange = scope.getTextRange(); // if some unrelated scope already marked dirty, we shouldn't just add another scope and return, // because between these two dirty whitespaces might easily be some other non-whitespace PSI, // and this PSI element is not expected to be highlighted alone, which could lead to unexpected highlighter disappearances // see DaemonRespondToChangesTest.testPutArgumentsOnSeparateLinesIntentionMustNotRemoveErrorHighlighting if (existingDirtyScope == null || scopeRange.contains(existingDirtyScope)) { myFileStatusMap.markFileScopeDirty(document, scopeRange, fileLength, "Scope: " + scope); return; } existingDirtyScope = existingDirtyScope.union(scopeRange); } element = element.getParent(); } }