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");
}
- 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
}
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);
}
}