mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
serviceAsync should not return Deferred
GitOrigin-RevId: ab482e63c006f1c77ceafd8124357b2a39d1fe3d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3b54501d48
commit
b2ff586ecf
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.components
|
||||
|
||||
import kotlinx.coroutines.Deferred
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
@@ -57,7 +56,7 @@ inline fun <reified T : Any> ComponentManager.services(includeLocal: Boolean): L
|
||||
|
||||
@ApiStatus.Internal
|
||||
@ApiStatus.Experimental
|
||||
suspend inline fun <reified T : Any> ComponentManager.serviceAsync(): Deferred<T> {
|
||||
suspend inline fun <reified T : Any> ComponentManager.serviceAsync(): T {
|
||||
return (this as ComponentManagerEx).getServiceAsync(T::class.java)
|
||||
}
|
||||
|
||||
@@ -65,7 +64,7 @@ suspend inline fun <reified T : Any> ComponentManager.serviceAsync(): Deferred<T
|
||||
interface ComponentManagerEx {
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.Internal
|
||||
suspend fun <T : Any> getServiceAsync(keyClass: Class<T>): Deferred<T> {
|
||||
suspend fun <T : Any> getServiceAsync(keyClass: Class<T>): T {
|
||||
throw AbstractMethodError()
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.intellij.openapi.progress;
|
||||
|
||||
import com.intellij.concurrency.ThreadContext;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import kotlinx.coroutines.Job;
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
@@ -63,4 +64,18 @@ public final class Cancellation {
|
||||
throw new RuntimeException("PCE is not expected in non-cancellable section execution", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static @NotNull AccessToken withCancelableSection() {
|
||||
if (isInNonCancelableSection()) {
|
||||
return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
}
|
||||
|
||||
isInNonCancelableSection.set(Boolean.TRUE);
|
||||
return new AccessToken() {
|
||||
@Override
|
||||
public void finish() {
|
||||
isInNonCancelableSection.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ private class ProjectRunConfigurationInitializer : ProjectServiceContainerInitia
|
||||
// wait for module manager - may be required for module level run configurations
|
||||
// it allows us to avoid thread blocking
|
||||
// (RunManager itself cannot yet do the same, as the platform doesn't provide non-blocking load state)
|
||||
project.serviceAsync<ModuleManager>().join()
|
||||
project.serviceAsync<ModuleManager>()
|
||||
|
||||
runActivity("RunManager initialization") {
|
||||
// we must not fire beginUpdate here, because message bus will fire queued parent message bus messages
|
||||
// (and, so, SOE may occur because all other projectOpened will be processed before us)
|
||||
// simply, you should not listen changes until the project opened
|
||||
project.serviceAsync<RunManager>().join()
|
||||
project.serviceAsync<RunManager>()
|
||||
IS_RUN_MANAGER_INITIALIZED.set(project, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.actionSystem.ex
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
@@ -7,7 +7,7 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.components.ComponentManagerEx
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.components.serviceIfCreated
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -66,7 +66,7 @@ abstract class ActionManagerEx : ActionManager() {
|
||||
if (created == null) {
|
||||
@Suppress("DEPRECATION")
|
||||
(scope ?: app.coroutineScope).launch {
|
||||
val actionManager = (app as ComponentManagerEx).getServiceAsync(ActionManager::class.java).await()
|
||||
val actionManager = app.serviceAsync<ActionManager>()
|
||||
withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
task(actionManager)
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ private const val COMMON_SUB_STACK_WEIGHT = 0.25
|
||||
private const val DEBUG = false
|
||||
|
||||
private suspend fun reportUnfinishedFreezes() {
|
||||
ApplicationManager.getApplication().serviceAsync<PerformanceWatcher>().await().processUnfinishedFreeze { dir, duration ->
|
||||
ApplicationManager.getApplication().serviceAsync<PerformanceWatcher>().processUnfinishedFreeze { dir, duration ->
|
||||
val files = try {
|
||||
withContext(Dispatchers.IO) {
|
||||
Files.newDirectoryStream(dir).use { it.toList() }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.ui.html
|
||||
|
||||
import com.intellij.diagnostic.runActivity
|
||||
@@ -8,9 +8,9 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.components.ComponentManagerEx
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.editor.colors.EditorColorsListener
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
@@ -85,11 +85,11 @@ object GlobalStyleSheetHolder {
|
||||
updateRequests
|
||||
.debounce(5.milliseconds)
|
||||
.collectLatest {
|
||||
val componentManager = ApplicationManager.getApplication() as ComponentManagerEx
|
||||
listOf(
|
||||
componentManager.getServiceAsync(EditorColorsManager::class.java),
|
||||
componentManager.getServiceAsync(FontFamilyService::class.java),
|
||||
).awaitAll()
|
||||
val app = ApplicationManager.getApplication()
|
||||
coroutineScope {
|
||||
async { app.serviceAsync<EditorColorsManager>() }
|
||||
async { app.serviceAsync<FontFamilyService>() }
|
||||
}
|
||||
withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
updateGlobalStyleSheet()
|
||||
}
|
||||
|
||||
@@ -157,9 +157,9 @@ private suspend fun initApplicationImpl(args: List<String>,
|
||||
|
||||
if (!app.isHeadlessEnvironment) {
|
||||
asyncScope.launch {
|
||||
subtask("UISettings preloading") { app.serviceAsync<UISettings>().join() }
|
||||
subtask("KeymapManager preloading") { app.serviceAsync<KeymapManager>().join() }
|
||||
subtask("ActionManager preloading") { app.serviceAsync<ActionManager>().join() }
|
||||
subtask("UISettings preloading") { app.serviceAsync<UISettings>() }
|
||||
subtask("KeymapManager preloading") { app.serviceAsync<KeymapManager>() }
|
||||
subtask("ActionManager preloading") { app.serviceAsync<ActionManager>() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,20 +229,20 @@ fun CoroutineScope.preloadCriticalServices(app: ApplicationImpl) {
|
||||
launch {
|
||||
// LocalHistory wants ManagingFS.
|
||||
// It should be fixed somehow, but for now, to avoid thread contention, preload it in a controlled manner.
|
||||
app.getServiceAsync(ManagingFS::class.java).join()
|
||||
app.serviceAsync<ManagingFS>()
|
||||
// PlatformVirtualFileManager also wants ManagingFS
|
||||
launch { app.getServiceAsync(VirtualFileManager::class.java) }
|
||||
launch { app.serviceAsync<VirtualFileManager>() }
|
||||
launch { app.getServiceAsyncIfDefined(LocalHistory::class.java) }
|
||||
}
|
||||
launch {
|
||||
// required for any persistence state component (pathMacroSubstitutor.expandPaths), so, preload
|
||||
app.serviceAsync<PathMacros>().join()
|
||||
app.serviceAsync<PathMacros>()
|
||||
|
||||
launch {
|
||||
app.serviceAsync<RegistryManager>().join()
|
||||
app.serviceAsync<RegistryManager>()
|
||||
// wants RegistryManager
|
||||
if (!app.isHeadlessEnvironment) {
|
||||
app.serviceAsync<PerformanceWatcher>().join()
|
||||
app.serviceAsync<PerformanceWatcher>()
|
||||
// cache it (CachedSingletonsRegistry is used,
|
||||
// and IdeEventQueue should use loaded PerformanceWatcher service as soon as it is ready)
|
||||
PerformanceWatcher.getInstance()
|
||||
@@ -251,18 +251,18 @@ fun CoroutineScope.preloadCriticalServices(app: ApplicationImpl) {
|
||||
|
||||
// required for indexing tasks (see JavaSourceModuleNameIndex for example)
|
||||
// FileTypeManager by mistake uses PropertiesComponent instead of own state - it should be fixed someday
|
||||
app.getServiceAsync(PropertiesComponent::class.java).join()
|
||||
app.getServiceAsync(FileTypeManager::class.java).join()
|
||||
app.serviceAsync<PropertiesComponent>()
|
||||
app.serviceAsync<FileTypeManager>()
|
||||
|
||||
// ProjectJdkTable wants FileTypeManager
|
||||
launch {
|
||||
// and VirtualFilePointerManager
|
||||
app.getServiceAsync(VirtualFilePointerManager::class.java).join()
|
||||
app.getServiceAsync(ProjectJdkTable::class.java)
|
||||
app.serviceAsync<VirtualFilePointerManager>()
|
||||
app.serviceAsync<ProjectJdkTable>()
|
||||
}
|
||||
|
||||
// wants PropertiesComponent
|
||||
launch { app.getServiceAsync(DebugLogManager::class.java) }
|
||||
launch { app.serviceAsync<DebugLogManager>() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ abstract class ClientSessionImpl(
|
||||
assert(containerState.compareAndSet(ContainerState.PRE_INIT, ContainerState.COMPONENT_CREATED))
|
||||
}
|
||||
|
||||
override suspend fun preloadService(service: ServiceDescriptor): Job? {
|
||||
override suspend fun preloadService(service: ServiceDescriptor) {
|
||||
return ClientId.withClientId(clientId) {
|
||||
super.preloadService(service)
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ internal class ProjectUiFrameAllocator(val options: OpenProjectTask,
|
||||
launch {
|
||||
val frameHelper = deferredProjectFrameHelper.await()
|
||||
val project = rawProjectDeferred.await()
|
||||
val windowManager = ApplicationManager.getApplication().serviceAsync<WindowManager>().await() as WindowManagerImpl
|
||||
val windowManager = ApplicationManager.getApplication().serviceAsync<WindowManager>() as WindowManagerImpl
|
||||
subtask("project frame assigning", Dispatchers.EDT) {
|
||||
windowManager.assignFrame(frameHelper, project)
|
||||
frameHelper.setProject(project)
|
||||
@@ -159,7 +159,7 @@ internal class ProjectUiFrameAllocator(val options: OpenProjectTask,
|
||||
rawProjectDeferred: CompletableDeferred<Project>): FrameLoadingState {
|
||||
var frame = options.frame
|
||||
if (frame == null) {
|
||||
val windowManager = ApplicationManager.getApplication().serviceAsync<WindowManager>().await() as WindowManagerImpl
|
||||
val windowManager = ApplicationManager.getApplication().serviceAsync<WindowManager>() as WindowManagerImpl
|
||||
frame = windowManager.removeAndGetRootFrame()
|
||||
}
|
||||
|
||||
@@ -302,12 +302,12 @@ private suspend fun initFrame(rawProjectDeferred: CompletableDeferred<Project>,
|
||||
}
|
||||
|
||||
private suspend fun restoreEditors(project: Project, deferredProjectFrameHelper: CompletableDeferred<ProjectFrameHelper>) {
|
||||
val fileEditorManager = project.serviceAsync<FileEditorManager>().await() as? FileEditorManagerImpl ?: return
|
||||
val fileEditorManager = project.serviceAsync<FileEditorManager>() as? FileEditorManagerImpl ?: return
|
||||
coroutineScope {
|
||||
// only after FileEditorManager.init - DaemonCodeAnalyzer uses FileEditorManager
|
||||
launch {
|
||||
project.serviceAsync<WolfTheProblemSolver>().join()
|
||||
project.serviceAsync<DaemonCodeAnalyzer>().join()
|
||||
project.serviceAsync<WolfTheProblemSolver>()
|
||||
project.serviceAsync<DaemonCodeAnalyzer>()
|
||||
}
|
||||
|
||||
val (editorComponent, editorState) = fileEditorManager.init()
|
||||
@@ -383,7 +383,7 @@ private fun CoroutineScope.initFrame(deferredProjectFrameHelper: Deferred<Projec
|
||||
reopeningEditorJob: Job,
|
||||
deferredToolbarActionGroups: Deferred<List<Pair<ActionGroup, String>>>) {
|
||||
launch(CoroutineName("tool window pane creation")) {
|
||||
val toolWindowManager = project.serviceAsync<ToolWindowManager>().await() as? ToolWindowManagerImpl ?: return@launch
|
||||
val toolWindowManager = project.serviceAsync<ToolWindowManager>() as? ToolWindowManagerImpl ?: return@launch
|
||||
|
||||
val taskListDeferred = async(CoroutineName("toolwindow init command creation")) {
|
||||
computeToolWindowBeans(project)
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx
|
||||
import com.intellij.openapi.application.impl.LaterInvocator
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.components.serviceIfCreated
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.extensions.PluginDescriptor
|
||||
@@ -945,9 +946,7 @@ fun CoroutineScope.runInitProjectActivities(project: Project) {
|
||||
(StartupManager.getInstance(project) as StartupManagerImpl).initProject()
|
||||
}
|
||||
|
||||
val waitEdtActivity = StartUpMeasurer.startActivity("placing calling projectOpened on event queue")
|
||||
launchAndMeasure("projectOpened event executing", Dispatchers.EDT) {
|
||||
waitEdtActivity.end()
|
||||
launch(CoroutineName("projectOpened event executing") + Dispatchers.EDT) {
|
||||
tracer.spanBuilder("projectOpened event executing").useWithScope2 {
|
||||
@Suppress("DEPRECATION", "removal")
|
||||
ApplicationManager.getApplication().messageBus.syncPublisher(ProjectManager.TOPIC).projectOpened(project)
|
||||
@@ -961,22 +960,13 @@ fun CoroutineScope.runInitProjectActivities(project: Project) {
|
||||
return
|
||||
}
|
||||
|
||||
launchAndMeasure("projectOpened component executing", Dispatchers.EDT) {
|
||||
launch(CoroutineName("projectOpened component executing") + Dispatchers.EDT) {
|
||||
for (component in projectComponents) {
|
||||
try {
|
||||
runCatching {
|
||||
val componentActivity = StartUpMeasurer.startActivity(component.javaClass.name, ActivityCategory.PROJECT_OPEN_HANDLER)
|
||||
component.projectOpened()
|
||||
componentActivity.end()
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}.getOrLogException(LOG)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1196,7 +1186,7 @@ private suspend fun initProject(file: Path,
|
||||
null
|
||||
}
|
||||
else {
|
||||
(project.serviceAsync<FileEditorManager>().await() as? FileEditorManagerImpl)?.initJob
|
||||
(project.serviceAsync<FileEditorManager>() as? FileEditorManagerImpl)?.initJob
|
||||
}
|
||||
|
||||
if (preloadServices) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.vfs.encoding
|
||||
|
||||
import com.intellij.openapi.application.EDT
|
||||
@@ -11,7 +11,7 @@ import kotlinx.coroutines.withContext
|
||||
private class EncodingProjectManagerStartUpActivity : ProjectActivity {
|
||||
override suspend fun execute(project: Project) {
|
||||
// do not try to init on EDT due to VFS usage in loadState
|
||||
val service = project.serviceAsync<EncodingProjectManager>().await() as EncodingProjectManagerImpl
|
||||
val service = project.serviceAsync<EncodingProjectManager>() as EncodingProjectManagerImpl
|
||||
withContext(Dispatchers.EDT) {
|
||||
service.reloadAlreadyLoadedDocuments()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.wm.impl
|
||||
|
||||
import com.intellij.DynamicBundle
|
||||
@@ -280,8 +280,11 @@ open class IdeMenuBar internal constructor() : JMenuBar(), IdeEventQueue.EventDi
|
||||
|
||||
coroutineScope.launch {
|
||||
val app = ApplicationManager.getApplication()
|
||||
val actionManager = app.serviceAsync<ActionManager>().await()
|
||||
app.serviceAsync<CustomActionsSchema>().join()
|
||||
launch {
|
||||
app.serviceAsync<CustomActionsSchema>()
|
||||
}
|
||||
|
||||
val actionManager = app.serviceAsync<ActionManager>()
|
||||
updateActions(actionManager = actionManager, screenMenuPeer = screenMenuPeer)
|
||||
}
|
||||
activity.end()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.wm.impl.headertoolbar
|
||||
|
||||
import com.intellij.accessibility.AccessibilityUtils
|
||||
@@ -65,8 +65,8 @@ internal class MainToolbar: JPanel(HorizontalLayout(10)) {
|
||||
companion object {
|
||||
suspend fun computeActionGroups(): List<Pair<ActionGroup, String>> {
|
||||
val app = ApplicationManager.getApplication() as ComponentManagerEx
|
||||
app.getServiceAsync(ActionManager::class.java).await()
|
||||
val customActionSchema = app.getServiceAsync(CustomActionsSchema::class.java).await()
|
||||
app.getServiceAsync(ActionManager::class.java)
|
||||
val customActionSchema = app.getServiceAsync(CustomActionsSchema::class.java)
|
||||
return computeActionGroups(customActionSchema)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet", "ReplacePutWithAssignment", "LiftReturnOrAssignment")
|
||||
@file:OptIn(FlowPreview::class)
|
||||
|
||||
@@ -59,7 +59,7 @@ class StatusBarWidgetsManager(private val project: Project,
|
||||
|
||||
override val currentFileEditor: StateFlow<FileEditor?> by lazy {
|
||||
flow {
|
||||
emit(project.serviceAsync<FileEditorManager>().await() as FileEditorManagerEx)
|
||||
emit(project.serviceAsync<FileEditorManager>() as FileEditorManagerEx)
|
||||
}
|
||||
.take(1)
|
||||
.flatMapConcat { it.currentFileEditorFlow }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.toolWindow
|
||||
|
||||
import com.intellij.diagnostic.PluginException
|
||||
@@ -156,7 +156,7 @@ class ToolWindowSetInitializer(private val project: Project, private val manager
|
||||
}
|
||||
|
||||
runActivity("ensureToolWindowActionRegistered executing$suffix") {
|
||||
val actionManager = ApplicationManager.getApplication().serviceAsync<ActionManager>().await()
|
||||
val actionManager = ApplicationManager.getApplication().serviceAsync<ActionManager>()
|
||||
for (entry in entries) {
|
||||
ActivateToolWindowAction.ensureToolWindowActionRegistered(entry.toolWindow, actionManager)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ui.jcef
|
||||
|
||||
import com.intellij.openapi.util.registry.RegistryManager
|
||||
import com.intellij.ide.plugins.DynamicPluginListener
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ComponentManagerEx
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.util.registry.RegistryManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Forces JCEF early startup in order to support co-existence with JavaFX (see IDEA-236310).
|
||||
*/
|
||||
private class JBCefStartup {
|
||||
private class JBCefStartup(coroutineScope: CoroutineScope) {
|
||||
@Suppress("unused")
|
||||
private var STARTUP_CLIENT: JBCefClient? = null // auto-disposed along with JBCefApp on IDE shutdown
|
||||
|
||||
@@ -21,16 +22,14 @@ private class JBCefStartup {
|
||||
init {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (!app.isUnitTestMode) {
|
||||
app.coroutineScope.launch {
|
||||
coroutineScope.launch {
|
||||
doInit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun doInit() {
|
||||
@Suppress("SpellCheckingInspection") val isPreinit = (ApplicationManager.getApplication() as ComponentManagerEx)
|
||||
.getServiceAsync(RegistryManager::class.java)
|
||||
.await()
|
||||
@Suppress("SpellCheckingInspection") val isPreinit = ApplicationManager.getApplication().serviceAsync<RegistryManager>()
|
||||
.get("ide.browser.jcef.preinit")
|
||||
if (isPreinit.asBoolean() && JBCefApp.isSupported()) {
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplacePutWithAssignment")
|
||||
|
||||
package com.intellij.serviceContainer
|
||||
@@ -133,7 +133,7 @@ internal sealed class BaseComponentAdapter(
|
||||
PluginException("Cyclic service initialization: ${toString()}", pluginId)
|
||||
}
|
||||
|
||||
return Cancellation.computeInNonCancelableSection<T, RuntimeException> {
|
||||
return Cancellation.withCancelableSection().use {
|
||||
doCreateInstance(keyClass = keyClass, componentManager = componentManager, activityCategory = activityCategory)
|
||||
}
|
||||
}
|
||||
@@ -176,10 +176,10 @@ internal sealed class BaseComponentAdapter(
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
suspend fun <T : Any> getInstanceAsync(componentManager: ComponentManagerImpl, keyClass: Class<T>?): Deferred<T> {
|
||||
suspend fun <T : Any> getInstanceAsync(componentManager: ComponentManagerImpl, keyClass: Class<T>?): T {
|
||||
return withContext(NonCancellable) {
|
||||
if (!IS_DEFERRED_PREPARED.compareAndSet(this@BaseComponentAdapter, false, true)) {
|
||||
return@withContext deferred as Deferred<T>
|
||||
return@withContext (deferred as Deferred<T>).await()
|
||||
}
|
||||
|
||||
createInstance(
|
||||
@@ -187,7 +187,6 @@ internal sealed class BaseComponentAdapter(
|
||||
componentManager = componentManager,
|
||||
activityCategory = if (StartUpMeasurer.isEnabled()) getActivityCategory(componentManager) else null,
|
||||
)
|
||||
deferred as Deferred<T>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ abstract class ComponentManagerImpl(
|
||||
}
|
||||
|
||||
for (componentAdapter in componentAdapters.getImmutableSet()) {
|
||||
componentAdapter.getInstanceAsync<Any>(this, keyClass = null).join()
|
||||
componentAdapter.getInstanceAsync<Any>(this, keyClass = null)
|
||||
}
|
||||
|
||||
activity?.end()
|
||||
@@ -640,11 +640,11 @@ abstract class ComponentManagerImpl(
|
||||
return result
|
||||
}
|
||||
|
||||
final override suspend fun <T : Any> getServiceAsync(keyClass: Class<T>): Deferred<T> {
|
||||
final override suspend fun <T : Any> getServiceAsync(keyClass: Class<T>): T {
|
||||
return getServiceAsyncIfDefined(keyClass) ?: throw RuntimeException("service is not defined for $keyClass")
|
||||
}
|
||||
|
||||
suspend fun <T : Any> getServiceAsyncIfDefined(keyClass: Class<T>): Deferred<T>? {
|
||||
suspend fun <T : Any> getServiceAsyncIfDefined(keyClass: Class<T>): T? {
|
||||
val key = keyClass.name
|
||||
val adapter = componentKeyToAdapter.get(key) ?: return null
|
||||
check(adapter is ServiceComponentAdapter) {
|
||||
@@ -1136,16 +1136,8 @@ abstract class ComponentManagerImpl(
|
||||
return
|
||||
}
|
||||
|
||||
scope.launch {
|
||||
val activity = StartUpMeasurer.startActivity("${service.`interface`} preloading")
|
||||
val job = preloadService(service) ?: return@launch
|
||||
if (scope === syncScope) {
|
||||
job.join()
|
||||
activity.end()
|
||||
}
|
||||
else {
|
||||
job.invokeOnCompletion { activity.end() }
|
||||
}
|
||||
scope.launch(CoroutineName("${service.`interface`} preloading")) {
|
||||
preloadService(service)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1159,19 +1151,14 @@ abstract class ComponentManagerImpl(
|
||||
onlyIfAwait: Boolean) {
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
protected open suspend fun preloadService(service: ServiceDescriptor): Job? {
|
||||
val adapter = componentKeyToAdapter.get(service.getInterface()) as ServiceComponentAdapter? ?: return null
|
||||
val deferred = adapter.getInstanceAsync<Any>(componentManager = this, keyClass = null)
|
||||
if (deferred.isCompleted) {
|
||||
val instance = deferred.getCompleted()
|
||||
val implClass = instance.javaClass
|
||||
// well, we don't know the interface class, so we cannot add any service to a hot cache
|
||||
if (Modifier.isFinal(implClass.modifiers)) {
|
||||
serviceInstanceHotCache.putIfAbsent(implClass, instance)
|
||||
}
|
||||
protected open suspend fun preloadService(service: ServiceDescriptor) {
|
||||
val adapter = componentKeyToAdapter.get(service.getInterface()) as ServiceComponentAdapter? ?: return
|
||||
val instance = adapter.getInstanceAsync<Any>(componentManager = this, keyClass = null)
|
||||
val implClass = instance.javaClass
|
||||
// well, we don't know the interface class, so we cannot add any service to a hot cache
|
||||
if (Modifier.isFinal(implClass.modifiers)) {
|
||||
serviceInstanceHotCache.putIfAbsent(implClass, instance)
|
||||
}
|
||||
return deferred
|
||||
}
|
||||
|
||||
override fun isDisposed(): Boolean {
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.diagnostic
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
inline fun <T> Activity?.runChild(name: String, task: () -> T): T {
|
||||
val activity = this?.startChild(name)
|
||||
@@ -21,17 +15,4 @@ inline fun <T> runActivity(@NonNls name: String, category: ActivityCategory = Ac
|
||||
val result = task()
|
||||
activity?.end()
|
||||
return result
|
||||
}
|
||||
|
||||
@Internal
|
||||
inline fun CoroutineScope.launchAndMeasure(
|
||||
activityName: String,
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
crossinline block: suspend CoroutineScope.() -> Unit
|
||||
): Job {
|
||||
return launch(context) {
|
||||
runActivity(activityName) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,7 @@ class VcsProjectLog(private val project: Project, private val coroutineScope: Co
|
||||
return null
|
||||
}
|
||||
|
||||
val projectLevelVcsManager = project.serviceAsync<ProjectLevelVcsManager>().await()
|
||||
val projectLevelVcsManager = project.serviceAsync<ProjectLevelVcsManager>()
|
||||
val logProviders = VcsLogManager.findLogProviders(projectLevelVcsManager.allVcsRoots.toList(), project)
|
||||
if (logProviders.isEmpty()) {
|
||||
return null
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.lang.ant.config.impl
|
||||
|
||||
import com.intellij.lang.ant.AntDisposable
|
||||
@@ -24,7 +24,7 @@ private class AntShortcutStartupActivity : ProjectActivity {
|
||||
|
||||
override suspend fun execute(project: Project) {
|
||||
val prefix = AntConfiguration.getActionIdPrefix(project)
|
||||
val actionManager = ApplicationManager.getApplication().serviceAsync<ActionManager>().await()
|
||||
val actionManager = ApplicationManager.getApplication().serviceAsync<ActionManager>()
|
||||
for (keymap in KeymapManagerEx.getInstanceEx().allKeymaps) {
|
||||
for (id in keymap.actionIdList) {
|
||||
if (id.startsWith(prefix) && actionManager.getAction(id) == null) {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.macros
|
||||
|
||||
import com.intellij.ide.ApplicationInitializedListener
|
||||
import com.intellij.ide.SaveAndSyncHandler
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.PathMacros
|
||||
import com.intellij.openapi.components.ComponentManagerEx
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.extensions.ExtensionNotApplicableException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
@@ -15,18 +18,21 @@ import kotlinx.coroutines.launch
|
||||
* Application-wide path macros are visible in the "Path Variables" UI. Since we don't want to confuse users with application-wide
|
||||
* KOTLIN_BUNDLED stale value in the UI, we clean the application-wide value in this class
|
||||
*/
|
||||
private class ApplicationWideKotlinBundledPathMacroCleaner {
|
||||
private class ApplicationWideKotlinBundledPathMacroCleaner : ApplicationInitializedListener {
|
||||
init {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (!app.isHeadlessEnvironment) {
|
||||
app.coroutineScope.launch {
|
||||
val pathMacros = (app as ComponentManagerEx).getServiceAsync(PathMacros::class.java).await()
|
||||
if (pathMacros.getValue(KOTLIN_BUNDLED) != null) {
|
||||
pathMacros.setMacro(KOTLIN_BUNDLED, null)
|
||||
// Flush settings otherwise they may stay in config/idea/options/path.macros.xml and then leak into the JPS
|
||||
// (because JPS "reimplements" Path macro subsystem and, basically, just reads the `path.macros.xml` file again on its own)
|
||||
SaveAndSyncHandler.getInstance().scheduleSave(SaveAndSyncHandler.SaveTask(null, true))
|
||||
}
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment) {
|
||||
throw ExtensionNotApplicableException.create()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun execute(asyncScope: CoroutineScope) {
|
||||
asyncScope.launch {
|
||||
val pathMacros = ApplicationManager.getApplication().serviceAsync<PathMacros>()
|
||||
if (pathMacros.getValue(KOTLIN_BUNDLED) != null) {
|
||||
pathMacros.setMacro(KOTLIN_BUNDLED, null)
|
||||
// Flush settings otherwise they may stay in config/idea/options/path.macros.xml and then leak into the JPS
|
||||
// (because JPS "reimplements" Path macro subsystem and, basically, just reads the `path.macros.xml` file again on its own)
|
||||
SaveAndSyncHandler.getInstance().scheduleSave(SaveAndSyncHandler.SaveTask(null, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.quickfix.QuickFixes"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightSettings"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.editor.KotlinEditorOptions"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.macros.ApplicationWideKotlinBundledPathMacroCleaner" preload="true"/>
|
||||
<applicationInitializedListener implementation="org.jetbrains.kotlin.idea.macros.ApplicationWideKotlinBundledPathMacroCleaner"/>
|
||||
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.core.KotlinPluginDisposable"/>
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.core.util.ProjectJob"/>
|
||||
|
||||
Reference in New Issue
Block a user