mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cancel reparsing if psi is reloaded anyway (e.g. FilePropertyPusher reloads psi); don't reparse for the first language substitution (everything seems to work in this case) (IDEA-CR-11333)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ public class FileManagerImpl implements FileManager {
|
||||
}
|
||||
|
||||
public void forceReload(@NotNull VirtualFile vFile) {
|
||||
LanguageSubstitutors.cancelReparsing(vFile);
|
||||
if (findCachedViewProvider(vFile) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user