Skip to content

Commit

Permalink
7.3.1 (#236)
Browse files Browse the repository at this point in the history
* Add missing `user` and `text` references for `PurchasedPaidMediaUpdate`.
  • Loading branch information
vendelieu authored Sep 8, 2024
1 parent d496ae1 commit 6690fff
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 179 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Telegram-bot (KtGram) Changelog

### 7.3.1

* Add missing `user` and `text` references for `PurchasedPaidMediaUpdate`.

## 7.3.0

* Supported Telegram API [7.10](https://core.telegram.org/bots/api-changelog#september-6-2024)
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ methods [

### Additional resources

> There is a [wiki](https://github.com/vendelieu/telegram-bot/wiki) section that have helpful information.
* There is a [wiki](https://github.com/vendelieu/telegram-bot/wiki) section that has helpful information.
* [API reference](https://vendelieu.github.io/telegram-bot/)

### Questions

Expand Down
13 changes: 8 additions & 5 deletions helper/src/jvmMain/kotlin/eu/vendeli/ksp/ApiProcessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,15 @@ class ApiProcessor(
val fdslType = FunctionalHandlingDsl::class.asTypeName()
val blockType = ActivityCtx::class.asTypeName()
addImport("eu.vendeli.tgbot.types.internal", "UpdateType")
addImport("eu.vendeli.tgbot.utils", "cast")

UpdateType.entries.forEach { type ->
val funName = type.name
val nameRef = type.name
.lowercase()
.snakeToCamelCase()
.replace("editMessage", "editedMessage")
val funName = nameRef
.beginWithUpperCase()
.replace("EditMessage", "EditedMessage")

val pUpdateType = funName + "Update"
addImport("eu.vendeli.tgbot.types.internal", pUpdateType)

Expand All @@ -134,8 +135,10 @@ class ApiProcessor(
FunSpec
.builder("on$funName")
.receiver(fdslType)
.addKdoc("Action that is performed on the presence of $funName in the Update.")
.addParameter(ParameterSpec.builder("block", blockTypeRef).build())
.addKdoc(
"Action that is performed on the presence of " +
"[eu.vendeli.tgbot.types.Update.$nameRef] in the [eu.vendeli.tgbot.types.Update].",
).addParameter(ParameterSpec.builder("block", blockTypeRef).build())
.addCode("functionalActivities.onUpdateActivities[$type] = block.cast()")
.build(),
)
Expand Down
95 changes: 45 additions & 50 deletions ksp/src/jvmMain/kotlin/eu/vendeli/ksp/ActivityCollectors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.squareup.kotlinpoet.buildCodeBlock
import eu.vendeli.ksp.dto.CollectorsContext
import eu.vendeli.ksp.dto.CommonAnnotationData
import eu.vendeli.ksp.utils.addMap
import eu.vendeli.ksp.utils.addVarStatement
import eu.vendeli.ksp.utils.buildMeta
import eu.vendeli.ksp.utils.commonMatcherClass
import eu.vendeli.ksp.utils.invocableType
import eu.vendeli.ksp.utils.parseAsCommandHandler
Expand All @@ -25,10 +25,7 @@ import eu.vendeli.tgbot.annotations.CommandHandler
import eu.vendeli.tgbot.annotations.CommandHandler.CallbackQuery
import eu.vendeli.tgbot.annotations.InputHandler
import eu.vendeli.tgbot.annotations.UpdateHandler
import eu.vendeli.tgbot.implementations.DefaultArgParser
import eu.vendeli.tgbot.implementations.DefaultGuard
import eu.vendeli.tgbot.types.internal.UpdateType
import eu.vendeli.tgbot.utils.fullName

internal fun collectCommandActivities(
symbols: Sequence<KSFunctionDeclaration>,
Expand Down Expand Up @@ -63,24 +60,21 @@ internal fun collectCommandActivities(
annotationData.scope.forEach { updT ->
logger.info("Command: $it UpdateType: ${updT.name} --> ${function.qualifiedName?.asString()}")

addVarStatement(postFix = "\n)),") {
add("(\"$it\" to %L)" to updT)
add(
" to (%L to InvocationMeta(\n" to activitiesFile.buildInvocationLambdaCodeBlock(
function,
injectableTypes,
pkg,
addStatement(
"(\"$it\" to %L) to %L,", updT,
activitiesFile.buildInvocationLambdaCodeBlock(
function,
injectableTypes,
pkg,
buildMeta(
qualifier = function.qualifiedName!!.getQualifier(),
function = function.simpleName.asString(),
rateLimits = annotationData.rateLimits.toRateLimits(),
guardClass = annotationData.guardClass,
argParserClass = annotationData.argParserClass
),
)
add("qualifier = \"%L\"" to function.qualifiedName!!.getQualifier())
add(",\n function = \"%L\"" to function.simpleName.asString())
if (annotationData.rateLimits.first > 0 || annotationData.rateLimits.second > 0)
add(",\n rateLimits = %L" to annotationData.rateLimits.toRateLimits())
if (annotationData.guardClass != DefaultGuard::class.fullName)
add(",\n guard = %L::class" to annotationData.guardClass)
if (annotationData.argParserClass != DefaultArgParser::class.fullName)
add(",\n argParser = %L::class" to annotationData.argParserClass)
}
),
)
}
}
}
Expand All @@ -107,21 +101,22 @@ internal fun collectInputActivities(
.parseAsInputHandler()
annotationData.first.forEach {
logger.info("Input: $it --> ${function.qualifiedName?.asString()}")
addVarStatement(postFix = "\n)),") {
add(
"\"$it\" to (%L to InvocationMeta(\n" to activitiesFile.buildInvocationLambdaCodeBlock(
function,
injectableTypes,
pkg,

addStatement(
"\"$it\" to %L,",
activitiesFile.buildInvocationLambdaCodeBlock(
function,
injectableTypes,
pkg,
buildMeta(
qualifier = function.qualifiedName!!.getQualifier(),
function = function.simpleName.asString(),
rateLimits = annotationData.second.toRateLimits(),
guardClass = annotationData.third,
argParserClass = null
),
)
add("qualifier = \"%L\"" to function.qualifiedName!!.getQualifier())
add(",\n function = \"%L\"" to function.simpleName.asString())
if (annotationData.second.first > 0 || annotationData.second.second > 0)
add(",\n rateLimits = %L" to annotationData.second.toRateLimits())
if (annotationData.third != DefaultGuard::class.fullName)
add(",\n guard = %L::class" to annotationData.third)
}
),
)
}
}
}
Expand Down Expand Up @@ -171,22 +166,22 @@ internal fun collectCommonActivities(
.apply {
add("mapOf(\n")
data.forEach {
addVarStatement(postFix = "\n)),") {
add("%L to " to it.value.toCommonMatcher(it.filter, it.scope))
add(
"(%L to InvocationMeta(\n" to activitiesFile.buildInvocationLambdaCodeBlock(
it.funDeclaration,
injectableTypes,
pkg,
addStatement(
"%L to %L,",
it.value.toCommonMatcher(it.filter, it.scope),
activitiesFile.buildInvocationLambdaCodeBlock(
it.funDeclaration,
injectableTypes,
pkg,
buildMeta(
qualifier = it.funQualifier,
function = it.funSimpleName,
rateLimits = it.rateLimits,
argParserClass = it.argParser,
guardClass = null,
),
)
add("qualifier = \"%L\"" to it.funQualifier)
add(",\n function = \"%L\"" to it.funSimpleName)
if (it.rateLimits.rate > 0 || it.rateLimits.period > 0)
add(",\n rateLimits = %L" to it.rateLimits)
if (it.argParser != DefaultArgParser::class.fullName)
add(",\n argParser = %L::class" to it.argParser)
}
),
)
}
add(")\n")
}.build(),
Expand Down
18 changes: 15 additions & 3 deletions ksp/src/jvmMain/kotlin/eu/vendeli/ksp/ActivityProcessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ActivityProcessor(
addImport("eu.vendeli.tgbot.types.internal.configuration", "RateLimits")

addSuspendCallFun()
addSuspendCallFun(true)
addImport("eu.vendeli.tgbot.utils", "getInstance")
}

Expand Down Expand Up @@ -190,11 +191,17 @@ class ActivityProcessor(
)
}

private fun FileBuilder.addSuspendCallFun() = addFunction(
private fun FileBuilder.addSuspendCallFun(withMeta: Boolean = false) = addFunction(
FunSpec
.builder("suspendCall")
.apply {
addModifiers(KModifier.PRIVATE, KModifier.INLINE)
if (withMeta) addParameter(
ParameterSpec.builder(
"meta",
TypeVariableName("InvocationMeta"),
).build(),
)
addParameter(
ParameterSpec
.builder(
Expand All @@ -203,8 +210,13 @@ class ActivityProcessor(
KModifier.NOINLINE,
).build(),
)
returns(TypeVariableName("InvocationLambda"))
addStatement("return block")
if (!withMeta) {
returns(TypeVariableName("InvocationLambda"))
addStatement("return block")
} else {
returns(TypeVariableName("Invocable"))
addStatement("return block to meta")
}
}.build(),
)
}
16 changes: 12 additions & 4 deletions ksp/src/jvmMain/kotlin/eu/vendeli/ksp/InvocationLambdaBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ internal fun FileBuilder.buildInvocationLambdaCodeBlock(
function: KSFunctionDeclaration,
injectableTypes: Map<TypeName, ClassName>,
pkg: String? = null,
meta: Pair<String, Array<Any?>>? = null,
) = buildCodeBlock {
val isTopLvl = function.functionKind == FunctionKind.TOP_LEVEL
val funQualifier = function.qualifiedName!!.getQualifier()
Expand All @@ -88,7 +89,14 @@ internal fun FileBuilder.buildInvocationLambdaCodeBlock(
}
val isObject = (function.parent as? KSClassDeclaration)?.classKind == ClassKind.OBJECT

beginControlFlow("suspendCall { classManager, update, user, bot, parameters ->")
val lambda = meta?.let {
beginControlFlow(
"suspendCall(\n\t${it.first}\n) { classManager, update, user, bot, parameters ->",
*it.second,
)
} ?: beginControlFlow("suspendCall { classManager, update, user, bot, parameters ->")

lambda
.apply {
var parametersEnumeration = ""
if (!isTopLvl && !isObject && function.functionKind != FunctionKind.STATIC) {
Expand All @@ -109,9 +117,9 @@ internal fun FileBuilder.buildInvocationLambdaCodeBlock(
}?.let { i ->
i.arguments.first { a -> a.name?.asString() == "name" }.value as? String
} ?: parameter.name!!.getShortName()
).let {
"parameters[\"$it\"]"
}
).let {
"parameters[\"$it\"]"
}
val parameterTypeName = parameter.type.toTypeName()
val typeName = parameterTypeName.copy(false)
val nullabilityMark = if (parameterTypeName.isNullable) "" else "!!"
Expand Down
51 changes: 34 additions & 17 deletions ksp/src/jvmMain/kotlin/eu/vendeli/ksp/utils/HelperUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import com.squareup.kotlinpoet.asClassName
import com.squareup.kotlinpoet.asTypeName
import eu.vendeli.tgbot.TelegramBot
import eu.vendeli.tgbot.implementations.ClassDataImpl
import eu.vendeli.tgbot.implementations.DefaultArgParser
import eu.vendeli.tgbot.implementations.DefaultGuard
import eu.vendeli.tgbot.implementations.UserDataMapImpl
import eu.vendeli.tgbot.interfaces.ctx.ClassData
import eu.vendeli.tgbot.interfaces.ctx.UserData
Expand Down Expand Up @@ -123,6 +125,38 @@ internal inline fun <R> Any?.safeCast(): R? = this as? R

internal fun Pair<Long, Long>.toRateLimits(): RateLimits = RateLimits(first, second)

@Suppress("NOTHING_TO_INLINE")
internal inline fun buildMeta(
qualifier: String,
function: String,
rateLimits: RateLimits,
guardClass: String? = null,
argParserClass: String? = null,
): Pair<String, Array<Any?>> {
val parametersList = mutableListOf<Any?>(
qualifier,
function
)

return buildString {
append("InvocationMeta(\n\tqualifier = \"%L\",\n\tfunction = \"%L\"")
if (rateLimits.period > 0 || rateLimits.rate > 0) {
append(",\n\trateLimits = %L")
parametersList.add(rateLimits)
}

if (guardClass != null && guardClass != DefaultGuard::class.fullName) {
append(",\n\tguard = %L::class")
parametersList.add(guardClass)
}
if (argParserClass != null && argParserClass != DefaultArgParser::class.fullName) {
append(",\n\targParser = %L::class")
parametersList.add(argParserClass)
}
append("\n\t)")
} to parametersList.toTypedArray()
}

internal fun <T : Annotation> Resolver.getAnnotatedFnSymbols(
targetPackage: String? = null,
vararg kClasses: KClass<out T>,
Expand All @@ -142,23 +176,6 @@ internal fun <T : Annotation> Resolver.getAnnotatedFnSymbols(
}
}

internal fun CodeBlock.Builder.addVarStatement(
prefix: String? = null,
postFix: String? = null,
builder: MutableList<Pair<String, Any?>>.() -> Unit,
) {
val pairList = buildList(builder)

val format = buildString {
prefix?.also(::append)
pairList.forEach {
append(it.first)
}
postFix?.also(::append)
}
addStatement(format, *pairList.map { it.second }.toTypedArray())
}

internal fun <T : Annotation> Resolver.getAnnotatedClassSymbols(clazz: KClass<T>, targetPackage: String? = null) =
if (targetPackage == null) getSymbolsWithAnnotation(clazz.qualifiedName!!).filterIsInstance<KSClassDeclaration>()
else getSymbolsWithAnnotation(clazz.qualifiedName!!)
Expand Down
4 changes: 3 additions & 1 deletion telegram-bot/api/telegram-bot.api
Original file line number Diff line number Diff line change
Expand Up @@ -7825,7 +7825,7 @@ public final class eu/vendeli/tgbot/types/internal/ProcessedUpdateKt {
public static final fun getUserOrNull (Leu/vendeli/tgbot/types/internal/ProcessedUpdate;)Leu/vendeli/tgbot/types/User;
}

public final class eu/vendeli/tgbot/types/internal/PurchasedPaidMediaUpdate : eu/vendeli/tgbot/types/internal/ProcessedUpdate {
public final class eu/vendeli/tgbot/types/internal/PurchasedPaidMediaUpdate : eu/vendeli/tgbot/types/internal/ProcessedUpdate, eu/vendeli/tgbot/types/internal/TextReference, eu/vendeli/tgbot/types/internal/UserReference {
public fun <init> (ILeu/vendeli/tgbot/types/Update;Leu/vendeli/tgbot/types/media/PaidMediaPurchased;)V
public final fun component1 ()I
public final fun component2 ()Leu/vendeli/tgbot/types/Update;
Expand All @@ -7835,7 +7835,9 @@ public final class eu/vendeli/tgbot/types/internal/PurchasedPaidMediaUpdate : eu
public fun equals (Ljava/lang/Object;)Z
public fun getOrigin ()Leu/vendeli/tgbot/types/Update;
public final fun getPurchasedPaidMedia ()Leu/vendeli/tgbot/types/media/PaidMediaPurchased;
public fun getText ()Ljava/lang/String;
public fun getUpdateId ()I
public fun getUser ()Leu/vendeli/tgbot/types/User;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,12 @@ data class PurchasedPaidMediaUpdate(
override val updateId: Int,
override val origin: Update,
val purchasedPaidMedia: PaidMediaPurchased,
) : ProcessedUpdate(updateId, origin, UpdateType.PURCHASED_PAID_MEDIA) {
) : ProcessedUpdate(updateId, origin, UpdateType.PURCHASED_PAID_MEDIA),
UserReference,
TextReference {
override val user: User = purchasedPaidMedia.from
override val text: String = purchasedPaidMedia.paidMediaPayload

internal companion object : UpdateSerializer<PurchasedPaidMediaUpdate>()
}

Expand Down
Loading

0 comments on commit 6690fff

Please sign in to comment.