diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java index 590d753a010a..e8babbc31b2c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java @@ -57,7 +57,9 @@ public class JavaCodeBlockModificationListener implements PsiTreeChangePreproces case CHILD_MOVED: case PROPERTY_CHANGED: - myModificationTracker.incCounter(); + if (PsiModificationTrackerImpl.canAffectPsi(event)) { + myModificationTracker.incCounter(); + } break; default: diff --git a/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java b/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java index e23e4b9232ac..bc701ec1ea24 100644 --- a/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java @@ -418,4 +418,20 @@ public class PsiModificationTrackerTest extends CodeInsightTestCase { return null; }); } + + public void testNoIncrementOnReadOnlyStatusChange() throws IOException { + VirtualFile file = addFileToProject("Foo.java", "class Foo {}").getVirtualFile(); + + PsiModificationTracker tracker = PsiManager.getInstance(getProject()).getModificationTracker(); + long mc = tracker.getModificationCount(); + + WriteAction.run(() -> file.setWritable(false)); + assertEquals(mc, tracker.getModificationCount()); + + PlatformTestUtil.tryGcSoftlyReachableObjects(); + assertNull(PsiManagerEx.getInstanceEx(myProject).getFileManager().getCachedPsiFile(file)); + + WriteAction.run(() -> file.setWritable(true)); + assertEquals(mc, tracker.getModificationCount()); + } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java index ceca9262eb64..ceba43ce3027 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ModificationTracker; import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiTreeChangeEvent; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; @@ -83,6 +84,10 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr @Override public void treeChanged(@NotNull PsiTreeChangeEventImpl event) { + if (!canAffectPsi(event)) { + return; + } + myModificationCount.getAndIncrement(); if (event.getParent() instanceof PsiDirectory || event.getOldParent() instanceof PsiDirectory /* move events */) { @@ -92,6 +97,10 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr fireEvent(); } + public static boolean canAffectPsi(@NotNull PsiTreeChangeEventImpl event) { + return !PsiTreeChangeEvent.PROP_WRITABLE.equals(event.getPropertyName()); + } + @Override public long getModificationCount() { return myModificationCount.get();