From 8875a315251e7924ddee9374a4f8c7488561360f Mon Sep 17 00:00:00 2001
From: "Ilya.Kazakevich" <Ilya.Kazakevich@jetbrains.com>
Date: Fri, 18 Aug 2017 02:36:46 +0300
Subject: [PATCH] PY-20537: Invalidate caches in "clearCaches", not
 "subtreeChanged"

"clearCaches" is the right place to invalidate caches because
"subtreeChanged" is not always called: some times only "onContentChanged"
called. Both methods call "clearCaches" though.

"clearCaches" moved to interface level since it is part of public API now
---
 .../core-api/src/com/intellij/psi/PsiFile.java     | 14 ++++++++++++--
 .../com/intellij/psi/impl/source/PsiFileImpl.java  |  1 +
 .../com/jetbrains/python/psi/impl/PyFileImpl.java  |  4 ++--
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/platform/core-api/src/com/intellij/psi/PsiFile.java b/platform/core-api/src/com/intellij/psi/PsiFile.java
index c13568cb1d19..d3a93b8a7873 100644
--- a/platform/core-api/src/com/intellij/psi/PsiFile.java
+++ b/platform/core-api/src/com/intellij/psi/PsiFile.java
@@ -101,8 +101,18 @@ public interface PsiFile extends PsiFileSystemItem {
   FileASTNode getNode();
 
   /**
-   * Called by the PSI framework when the contents of the file changes. Can be used to invalidate
-   * file-level caches. If you override this method, you <b>must</b> call the base class implementation.
+   * Called by the PSI framework when the contents of the file changes.
+   * If you override this method, you <b>must</b> call the base class implementation.
+   * While this method can be used to invalidate file-level caches, it is more much safe to invalidate them in  {@link #clearCaches()}
+   * since file contents can be reloaded completely (without any specific subtree change) without this method being called.
    */
   void subtreeChanged();
+
+  /**
+   * Invalidate any file-specific cache in this method. It is called on file file content change.
+   * If you override this method, you <b>must</b> call the base class implementation.
+   */
+  default void clearCaches() {
+
+  }
 }
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
index 036bd368d02b..9524ced4bb6d 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
@@ -368,6 +368,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
     return treeElement;
   }
 
+  @Override
   public void clearCaches() {
     myModificationStamp ++;
   }
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
index 7748cf5f18fa..50e093916a7f 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
@@ -729,8 +729,8 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
   }
 
   @Override
-  public void subtreeChanged() {
-    super.subtreeChanged();
+  public void clearCaches() {
+    super.clearCaches();
     ControlFlowCache.clear(this);
     myDunderAllCalculated = false;
     myFutureFeatures.clear(); // probably no need to synchronize
-- 
GitLab