diff --git a/components/resources/library/src/androidInstrumentedTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.android.kt b/components/resources/library/src/androidInstrumentedTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.android.kt index 83c36d588e..6783007f16 100644 --- a/components/resources/library/src/androidInstrumentedTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.android.kt +++ b/components/resources/library/src/androidInstrumentedTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.android.kt @@ -12,7 +12,7 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith -@OptIn(ExperimentalTestApi::class) +@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class, InternalResourceApi::class) class ComposeResourceTest { @Before diff --git a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/FontResources.android.kt b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/FontResources.android.kt index 50891efb49..46212bb3dc 100644 --- a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/FontResources.android.kt +++ b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/FontResources.android.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.* +@ExperimentalResourceApi @Composable actual fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): Font { val environment = LocalComposeEnvironment.current.rememberEnvironment() diff --git a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.android.kt b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.android.kt index cc4c816ab3..205de0e47c 100644 --- a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.android.kt +++ b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.android.kt @@ -4,6 +4,7 @@ import android.content.res.Configuration import android.content.res.Resources import java.util.* +@OptIn(InternalResourceApi::class) internal actual fun getSystemEnvironment(): ResourceEnvironment { val locale = Locale.getDefault() val configuration = Resources.getSystem().configuration diff --git a/components/resources/library/src/blockingMain/kotlin/org/jetbrains/compose/resources/Resource.blocking.kt b/components/resources/library/src/blockingMain/kotlin/org/jetbrains/compose/resources/Resource.blocking.kt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/FontResources.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/FontResources.kt index e060f02f56..9aee02b875 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/FontResources.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/FontResources.kt @@ -12,8 +12,11 @@ import androidx.compose.ui.text.font.* * * @see Resource */ +@OptIn(InternalResourceApi::class) +@ExperimentalResourceApi @Immutable -class FontResource(id: String, items: Set): Resource(id, items) +class FontResource +@InternalResourceApi constructor(id: String, items: Set): Resource(id, items) /** * Creates an [FontResource] object with the specified path. @@ -21,6 +24,7 @@ class FontResource(id: String, items: Set): Resource(id, items) * @param path The path to the font resource file. * @return A new [FontResource] object. */ +@OptIn(InternalResourceApi::class) @ExperimentalResourceApi fun FontResource(path: String): FontResource = FontResource( id = "FontResource:$path", @@ -39,6 +43,7 @@ fun FontResource(path: String): FontResource = FontResource( * @throws NotFoundException if the specified resource ID is not found. */ @Composable +@ExperimentalResourceApi expect fun Font( resource: FontResource, weight: FontWeight = FontWeight.Normal, diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt index 0545f178a5..7916ab5238 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt @@ -20,8 +20,11 @@ import org.jetbrains.compose.resources.vector.xmldom.Element * @param id The unique identifier of the drawable resource. * @param items The set of resource items associated with the image resource. */ +@OptIn(InternalResourceApi::class) +@ExperimentalResourceApi @Immutable -class DrawableResource(id: String, items: Set) : Resource(id, items) +class DrawableResource +@InternalResourceApi constructor(id: String, items: Set) : Resource(id, items) /** * Creates an [DrawableResource] object with the specified path. @@ -29,6 +32,7 @@ class DrawableResource(id: String, items: Set) : Resource(id, item * @param path The path of the drawable resource. * @return An [DrawableResource] object. */ +@OptIn(InternalResourceApi::class) @ExperimentalResourceApi fun DrawableResource(path: String): DrawableResource = DrawableResource( id = "DrawableResource:$path", @@ -42,6 +46,7 @@ fun DrawableResource(path: String): DrawableResource = DrawableResource( * @param resource The drawable resource to be used. * @return The [Painter] loaded from the resource. */ +@ExperimentalResourceApi @Composable fun painterResource(resource: DrawableResource): Painter { val environment = LocalComposeEnvironment.current.rememberEnvironment() @@ -62,6 +67,7 @@ private val emptyImageBitmap: ImageBitmap by lazy { ImageBitmap(1, 1) } * @param resource The drawable resource to be used. * @return The ImageBitmap loaded from the resource. */ +@ExperimentalResourceApi @Composable fun imageResource(resource: DrawableResource): ImageBitmap { val resourceReader = LocalResourceReader.current @@ -85,6 +91,7 @@ private val emptyImageVector: ImageVector by lazy { * @param resource The drawable resource to be used. * @return The ImageVector loaded from the resource. */ +@ExperimentalResourceApi @Composable fun vectorResource(resource: DrawableResource): ImageVector { val resourceReader = LocalResourceReader.current diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Qualifier.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Qualifier.kt index 5f289c1ff5..150f144bc3 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Qualifier.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Qualifier.kt @@ -2,14 +2,17 @@ package org.jetbrains.compose.resources interface Qualifier +@InternalResourceApi data class LanguageQualifier( val language: String ) : Qualifier +@InternalResourceApi data class RegionQualifier( val region: String ) : Qualifier +@InternalResourceApi enum class ThemeQualifier : Qualifier { LIGHT, DARK; @@ -21,6 +24,7 @@ enum class ThemeQualifier : Qualifier { } //https://developer.android.com/guide/topics/resources/providing-resources +@InternalResourceApi enum class DensityQualifier(val dpi: Int) : Qualifier { LDPI(120), MDPI(160), diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Resource.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Resource.kt index 38e9e371f3..c9074f65fb 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Resource.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Resource.kt @@ -14,8 +14,10 @@ annotation class InternalResourceApi * @property id The ID of the resource. * @property items The set of resource items associated with the resource. */ +@ExperimentalResourceApi @Immutable -sealed class Resource( +sealed class Resource +@InternalResourceApi constructor( internal val id: String, internal val items: Set ) { @@ -39,6 +41,7 @@ sealed class Resource( * @property qualifiers The qualifiers of the resource item. * @property path The path of the resource item. */ +@InternalResourceApi @Immutable data class ResourceItem( internal val qualifiers: Set, diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.kt index cb53469131..561abf3745 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.intl.Locale +@OptIn(InternalResourceApi::class) internal data class ResourceEnvironment( val language: LanguageQualifier, val region: RegionQualifier, @@ -17,6 +18,7 @@ internal interface ComposeEnvironment { fun rememberEnvironment(): ResourceEnvironment } +@OptIn(InternalResourceApi::class) internal val DefaultComposeEnvironment = object : ComposeEnvironment { @Composable override fun rememberEnvironment(): ResourceEnvironment { @@ -48,6 +50,7 @@ internal expect fun getSystemEnvironment(): ResourceEnvironment */ internal var getResourceEnvironment = ::getSystemEnvironment +@OptIn(InternalResourceApi::class, ExperimentalResourceApi::class) internal fun Resource.getPathByEnvironment(environment: ResourceEnvironment): String { //Priority of environments: https://developer.android.com/guide/topics/resources/providing-resources#table2 items.toList() @@ -68,6 +71,7 @@ internal fun Resource.getPathByEnvironment(environment: ResourceEnvironment): St } } +@OptIn(InternalResourceApi::class) private fun List.filterBy(qualifier: Qualifier): List { //Android has a slightly different algorithm, //but it provides the same result: https://developer.android.com/guide/topics/resources/providing-resources#BestMatch diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt index 044a6f5a84..c8d7f9ac1a 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt @@ -2,6 +2,7 @@ package org.jetbrains.compose.resources import androidx.compose.runtime.staticCompositionLocalOf +@ExperimentalResourceApi class MissingResourceException(path: String) : Exception("Missing resource with path: $path") /** diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/StringResources.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/StringResources.kt index c80c9488b4..1dcebfa830 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/StringResources.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/StringResources.kt @@ -16,8 +16,11 @@ private val SimpleStringFormatRegex = Regex("""%(\d)\$[ds]""") * @param key The key used to retrieve the string resource. * @param items The set of resource items associated with the string resource. */ +@OptIn(InternalResourceApi::class) +@ExperimentalResourceApi @Immutable -class StringResource(id: String, val key: String, items: Set): Resource(id, items) +class StringResource +@InternalResourceApi constructor(id: String, val key: String, items: Set): Resource(id, items) private sealed interface StringItem { data class Value(val text: String) : StringItem @@ -69,6 +72,7 @@ private suspend fun parseStringXml(path: String, resourceReader: ResourceReader) * * @throws IllegalArgumentException If the provided ID is not found in the resource file. */ +@ExperimentalResourceApi @Composable fun stringResource(resource: StringResource): String { val resourceReader = LocalResourceReader.current @@ -86,9 +90,11 @@ fun stringResource(resource: StringResource): String { * * @throws IllegalArgumentException If the provided ID is not found in the resource file. */ +@ExperimentalResourceApi suspend fun getString(resource: StringResource): String = loadString(resource, DefaultResourceReader, getResourceEnvironment()) +@OptIn(ExperimentalResourceApi::class) private suspend fun loadString( resource: StringResource, resourceReader: ResourceReader, @@ -110,6 +116,7 @@ private suspend fun loadString( * * @throws IllegalArgumentException If the provided ID is not found in the resource file. */ +@ExperimentalResourceApi @Composable fun stringResource(resource: StringResource, vararg formatArgs: Any): String { val resourceReader = LocalResourceReader.current @@ -129,6 +136,7 @@ fun stringResource(resource: StringResource, vararg formatArgs: Any): String { * * @throws IllegalArgumentException If the provided ID is not found in the resource file. */ +@ExperimentalResourceApi suspend fun getString(resource: StringResource, vararg formatArgs: Any): String = loadString( resource, formatArgs.map { it.toString() }, @@ -136,6 +144,7 @@ suspend fun getString(resource: StringResource, vararg formatArgs: Any): String getResourceEnvironment() ) +@OptIn(ExperimentalResourceApi::class) private suspend fun loadString( resource: StringResource, args: List, @@ -156,6 +165,7 @@ private suspend fun loadString( * * @throws IllegalStateException if the string array with the given ID is not found. */ +@ExperimentalResourceApi @Composable fun stringArrayResource(resource: StringResource): List { val resourceReader = LocalResourceReader.current @@ -173,9 +183,11 @@ fun stringArrayResource(resource: StringResource): List { * * @throws IllegalStateException if the string array with the given ID is not found. */ +@ExperimentalResourceApi suspend fun getStringArray(resource: StringResource): List = loadStringArray(resource, DefaultResourceReader, getResourceEnvironment()) +@OptIn(ExperimentalResourceApi::class) private suspend fun loadStringArray( resource: StringResource, resourceReader: ResourceReader, diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/MalformedXMLException.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/MalformedXMLException.kt index 50c9c221ce..48bb17f371 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/MalformedXMLException.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/MalformedXMLException.kt @@ -1,6 +1,9 @@ package org.jetbrains.compose.resources.vector.xmldom +import org.jetbrains.compose.resources.ExperimentalResourceApi + /** * Error throw when parsed XML is malformed */ +@ExperimentalResourceApi class MalformedXMLException(message: String?) : Exception(message) diff --git a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ResourceTest.kt b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ResourceTest.kt index 5c5c828748..36fd4230c8 100644 --- a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ResourceTest.kt +++ b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ResourceTest.kt @@ -10,6 +10,7 @@ import org.jetbrains.compose.resources.ThemeQualifier.DARK import org.jetbrains.compose.resources.ThemeQualifier.LIGHT import kotlin.test.* +@OptIn(ExperimentalResourceApi::class, InternalResourceApi::class) class ResourceTest { @Test fun testResourceEquals() = runBlockingTest { diff --git a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestComposeEnvironment.kt b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestComposeEnvironment.kt index ad19013d8b..c2491b5e88 100644 --- a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestComposeEnvironment.kt +++ b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestComposeEnvironment.kt @@ -2,6 +2,7 @@ package org.jetbrains.compose.resources import androidx.compose.runtime.Composable +@OptIn(InternalResourceApi::class) internal fun getTestEnvironment() = ResourceEnvironment( language = LanguageQualifier("en"), region = RegionQualifier("US"), diff --git a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestUtils.kt b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestUtils.kt index b308653028..cd0658f53d 100644 --- a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestUtils.kt +++ b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestUtils.kt @@ -6,6 +6,7 @@ expect class TestReturnType expect fun runBlockingTest(block: suspend CoroutineScope.() -> Unit): TestReturnType +@OptIn(InternalResourceApi::class, ExperimentalResourceApi::class) internal fun TestStringResource(key: String) = StringResource( "STRING:$key", key, diff --git a/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.desktop.kt b/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.desktop.kt index 8c45734ebe..5b14bd60d0 100644 --- a/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.desktop.kt +++ b/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.desktop.kt @@ -5,6 +5,7 @@ import org.jetbrains.skiko.currentSystemTheme import java.awt.Toolkit import java.util.* +@OptIn(InternalResourceApi::class) internal actual fun getSystemEnvironment(): ResourceEnvironment { val locale = Locale.getDefault() //FIXME: don't use skiko internals diff --git a/components/resources/library/src/desktopTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.desktop.kt b/components/resources/library/src/desktopTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.desktop.kt index 83c36d588e..6783007f16 100644 --- a/components/resources/library/src/desktopTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.desktop.kt +++ b/components/resources/library/src/desktopTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.desktop.kt @@ -12,7 +12,7 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith -@OptIn(ExperimentalTestApi::class) +@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class, InternalResourceApi::class) class ComposeResourceTest { @Before diff --git a/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.ios.kt b/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.ios.kt index 780e76fcaa..b941d0ff10 100644 --- a/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.ios.kt +++ b/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.ios.kt @@ -4,6 +4,7 @@ import platform.Foundation.* import platform.UIKit.UIScreen import platform.UIKit.UIUserInterfaceStyle +@OptIn(InternalResourceApi::class) internal actual fun getSystemEnvironment(): ResourceEnvironment { val locale = NSLocale.currentLocale() diff --git a/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt b/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt index 484062e735..0a81769a56 100644 --- a/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt +++ b/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt @@ -6,6 +6,8 @@ import platform.Foundation.NSBundle import platform.Foundation.NSFileManager import platform.posix.memcpy +@OptIn(ExperimentalResourceApi::class) +@InternalResourceApi actual suspend fun readResourceBytes(path: String): ByteArray { val fileManager = NSFileManager.defaultManager() // todo: support fallback path at bundle root? diff --git a/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ImageResources.js.kt b/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ImageResources.js.kt index 725ffd532d..8061e6529b 100644 --- a/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ImageResources.js.kt +++ b/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ImageResources.js.kt @@ -3,6 +3,7 @@ package org.jetbrains.compose.resources import org.jetbrains.compose.resources.vector.xmldom.* import org.w3c.dom.parsing.DOMParser +@OptIn(ExperimentalResourceApi::class) internal actual fun ByteArray.toXmlElement(): Element { val xmlString = decodeToString() val xmlDom = DOMParser().parseFromString(xmlString, "application/xml") diff --git a/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.js.kt b/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.js.kt index 4039c79438..589e0b8587 100644 --- a/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.js.kt +++ b/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.js.kt @@ -9,6 +9,7 @@ private external class Intl { } } +@OptIn(InternalResourceApi::class) internal actual fun getSystemEnvironment(): ResourceEnvironment { val locale = Intl.Locale(window.navigator.language) val isDarkTheme = window.matchMedia("(prefers-color-scheme: dark)").matches diff --git a/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt b/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt index 5ae6dce1b2..8cfb63b243 100644 --- a/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt +++ b/components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt @@ -9,6 +9,7 @@ private fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this, 0, byteLength).unsafeCast() @OptIn(ExperimentalResourceApi::class) +@InternalResourceApi actual suspend fun readResourceBytes(path: String): ByteArray { val resPath = WebResourcesConfiguration.getResourcePath(path) val response = window.fetch(resPath).await() diff --git a/components/resources/library/src/jvmAndAndroidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.jvmAndAndroid.kt b/components/resources/library/src/jvmAndAndroidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.jvmAndAndroid.kt index c19aee37e6..9d393b859a 100644 --- a/components/resources/library/src/jvmAndAndroidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.jvmAndAndroid.kt +++ b/components/resources/library/src/jvmAndAndroidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.jvmAndAndroid.kt @@ -2,6 +2,8 @@ package org.jetbrains.compose.resources private object JvmResourceReader +@OptIn(ExperimentalResourceApi::class) +@InternalResourceApi actual suspend fun readResourceBytes(path: String): ByteArray { val classLoader = Thread.currentThread().contextClassLoader ?: JvmResourceReader.javaClass.classLoader val resource = classLoader.getResourceAsStream(path) ?: throw MissingResourceException(path) diff --git a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt index 83404652ee..ca2ba2507e 100644 --- a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt +++ b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt @@ -6,6 +6,7 @@ import platform.CoreGraphics.CGDisplayPixelsWide import platform.CoreGraphics.CGDisplayScreenSize import platform.Foundation.* +@OptIn(InternalResourceApi::class) internal actual fun getSystemEnvironment(): ResourceEnvironment { val locale = NSLocale.currentLocale() val isDarkTheme = NSUserDefaults.standardUserDefaults.stringForKey("AppleInterfaceStyle") == "Dark" diff --git a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt index 7c295e851e..03d515621c 100644 --- a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt +++ b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt @@ -5,6 +5,8 @@ import kotlinx.cinterop.usePinned import platform.Foundation.NSFileManager import platform.posix.memcpy +@OptIn(ExperimentalResourceApi::class) +@InternalResourceApi actual suspend fun readResourceBytes(path: String): ByteArray { val currentDirectoryPath = NSFileManager.defaultManager().currentDirectoryPath val contentsAtPath = NSFileManager.defaultManager().run { diff --git a/components/resources/library/src/nativeMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/DomXmlParser.kt b/components/resources/library/src/nativeMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/DomXmlParser.kt index d31065ae54..bdc7aeda03 100644 --- a/components/resources/library/src/nativeMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/DomXmlParser.kt +++ b/components/resources/library/src/nativeMain/kotlin/org/jetbrains/compose/resources/vector/xmldom/DomXmlParser.kt @@ -4,6 +4,7 @@ */ package org.jetbrains.compose.resources.vector.xmldom +import org.jetbrains.compose.resources.ExperimentalResourceApi import platform.Foundation.NSError import platform.Foundation.NSString import platform.Foundation.NSUTF8StringEncoding @@ -57,6 +58,7 @@ private class ElementImpl( override fun lookupPrefix(namespaceURI: String): String = prefixMap[namespaceURI] ?: "" } +@OptIn(ExperimentalResourceApi::class) @Suppress("CONFLICTING_OVERLOADS", "PARAMETER_NAME_CHANGED_ON_OVERRIDE") private class DomXmlParser : NSObject(), NSXMLParserDelegateProtocol { diff --git a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt index 07643c2436..0bd899be07 100644 --- a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt +++ b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt @@ -29,6 +29,7 @@ private val emptyFontBase64 = @OptIn(ExperimentalEncodingApi::class) private val defaultEmptyFont by lazy { Font("org.jetbrains.compose.emptyFont", Base64.decode(emptyFontBase64)) } +@ExperimentalResourceApi @Composable actual fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): Font { val resourceReader = LocalResourceReader.current diff --git a/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ImageResources.wasmJs.kt b/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ImageResources.wasmJs.kt index 4de24550e7..8cd2208f30 100644 --- a/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ImageResources.wasmJs.kt +++ b/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ImageResources.wasmJs.kt @@ -5,6 +5,7 @@ import org.jetbrains.compose.resources.vector.xmldom.ElementImpl import org.jetbrains.compose.resources.vector.xmldom.MalformedXMLException import org.w3c.dom.parsing.DOMParser +@OptIn(ExperimentalResourceApi::class) internal actual fun ByteArray.toXmlElement(): Element { val xmlString = decodeToString() val xmlDom = DOMParser().parseFromString(xmlString, "application/xml".toJsString()) diff --git a/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.wasmJs.kt b/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.wasmJs.kt index 48f3acd851..7a0bfcfb27 100644 --- a/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.wasmJs.kt +++ b/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.wasmJs.kt @@ -9,6 +9,7 @@ private external class Intl { } } +@OptIn(InternalResourceApi::class) internal actual fun getSystemEnvironment(): ResourceEnvironment { val locale = Intl.Locale(window.navigator.language) val isDarkTheme = window.matchMedia("(prefers-color-scheme: dark)").matches diff --git a/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt b/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt index 2f6577cc41..efb80613b3 100644 --- a/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt +++ b/components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt @@ -15,6 +15,7 @@ import kotlin.wasm.unsafe.withScopedMemoryAllocator * @return The content of the file as a byte array. */ @OptIn(ExperimentalResourceApi::class) +@InternalResourceApi actual suspend fun readResourceBytes(path: String): ByteArray { val resPath = WebResourcesConfiguration.getResourcePath(path) val response = window.fetch(resPath).await() diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesSpec.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesSpec.kt index c3fc0bf61f..c39ea711d0 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesSpec.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesSpec.kt @@ -88,7 +88,7 @@ private fun CodeBlock.Builder.addQualifiers(resourceItem: ResourceItem): CodeBlo error("Region qualifier must be used only with language.\nFile: ${resourceItem.path}") } val langAndRegion = "$lang-$q" - if(!resourceItem.path.toString().contains("-$langAndRegion")) { + if (!resourceItem.path.toString().contains("-$langAndRegion")) { error("Region qualifier must be declared after language: '$langAndRegion'.\nFile: ${resourceItem.path}") } add("%T(\"${q.takeLast(2)}\"), ", regionQualifier) @@ -104,16 +104,20 @@ internal fun getResFileSpec( ): FileSpec = FileSpec.builder(packageName, "Res").apply { addType(TypeSpec.objectBuilder("Res").apply { addModifiers(KModifier.INTERNAL) + addAnnotation( + AnnotationSpec.builder(ClassName("kotlin", "OptIn")) + .addMember("org.jetbrains.compose.resources.InternalResourceApi::class") + .build() + ) + addAnnotation( + AnnotationSpec.builder(ClassName("org.jetbrains.compose.resources", "ExperimentalResourceApi")) + .build() + ) //readFileBytes val readResourceBytes = MemberName("org.jetbrains.compose.resources", "readResourceBytes") addFunction( FunSpec.builder("readBytes") - .addAnnotation( - AnnotationSpec.builder(ClassName("kotlin", "OptIn")) - .addMember("org.jetbrains.compose.resources.InternalResourceApi::class") - .build() - ) .addKdoc(""" Reads the content of the resource file at the specified path and returns it as a byte array. diff --git a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/expected/Res.kt b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/expected/Res.kt index 7f06ce6b18..22e3aa7d47 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/expected/Res.kt +++ b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/expected/Res.kt @@ -4,6 +4,7 @@ import kotlin.ByteArray import kotlin.OptIn import kotlin.String import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.LanguageQualifier import org.jetbrains.compose.resources.RegionQualifier @@ -12,6 +13,8 @@ import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.ThemeQualifier import org.jetbrains.compose.resources.readResourceBytes +@OptIn(org.jetbrains.compose.resources.InternalResourceApi::class) +@ExperimentalResourceApi internal object Res { /** * Reads the content of the resource file at the specified path and returns it as a byte array. @@ -21,7 +24,6 @@ internal object Res { * @param path The path of the file to read in the compose resource's directory. * @return The content of the file as a byte array. */ - @OptIn(org.jetbrains.compose.resources.InternalResourceApi::class) public suspend fun readBytes(path: String): ByteArray = readResourceBytes(path) public object drawable {