cancel reparsing if psi is reloaded anyway (e.g. FilePropertyPusher reloads psi)...
authorSergey Simonchik <sergey.simonchik@jetbrains.com>
Thu, 9 Jun 2016 15:49:36 +0000 (18:49 +0300)
committerSergey Simonchik <sergey.simonchik@jetbrains.com>
Thu, 9 Jun 2016 15:51:34 +0000 (18:51 +0300)
platform/core-api/src/com/intellij/psi/LanguageSubstitutors.java
platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java

index 1dca825fd2dacead15100c21bd153beeff7374fe..c3098f46068d111e274d096df6d254054ce5b100 100644 (file)
@@ -35,8 +35,7 @@ public final class LanguageSubstitutors extends LanguageExtension<LanguageSubsti
   public static final LanguageSubstitutors INSTANCE = new LanguageSubstitutors();
   private static final Logger LOG = Logger.getInstance(LanguageSubstitutors.class);
   private static final Key<Language> SUBSTITUTED_LANG_KEY = Key.create("SUBSTITUTED_LANG_KEY");
-
-  private boolean myReparsingInProgress;
+  private static final Key<Boolean> REPARSING_SCHEDULED = Key.create("REPARSING_SCHEDULED");
 
   private LanguageSubstitutors() {
     super("com.intellij.lang.substitutor");
@@ -55,9 +54,9 @@ public final class LanguageSubstitutors extends LanguageExtension<LanguageSubsti
   }
 
 
-  private void processLanguageSubstitution(@NotNull final VirtualFile file,
-                                           @NotNull Language originalLang,
-                                           @NotNull final Language substitutedLang) {
+  private static void processLanguageSubstitution(@NotNull final VirtualFile file,
+                                                  @NotNull Language originalLang,
+                                                  @NotNull final Language substitutedLang) {
     if (file instanceof VirtualFileWindow) {
       // Injected files are created with substituted language, no need to reparse:
       //   com.intellij.psi.impl.source.tree.injected.MultiHostRegistrarImpl#doneInjecting
@@ -65,41 +64,30 @@ public final class LanguageSubstitutors extends LanguageExtension<LanguageSubsti
     }
     Language prevSubstitutedLang = SUBSTITUTED_LANG_KEY.get(file);
     final Language prevLang = ObjectUtils.notNull(prevSubstitutedLang, originalLang);
-    if (!haveCommonAncestorLanguage(substitutedLang, prevLang)) {
+    if (!prevLang.is(substitutedLang)) {
       if (file.replace(SUBSTITUTED_LANG_KEY, prevSubstitutedLang, substitutedLang)) {
-        if (ApplicationManager.getApplication().isDispatchThread() && myReparsingInProgress) {
-          return; // avoid recursive reparsing
+        if (prevSubstitutedLang == null) {
+          return; // no need to reparse for the first language substitution
         }
         if (ApplicationManager.getApplication().isUnitTestMode()) {
           return;
         }
+        file.putUserData(REPARSING_SCHEDULED, true);
         ApplicationManager.getApplication().invokeLater(new Runnable() {
           @Override
           public void run() {
-            LOG.info("Reparsing " + file.getPath() + " because of language substitution " +
-                     prevLang.getID() + "->" + substitutedLang.getID());
-            myReparsingInProgress = true;
-            FileContentUtilCore.reparseFiles(file);
-            myReparsingInProgress = false;
+            if (file.replace(REPARSING_SCHEDULED, true, null)) {
+              LOG.info("Reparsing " + file.getPath() + " because of language substitution " +
+                       prevLang.getID() + "->" + substitutedLang.getID());
+              FileContentUtilCore.reparseFiles(file);
+            }
           }
         }, ModalityState.defaultModalityState());
       }
     }
   }
 
-  private static boolean haveCommonAncestorLanguage(@NotNull Language lang1, @NotNull Language lang2) {
-    Language rootLang1 = findRootLanguage(lang1);
-    Language rootLang2 = findRootLanguage(lang2);
-    return rootLang1.is(rootLang2);
-  }
-
-  @NotNull
-  private static Language findRootLanguage(@NotNull Language lang) {
-    Language parent = lang.getBaseLanguage();
-    while (parent != null) {
-      lang = parent;
-      parent = lang.getBaseLanguage();
-    }
-    return lang;
+  public static void cancelReparsing(@NotNull VirtualFile file) {
+    REPARSING_SCHEDULED.set(file, null);
   }
 }
index 1b2589f7a7140bbb20638bdf9beb7b05e75472bc..a83b2a670d22009bebfb9dde78f0e818ec44d4ec 100644 (file)
@@ -146,6 +146,7 @@ public class FileManagerImpl implements FileManager {
   }
 
   public void forceReload(@NotNull VirtualFile vFile) {
+    LanguageSubstitutors.cancelReparsing(vFile);
     if (findCachedViewProvider(vFile) == null) {
       return;
     }