From e1e77bdf4f70bd2dd3bace8439a9a6fae991d546 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sat, 2 Sep 2023 21:19:11 +0300 Subject: [PATCH] IDEA-330211 convert UIThemeProvider from Java to Kotlin GitOrigin-RevId: f45761263f910e7e1e9da9d31df840b58c0d44c7 --- .../com/intellij/ide/ui/UIThemeProvider.kt | 112 +++++++++--------- .../ide/ui/laf/UiThemeProviderListManager.kt | 37 +++--- .../src/ThemeEPPathReferenceContributor.java | 4 +- 3 files changed, 79 insertions(+), 74 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/UIThemeProvider.kt b/platform/platform-impl/src/com/intellij/ide/ui/UIThemeProvider.kt index 31fa98730ea7..0231cce88fac 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/UIThemeProvider.kt +++ b/platform/platform-impl/src/com/intellij/ide/ui/UIThemeProvider.kt @@ -1,92 +1,94 @@ // 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; +package com.intellij.ide.ui -import com.intellij.diagnostic.PluginException; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.extensions.PluginAware; -import com.intellij.openapi.extensions.PluginDescriptor; -import com.intellij.openapi.extensions.RequiredElement; -import com.intellij.util.ResourceUtil; -import com.intellij.util.xmlb.annotations.Attribute; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.util.function.Function; +import com.intellij.diagnostic.PluginException +import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.extensions.PluginAware +import com.intellij.openapi.extensions.PluginDescriptor +import com.intellij.openapi.extensions.RequiredElement +import com.intellij.util.ResourceUtil +import com.intellij.util.xmlb.annotations.Attribute +import org.jetbrains.annotations.ApiStatus.Internal +import java.io.IOException +import java.util.function.Function /** * Extension point for adding UI themes. - *
- * Read more about themes development. + * Read more about [themes development](https://plugins.jetbrains.com/docs/intellij/theme-structure.html). * * @author Konstantin Bulenkov */ -public final class UIThemeProvider implements PluginAware { - public static final ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.themeProvider"); - private PluginDescriptor pluginDescriptor; +class UIThemeProvider : PluginAware { + companion object { + @JvmField + val EP_NAME: ExtensionPointName = ExtensionPointName("com.intellij.themeProvider") + } + + private var pluginDescriptor: PluginDescriptor? = null /** - * Path to {@code *.theme.json} file + * Path to `*.theme.json` file */ @Attribute("path") @RequiredElement - public String path; + @JvmField + var path: String? = null /** * Unique theme identifier. For example, MyTheme123 */ @Attribute("id") @RequiredElement - public String id; + @JvmField + var id: String? = null @Attribute("parentTheme") - public @Nullable String parentTheme; + var parentTheme: String? = null - @Attribute("targetUi") public @NotNull TargetUIType targetUI = TargetUIType.UNSPECIFIED; + @Attribute("targetUi") + @JvmField + var targetUI: TargetUIType = TargetUIType.UNSPECIFIED - @ApiStatus.Internal - public byte[] getThemeJson() throws IOException { - String path = this.path; - path = path.charAt(0) == '/' ? path.substring(1) : path; - return ResourceUtil.getResourceAsBytes(path, pluginDescriptor.getClassLoader()); + @Throws(IOException::class) + @Internal + fun getThemeJson(): ByteArray? { + var path = path!! + path = if (path[0] == '/') path.substring(1) else path + return ResourceUtil.getResourceAsBytes(path, pluginDescriptor!!.getClassLoader()) } - public @Nullable UITheme createTheme( - @Nullable UITheme parentTheme, - @Nullable UITheme defaultDarkParent, - @Nullable UITheme defaultLightParent) { - if (defaultDarkParent != null && defaultDarkParent.getId().equals(id)) { - return defaultDarkParent; + fun createTheme(parentTheme: UITheme?, defaultDarkParent: UITheme?, defaultLightParent: UITheme?): UITheme? { + if (defaultDarkParent != null && defaultDarkParent.id == id) { + return defaultDarkParent } - if (defaultLightParent != null && defaultLightParent.getId().equals(id)) { - return defaultLightParent; + if (defaultLightParent != null && defaultLightParent.id == id) { + return defaultLightParent } + try { - ClassLoader classLoader = pluginDescriptor.getPluginClassLoader(); - byte[] stream = getThemeJson(); + val classLoader = pluginDescriptor!!.getPluginClassLoader() + val stream = getThemeJson() if (stream == null) { - Logger.getInstance(getClass()).warn(new PluginException( - "Cannot find theme resource: " + path + " (classLoader=" + classLoader + ", pluginDescriptor=" + pluginDescriptor + ")", - pluginDescriptor.getPluginId() - )); - return null; + thisLogger().warn(PluginException( + "Cannot find theme resource: $path (classLoader=$classLoader, pluginDescriptor=$pluginDescriptor)", + pluginDescriptor!!.getPluginId() + )) + return null } - return UITheme.loadFromJson(parentTheme, stream, id, classLoader, Function.identity(), defaultDarkParent, defaultLightParent); + return UITheme.loadFromJson(parentTheme, stream, id!!, classLoader, Function.identity(), defaultDarkParent, defaultLightParent) } - catch (Throwable e) { - Logger.getInstance(getClass()).warn(new PluginException( - "error loading UITheme '" + path + "', pluginDescriptor=" + pluginDescriptor, + catch (e: Throwable) { + thisLogger().warn(PluginException( + "error loading UITheme '$path', pluginDescriptor=$pluginDescriptor", e, - pluginDescriptor.getPluginId() - )); - return null; + pluginDescriptor!!.getPluginId() + )) + return null } } - @Override - public void setPluginDescriptor(@NotNull PluginDescriptor pluginDescriptor) { - this.pluginDescriptor = pluginDescriptor; + override fun setPluginDescriptor(pluginDescriptor: PluginDescriptor) { + this.pluginDescriptor = pluginDescriptor } } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/UiThemeProviderListManager.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/UiThemeProviderListManager.kt index 92d4dc39e539..b39a67c3d594 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/UiThemeProviderListManager.kt +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/UiThemeProviderListManager.kt @@ -18,6 +18,7 @@ import com.intellij.util.graph.OutboundSemiGraph internal class UiThemeProviderListManager { companion object { fun getInstance(): UiThemeProviderListManager = service() + internal const val DEFAULT_DARK_PARENT_THEME = "Darcula" internal const val DEFAULT_LIGHT_PARENT_THEME = "IntelliJ" } @@ -41,10 +42,12 @@ internal class UiThemeProviderListManager { } val parentTheme = findParentTheme(lafList, provider.parentTheme) - val theme = provider.createTheme(parentTheme, - lafMap.keys.single { it.theme.id == DEFAULT_DARK_PARENT_THEME }.theme, - lafMap.keys.single { it.theme.id == DEFAULT_LIGHT_PARENT_THEME }.theme) ?: return null - editorColorManager().handleThemeAdded(theme) + val theme = provider.createTheme( + parentTheme = parentTheme, + defaultDarkParent = lafMap.keys.single { it.theme.id == DEFAULT_DARK_PARENT_THEME }.theme, + defaultLightParent = lafMap.keys.single { it.theme.id == DEFAULT_LIGHT_PARENT_THEME }.theme, + ) ?: return null + editorColorManager.handleThemeAdded(theme) val newLaF = UIThemeLookAndFeelInfoImpl(theme) lafMap = lafMap + Pair(newLaF, provider.targetUI) return newLaF @@ -53,35 +56,34 @@ internal class UiThemeProviderListManager { fun themeProviderRemoved(provider: UIThemeProvider): UIThemeLookAndFeelInfo? { val oldLaF = findLaFByProviderId(provider) ?: return null lafMap = lafMap - oldLaF - editorColorManager().handleThemeRemoved(oldLaF.theme) + editorColorManager.handleThemeRemoved(oldLaF.theme) return oldLaF } - private fun findLaFById(id: String) = lafList.find { it.theme.id == id } + private fun findLaFById(id: String) = lafList.firstOrNull { it.theme.id == id } - private fun findLaFByProviderId(provider: UIThemeProvider) = findLaFById(provider.id) + private fun findLaFByProviderId(provider: UIThemeProvider) = provider.id?.let { findLaFById(it) } } private fun computeMap(): Map { val map = LinkedHashMap() val orderedProviders = sortTopologically(UIThemeProvider.EP_NAME.extensionList, { it.id }, { it.parentTheme }) - val darcula = orderedProviders.single{ it.id == UiThemeProviderListManager.DEFAULT_DARK_PARENT_THEME } - .createTheme(null, null, null) - val intelliJ = orderedProviders.single{ it.id == UiThemeProviderListManager.DEFAULT_LIGHT_PARENT_THEME } - .createTheme(darcula, null, null) + val darcula = orderedProviders.single { it.id == UiThemeProviderListManager.DEFAULT_DARK_PARENT_THEME } + .createTheme(parentTheme = null, defaultDarkParent = null, defaultLightParent = null) + val intelliJ = orderedProviders.single { it.id == UiThemeProviderListManager.DEFAULT_LIGHT_PARENT_THEME } + .createTheme(parentTheme = darcula, defaultDarkParent = null, defaultLightParent = null) for (provider in orderedProviders) { val parentTheme = findParentTheme(map.keys, provider.parentTheme) - val theme = UIThemeLookAndFeelInfoImpl(provider.createTheme(parentTheme, darcula, intelliJ) ?: continue) + val theme = UIThemeLookAndFeelInfoImpl(provider.createTheme(parentTheme = parentTheme, + defaultDarkParent = darcula, + defaultLightParent = intelliJ) ?: continue) map.put(theme, provider.targetUI) } return map } private fun findParentTheme(themes: Collection, parentId: String?): UITheme? { - if (parentId == null) { - return null - } - return themes.asSequence().map { it.theme }.find { it.id == parentId } + return if (parentId == null) null else themes.asSequence().map { it.theme }.firstOrNull { it.id == parentId } } private fun sortTopologically(list: List, idFun: (T) -> K, parentIdFun: (T) -> K?): List { @@ -100,4 +102,5 @@ private fun sortTopologically(list: List, idFun: (T) -> K, parentIdFun private const val DEFAULT_LIGHT_THEME_ID = "JetBrainsLightTheme" -private fun editorColorManager() = EditorColorsManager.getInstance() as EditorColorsManagerImpl +private val editorColorManager: EditorColorsManagerImpl + get() = EditorColorsManager.getInstance() as EditorColorsManagerImpl diff --git a/plugins/devkit/intellij.devkit.themes/src/ThemeEPPathReferenceContributor.java b/plugins/devkit/intellij.devkit.themes/src/ThemeEPPathReferenceContributor.java index 93c56546dd93..4d064b829cce 100644 --- a/plugins/devkit/intellij.devkit.themes/src/ThemeEPPathReferenceContributor.java +++ b/plugins/devkit/intellij.devkit.themes/src/ThemeEPPathReferenceContributor.java @@ -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 org.jetbrains.idea.devkit.themes; import com.intellij.ide.ui.UIThemeProvider; @@ -16,7 +16,7 @@ import org.jetbrains.idea.devkit.dom.ExtensionPoint; import org.jetbrains.idea.devkit.themes.metadata.UIThemeMetadataService; import org.jetbrains.idea.devkit.util.PsiUtil; -public class ThemeEPPathReferenceContributor extends PsiReferenceContributor { +final class ThemeEPPathReferenceContributor extends PsiReferenceContributor { @Override public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withLocalName("path"), new PsiReferenceProvider() {