mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[diff] IJPL-190026 Don't call LanguageUtil.getLanguageForPsi on EDT
`DiffLangSpecificProvider.findApplicable` is called from EDT, producing a slow operation error in `LanguageUtil.getLanguageForPsi -> ... -> findModuleForFile`. Now `DiffUserDataKeys.LANGUAGE` is set on BGT and `DiffLangSpecificProvider.findApplicable` relies on it. GitOrigin-RevId: dfe87819de3f3782ffcfee1174b0ba3d7dc69ea0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fbda434679
commit
6e2fa02aa7
@@ -545,14 +545,14 @@ com.intellij.diff.lang.DiffIgnoredRangeProvider
|
||||
com.intellij.diff.lang.DiffLangSpecificProvider
|
||||
- sf:Companion:com.intellij.diff.lang.DiffLangSpecificProvider$Companion
|
||||
- sf:EP_NAME:com.intellij.openapi.extensions.ExtensionPointName
|
||||
- s:findApplicable(com.intellij.openapi.project.Project,com.intellij.diff.contents.DiffContent,com.intellij.diff.contents.DiffContent):com.intellij.diff.lang.DiffLangSpecificProvider
|
||||
- s:findApplicable(com.intellij.diff.contents.DiffContent,com.intellij.diff.contents.DiffContent):com.intellij.diff.lang.DiffLangSpecificProvider
|
||||
- a:getDescription():java.lang.String
|
||||
- getLineFragments(com.intellij.openapi.project.Project,java.lang.CharSequence,java.lang.CharSequence,com.intellij.diff.tools.util.base.IgnorePolicy,com.intellij.diff.tools.util.base.HighlightPolicy,com.intellij.openapi.progress.ProgressIndicator):java.util.List
|
||||
- getPatchedLineFragments(com.intellij.openapi.project.Project,java.util.List,java.lang.CharSequence,java.lang.CharSequence,com.intellij.diff.tools.util.base.IgnorePolicy,com.intellij.diff.tools.util.base.HighlightPolicy,com.intellij.openapi.progress.ProgressIndicator):java.util.List
|
||||
- a:getShouldPrecalculateLineFragments():Z
|
||||
- a:isApplicable(com.intellij.lang.Language):Z
|
||||
f:com.intellij.diff.lang.DiffLangSpecificProvider$Companion
|
||||
- f:findApplicable(com.intellij.openapi.project.Project,com.intellij.diff.contents.DiffContent,com.intellij.diff.contents.DiffContent):com.intellij.diff.lang.DiffLangSpecificProvider
|
||||
- f:findApplicable(com.intellij.diff.contents.DiffContent,com.intellij.diff.contents.DiffContent):com.intellij.diff.lang.DiffLangSpecificProvider
|
||||
a:com.intellij.diff.lang.LangDiffIgnoredRangeProvider
|
||||
- com.intellij.diff.lang.DiffIgnoredRangeProvider
|
||||
- <init>():V
|
||||
@@ -560,15 +560,14 @@ a:com.intellij.diff.lang.LangDiffIgnoredRangeProvider
|
||||
- pa:accepts(com.intellij.openapi.project.Project,com.intellij.lang.Language):Z
|
||||
- pa:computeIgnoredRanges(com.intellij.openapi.project.Project,java.lang.CharSequence,com.intellij.lang.Language):java.util.List
|
||||
- getIgnoredRanges(com.intellij.openapi.project.Project,java.lang.CharSequence,com.intellij.diff.contents.DiffContent):java.util.List
|
||||
- s:getLanguage(com.intellij.openapi.project.Project,com.intellij.diff.contents.DiffContent):com.intellij.lang.Language
|
||||
com.intellij.diff.merge.LangSpecificMergeConflictResolver
|
||||
- sf:Companion:com.intellij.diff.merge.LangSpecificMergeConflictResolver$Companion
|
||||
- sf:EP_NAME:com.intellij.openapi.extensions.ExtensionPointName
|
||||
- s:findApplicable(com.intellij.openapi.project.Project,java.util.List):com.intellij.diff.merge.LangSpecificMergeConflictResolver
|
||||
- s:findApplicable(java.util.List):com.intellij.diff.merge.LangSpecificMergeConflictResolver
|
||||
- a:isApplicable(com.intellij.lang.Language):Z
|
||||
- a:tryResolveMergeConflicts(com.intellij.diff.merge.LangSpecificMergeContext,kotlin.coroutines.Continuation):java.lang.Object
|
||||
f:com.intellij.diff.merge.LangSpecificMergeConflictResolver$Companion
|
||||
- f:findApplicable(com.intellij.openapi.project.Project,java.util.List):com.intellij.diff.merge.LangSpecificMergeConflictResolver
|
||||
- f:findApplicable(java.util.List):com.intellij.diff.merge.LangSpecificMergeConflictResolver
|
||||
f:com.intellij.diff.merge.LangSpecificMergeContext
|
||||
- <init>(com.intellij.openapi.project.Project,java.util.List,java.util.List,java.util.List):V
|
||||
- f:file(com.intellij.diff.util.ThreeSide):com.intellij.psi.PsiFile
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.intellij.diff.impl;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.diff.chains.DiffRequestProducer;
|
||||
import com.intellij.diff.chains.DiffRequestProducerException;
|
||||
import com.intellij.diff.lang.DiffLanguage;
|
||||
import com.intellij.diff.requests.*;
|
||||
import com.intellij.diff.tools.util.SoftHardCacheMap;
|
||||
import com.intellij.diff.util.DiffTaskQueue;
|
||||
@@ -110,6 +111,9 @@ public abstract class CacheDiffRequestProcessor<T> extends DiffRequestProcessor
|
||||
myQueue.executeAndTryWait(
|
||||
indicator -> {
|
||||
final DiffRequest request = doLoadRequest(requestProvider, indicator);
|
||||
if (request instanceof ContentDiffRequest contentDiffRequest) {
|
||||
contentDiffRequest.getContents().forEach(content -> DiffLanguage.computeAndCacheLanguage(content, getProject()));
|
||||
}
|
||||
return () -> finishRequestLoading(request, force, scrollToChangePolicy, requestProvider);
|
||||
},
|
||||
() -> applyRequest(new LoadingDiffRequest(getRequestName(requestProvider)), force, scrollToChangePolicy),
|
||||
|
||||
@@ -61,11 +61,9 @@ interface DiffLangSpecificProvider {
|
||||
val EP_NAME: ExtensionPointName<DiffLangSpecificProvider> = ExtensionPointName.create<DiffLangSpecificProvider>("com.intellij.diff.lang.DiffLangSpecificAdjuster")
|
||||
|
||||
@JvmStatic
|
||||
fun findApplicable(project: Project?, leftContent: DiffContent, rightContent: DiffContent): DiffLangSpecificProvider? {
|
||||
if (project == null) return null
|
||||
|
||||
val leftLanguage = LangDiffIgnoredRangeProvider.getLanguage(project, leftContent)
|
||||
val rightLanguage = LangDiffIgnoredRangeProvider.getLanguage(project, rightContent)
|
||||
fun findApplicable(leftContent: DiffContent, rightContent: DiffContent): DiffLangSpecificProvider? {
|
||||
val leftLanguage = DiffLanguage.getLanguage(leftContent)
|
||||
val rightLanguage = DiffLanguage.getLanguage(rightContent)
|
||||
|
||||
if (leftLanguage == null || rightLanguage == null || leftLanguage != rightLanguage) return null
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.diff.lang
|
||||
|
||||
import com.intellij.diff.contents.DiffContent
|
||||
import com.intellij.diff.contents.DocumentContent
|
||||
import com.intellij.diff.lang.DiffLanguage.getLanguageOrCompute
|
||||
import com.intellij.diff.util.DiffUserDataKeys
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.LanguageUtil
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import org.jetbrains.annotations.CalledInAny
|
||||
|
||||
internal object DiffLanguage {
|
||||
/**
|
||||
* Note that unlike [getLanguageOrCompute] this method ignores [com.intellij.psi.LanguageSubstitutors] as their
|
||||
* calculation might require a background thread.
|
||||
*
|
||||
* @return language saved as user data in [content] or language guessed by [content] file type
|
||||
*/
|
||||
@CalledInAny
|
||||
fun getLanguage(content: DiffContent): Language? =
|
||||
getLanguageByDataKey(content) ?: getLanguageByFileType(content)
|
||||
|
||||
@JvmStatic
|
||||
@RequiresBackgroundThread
|
||||
fun getLanguageOrCompute(project: Project, content: DiffContent): Language? {
|
||||
val language = getLanguageByDataKey(content)
|
||||
if (language != null) return language
|
||||
|
||||
return computeLanguage(content, project)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RequiresBackgroundThread
|
||||
fun computeAndCacheLanguage(content: DiffContent, project: Project?) {
|
||||
val language = computeLanguage(content, project)
|
||||
if (language != null) {
|
||||
content.putUserData(DiffUserDataKeys.LANGUAGE, language)
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeLanguage(content: DiffContent, project: Project?): Language? {
|
||||
if (project == null) return getLanguageByFileType(content)
|
||||
|
||||
val fileType = content.getContentType()
|
||||
val languageForPsi = (content as? DocumentContent)?.highlightFile?.let { highlightingFile ->
|
||||
runReadAction { LanguageUtil.getLanguageForPsi(project, highlightingFile, fileType) }
|
||||
}
|
||||
|
||||
return languageForPsi ?: getLanguageByFileType(content)
|
||||
}
|
||||
|
||||
private fun getLanguageByDataKey(content: DiffContent): Language? = content.getUserData(DiffUserDataKeys.LANGUAGE)
|
||||
|
||||
private fun getLanguageByFileType(content: DiffContent): Language? = content.getContentType()?.let(LanguageUtil::getFileTypeLanguage)
|
||||
}
|
||||
@@ -2,15 +2,9 @@
|
||||
package com.intellij.diff.lang;
|
||||
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.DocumentContent;
|
||||
import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageUtil;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -24,7 +18,7 @@ public abstract class LangDiffIgnoredRangeProvider implements DiffIgnoredRangePr
|
||||
@Override
|
||||
public final boolean accepts(@Nullable Project project, @NotNull DiffContent content) {
|
||||
if (project == null) return false;
|
||||
Language language = getLanguage(project, content);
|
||||
Language language = DiffLanguage.getLanguageOrCompute(project, content);
|
||||
if (language == null) return false;
|
||||
return accepts(project, language);
|
||||
}
|
||||
@@ -32,21 +26,9 @@ public abstract class LangDiffIgnoredRangeProvider implements DiffIgnoredRangePr
|
||||
@Override
|
||||
public @NotNull List<TextRange> getIgnoredRanges(@Nullable Project project, @NotNull CharSequence text, @NotNull DiffContent content) {
|
||||
assert project != null;
|
||||
Language language = getLanguage(project, content);
|
||||
Language language = DiffLanguage.getLanguageOrCompute(project, content);
|
||||
assert language != null;
|
||||
|
||||
return computeIgnoredRanges(project, text, language);
|
||||
}
|
||||
|
||||
public static @Nullable Language getLanguage(@NotNull Project project, @NotNull DiffContent content) {
|
||||
Language language = content.getUserData(DiffUserDataKeys.LANGUAGE);
|
||||
if (language != null) return language;
|
||||
|
||||
FileType fileType = content.getContentType();
|
||||
VirtualFile file = content instanceof DocumentContent ? ((DocumentContent)content).getHighlightFile() : null;
|
||||
if (file != null) {
|
||||
return ReadAction.compute(() -> LanguageUtil.getLanguageForPsi(project, file, fileType));
|
||||
}
|
||||
return fileType == null ? null : LanguageUtil.getFileTypeLanguage(fileType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
package com.intellij.diff.merge
|
||||
|
||||
import com.intellij.diff.contents.DocumentContent
|
||||
import com.intellij.diff.lang.LangDiffIgnoredRangeProvider
|
||||
import com.intellij.diff.lang.DiffLanguage
|
||||
import com.intellij.diff.util.ThreeSide
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
/**
|
||||
* An interface for resolving merge conflicts in a way that requires semantic of some language.
|
||||
@@ -31,10 +30,10 @@ interface LangSpecificMergeConflictResolver {
|
||||
val EP_NAME: ExtensionPointName<LangSpecificMergeConflictResolver> = ExtensionPointName.create("com.intellij.diff.merge.conflict.semantic.resolver")
|
||||
|
||||
@JvmStatic
|
||||
fun findApplicable(project: Project?, contentList: List<DocumentContent>): LangSpecificMergeConflictResolver? {
|
||||
if (project == null || contentList.size != ThreeSide.entries.size) return null
|
||||
fun findApplicable(contentList: List<DocumentContent>): LangSpecificMergeConflictResolver? {
|
||||
if (contentList.size != ThreeSide.entries.size) return null
|
||||
|
||||
val languageList = contentList.mapNotNull { LangDiffIgnoredRangeProvider.getLanguage(project, it) }
|
||||
val languageList = contentList.mapNotNull { DiffLanguage.getLanguage(it) }
|
||||
|
||||
if (languageList.size != ThreeSide.entries.size || languageList.distinct().size != 1) return null
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.ApiStatus
|
||||
@ApiStatus.Internal
|
||||
class LangSpecificMergeConflictResolverWrapper(private val project: Project?, contentList: List<DocumentContent>) {
|
||||
private val resolver: LangSpecificMergeConflictResolver? = if (`is`("semantic.merge.conflict.resolution", false)) {
|
||||
LangSpecificMergeConflictResolver.findApplicable(project, contentList)
|
||||
LangSpecificMergeConflictResolver.findApplicable(contentList)
|
||||
}
|
||||
else {
|
||||
null
|
||||
|
||||
@@ -49,7 +49,7 @@ public class SmartTextDiffProvider extends TwosideTextDiffProviderBase implement
|
||||
DiffContent content1 = Side.LEFT.select(request.getContents());
|
||||
DiffContent content2 = Side.RIGHT.select(request.getContents());
|
||||
DiffIgnoredRangeProvider ignoredRangeProvider = getIgnoredRangeProvider(project, content1, content2);
|
||||
DiffLangSpecificProvider diffProvider = DiffLangSpecificProvider.findApplicable(project, content1, content2);
|
||||
DiffLangSpecificProvider diffProvider = DiffLangSpecificProvider.findApplicable(content1, content2);
|
||||
IgnorePolicy[] ignorePolicies = getIgnorePolicies();
|
||||
return new SmartTextDiffProvider(project, content1, content2, settings, rediff, disposable, ignoredRangeProvider, diffProvider,
|
||||
ignorePolicies);
|
||||
@@ -63,7 +63,7 @@ public class SmartTextDiffProvider extends TwosideTextDiffProviderBase implement
|
||||
DiffContent content1 = Side.LEFT.select(request.getContents());
|
||||
DiffContent content2 = Side.RIGHT.select(request.getContents());
|
||||
DiffIgnoredRangeProvider ignoredRangeProvider = getIgnoredRangeProvider(project, content1, content2);
|
||||
DiffLangSpecificProvider diffAdjuster = DiffLangSpecificProvider.findApplicable(project, content1, content2);
|
||||
DiffLangSpecificProvider diffAdjuster = DiffLangSpecificProvider.findApplicable(content1, content2);
|
||||
return new SmartTextDiffProvider.NoIgnore(project, content1, content2, settings, rediff, disposable, ignoredRangeProvider, diffAdjuster);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user