serviceAsync should not return Deferred

GitOrigin-RevId: ab482e63c006f1c77ceafd8124357b2a39d1fe3d
This commit is contained in:
Vladimir Krivosheev
2023-05-16 15:10:28 +02:00
committed by intellij-monorepo-bot
parent 3b54501d48
commit b2ff586ecf
23 changed files with 119 additions and 140 deletions

View File

@@ -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()
}
}

View File

@@ -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();
}
};
}
}

View File

@@ -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)
}
}

View File

@@ -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)
}

View File

@@ -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() }

View File

@@ -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()
}

View File

@@ -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>() }
}
}

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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()
}

View File

@@ -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()

View File

@@ -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)
}

View File

@@ -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 }

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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>
}
}

View File

@@ -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 {

View File

@@ -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()
}
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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))
}
}
}

View File

@@ -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"/>