diff --git a/plugin/src/main/java/app/cash/gingham/plugin/ResourceWriter.kt b/plugin/src/main/java/app/cash/gingham/plugin/ResourceWriter.kt index 58fa630..fe241cc 100644 --- a/plugin/src/main/java/app/cash/gingham/plugin/ResourceWriter.kt +++ b/plugin/src/main/java/app/cash/gingham/plugin/ResourceWriter.kt @@ -53,10 +53,22 @@ private fun TokenizedResource.toFunSpec(packageStringsType: TypeName): FunSpec { .apply { if (description != null) addKdoc(description) } .apply { tokens.forEach { addParameter(it.toParameterSpec()) } } .returns(Types.FormattedResource) - .addStatement("val arguments = %T(%L)", Types.ArrayMap.parameterizedBy(STRING, ANY), tokens.size) .apply { - for (token in tokens) { - addStatement("arguments.put(%S, %L)", token.argumentName, token.toParameterCodeBlock()) + if (hasContiguousNumberedTokens) { + addCode( + buildCodeBlock { + add("val arguments = arrayOf(⇥\n") + for (token in tokens) { + addStatement("%L,", token.toParameterCodeBlock()) + } + add("⇤)\n") + } + ) + } else { + addStatement("val arguments = %T(%L)", Types.ArrayMap.parameterizedBy(STRING, ANY), tokens.size) + for (token in tokens) { + addStatement("arguments.put(%S, %L)", token.argumentName, token.toParameterCodeBlock()) + } } } .addCode( diff --git a/plugin/src/main/java/app/cash/gingham/plugin/model/TokenizedResource.kt b/plugin/src/main/java/app/cash/gingham/plugin/model/TokenizedResource.kt index 12e320d..e84b086 100644 --- a/plugin/src/main/java/app/cash/gingham/plugin/model/TokenizedResource.kt +++ b/plugin/src/main/java/app/cash/gingham/plugin/model/TokenizedResource.kt @@ -11,6 +11,10 @@ internal data class TokenizedResource( val description: String?, val tokens: List, ) { + /* True when the tokens represent a contiguous set of integers counting from 0. */ + val hasContiguousNumberedTokens: Boolean = + tokens.indices.toList() == tokens.map { (it as? Token.NumberedToken)?.number } + sealed interface Token { val type: KClass<*> diff --git a/plugin/src/test/java/app/cash/gingham/plugin/ResourceWriterTest.kt b/plugin/src/test/java/app/cash/gingham/plugin/ResourceWriterTest.kt index 4145ee5..9181a4f 100644 --- a/plugin/src/test/java/app/cash/gingham/plugin/ResourceWriterTest.kt +++ b/plugin/src/test/java/app/cash/gingham/plugin/ResourceWriterTest.kt @@ -83,7 +83,6 @@ class ResourceWriterTest { // Do not edit this file directly. Instead, edit the string resources in the source file. package com.gingham.test - import android.util.ArrayMap import app.cash.gingham.FormattedResource import com.gingham.test.R import java.time.Instant @@ -104,12 +103,13 @@ class ResourceWriterTest { arg3: Number, arg4: String, ): FormattedResource { - val arguments = ArrayMap(5) - arguments.put("0", arg0) - arguments.put("1", Date.from(arg1)) - arguments.put("2", arg2) - arguments.put("3", arg3) - arguments.put("4", arg4) + val arguments = arrayOf( + arg0, + Date.from(arg1), + arg2, + arg3, + arg4, + ) return FormattedResource( id = R.string.test_numbered, arguments = arguments diff --git a/runtime/src/main/java/app/cash/gingham/FormattedResource.kt b/runtime/src/main/java/app/cash/gingham/FormattedResource.kt index eaef0a2..25da1a6 100644 --- a/runtime/src/main/java/app/cash/gingham/FormattedResource.kt +++ b/runtime/src/main/java/app/cash/gingham/FormattedResource.kt @@ -1,6 +1,7 @@ // Copyright Square, Inc. package app.cash.gingham +import android.icu.text.MessageFormat import androidx.annotation.StringRes /** @@ -23,5 +24,10 @@ import androidx.annotation.StringRes * - The R.string.detective_has_suspects resource ID * - An integer value for the suspects argument * - A string value for the detective argument + * + * @property arguments Arguments passed directly to [MessageFormat.format]. */ -data class FormattedResource(@StringRes val id: Int, val arguments: Map) +data class FormattedResource constructor( + @StringRes val id: Int, + val arguments: Any, +) diff --git a/runtime/src/main/java/app/cash/gingham/FormattedResources.kt b/runtime/src/main/java/app/cash/gingham/FormattedResources.kt index 7344838..614766a 100644 --- a/runtime/src/main/java/app/cash/gingham/FormattedResources.kt +++ b/runtime/src/main/java/app/cash/gingham/FormattedResources.kt @@ -16,4 +16,4 @@ fun Context.getString(formattedResource: FormattedResource): String = * Resolves and returns the final formatted version of the given formatted string. */ fun Resources.getString(formattedResource: FormattedResource): String = - MessageFormat.format(getString(formattedResource.id), formattedResource.arguments) + MessageFormat(getString(formattedResource.id)).format(formattedResource.arguments)