mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-09-03 07:09:23 +00:00
update classcasts
This commit is contained in:
@@ -9,5 +9,6 @@ repositories {
|
||||
dependencies {
|
||||
implementation libs.kotlin.poet
|
||||
implementation libs.ksp
|
||||
implementation libs.microutils.ksp.generator
|
||||
implementation project(":tgbotapi.core")
|
||||
}
|
||||
|
@@ -1,9 +1,13 @@
|
||||
package dev.inmo.tgbotapi.ksp.processor
|
||||
|
||||
import com.google.devtools.ksp.KspExperimental
|
||||
import com.google.devtools.ksp.getAnnotationsByType
|
||||
import com.google.devtools.ksp.isAnnotationPresent
|
||||
import com.google.devtools.ksp.symbol.*
|
||||
import com.squareup.kotlinpoet.*
|
||||
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
||||
import com.squareup.kotlinpoet.ksp.*
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
|
||||
private fun FileSpec.Builder.addTopLevelImport(className: ClassName) {
|
||||
className.topLevelClassName().let {
|
||||
@@ -27,6 +31,24 @@ private fun FileSpec.Builder.createTypeDefinition(ksClassDeclaration: KSClassDec
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(KspExperimental::class)
|
||||
private fun KSClassDeclaration.buildPrefix(sourceDeclaration: KSClassDeclaration): String {
|
||||
val ownName = if (isAnnotationPresent(ClassCastsIncluded.ExcludeSubName::class)) {
|
||||
""
|
||||
} else {
|
||||
simpleName.asString()
|
||||
}
|
||||
when (val parentDeclaration = parentDeclaration) {
|
||||
is KSClassDeclaration -> if (parentDeclaration === sourceDeclaration) {
|
||||
return ownName
|
||||
} else {
|
||||
return "${parentDeclaration.buildPrefix(sourceDeclaration)}$ownName"
|
||||
}
|
||||
}
|
||||
return ownName
|
||||
}
|
||||
|
||||
@OptIn(KspExperimental::class)
|
||||
fun FileSpec.Builder.fill(
|
||||
sourceKSClassDeclaration: KSClassDeclaration,
|
||||
subtypesMap: Map<KSClassDeclaration, Set<KSClassDeclaration>>,
|
||||
@@ -40,8 +62,10 @@ fun FileSpec.Builder.fill(
|
||||
val sourceClassName = sourceKSClassDeclaration.toClassName()
|
||||
val targetClassClassName = targetClassDeclaration.toClassName()
|
||||
val targetClassTypeDefinition = createTypeDefinition(targetClassDeclaration)
|
||||
val simpleName = targetClassDeclaration.simpleName.asString()
|
||||
val withFirstLowerCase = simpleName.replaceFirstChar { it.lowercase() }
|
||||
// val simpleName = targetClassDeclaration.simpleName.asString()
|
||||
// val additionalPrefix = targetClassDeclaration.buildPrefix()
|
||||
val resultPrefix = targetClassDeclaration.buildPrefix(sourceKSClassDeclaration)
|
||||
val withFirstLowerCase = resultPrefix.replaceFirstChar { it.lowercase() }
|
||||
val castedOrNullName = "${withFirstLowerCase}OrNull"
|
||||
|
||||
addTopLevelImport(targetClassClassName)
|
||||
@@ -68,7 +92,7 @@ fun FileSpec.Builder.fill(
|
||||
}.build()
|
||||
)
|
||||
addFunction(
|
||||
FunSpec.builder("if$simpleName").apply {
|
||||
FunSpec.builder("if$resultPrefix").apply {
|
||||
val genericType = TypeVariableName("T", null)
|
||||
addTypeVariable(genericType)
|
||||
receiver(sourceClassName)
|
||||
|
@@ -1,22 +1,21 @@
|
||||
package dev.inmo.tgbotapi.ksp.processor
|
||||
|
||||
import com.google.devtools.ksp.KspExperimental
|
||||
import com.google.devtools.ksp.getAllSuperTypes
|
||||
import com.google.devtools.ksp.getAnnotationsByType
|
||||
import com.google.devtools.ksp.isAnnotationPresent
|
||||
import com.google.devtools.ksp.*
|
||||
import com.google.devtools.ksp.processing.*
|
||||
import com.google.devtools.ksp.symbol.KSAnnotated
|
||||
import com.google.devtools.ksp.symbol.KSClassDeclaration
|
||||
import com.google.devtools.ksp.symbol.*
|
||||
import com.squareup.kotlinpoet.AnnotationSpec
|
||||
import com.squareup.kotlinpoet.ClassName
|
||||
import com.squareup.kotlinpoet.FileSpec
|
||||
import com.squareup.kotlinpoet.asClassName
|
||||
import com.squareup.kotlinpoet.ksp.toClassName
|
||||
import com.squareup.kotlinpoet.ksp.writeTo
|
||||
import dev.inmo.micro_ksp.generator.resolveSubclasses
|
||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsExcluded
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.io.StringWriter
|
||||
|
||||
class TelegramBotAPISymbolProcessor(
|
||||
private val codeGenerator: CodeGenerator,
|
||||
@@ -37,25 +36,38 @@ class TelegramBotAPISymbolProcessor(
|
||||
val classesSubtypes = mutableMapOf<KSClassDeclaration, MutableSet<KSClassDeclaration>>()
|
||||
|
||||
resolver.getAllFiles().forEach {
|
||||
it.declarations.forEach { potentialSubtype ->
|
||||
if (
|
||||
potentialSubtype is KSClassDeclaration
|
||||
&& potentialSubtype.isAnnotationPresent(ClassCastsExcluded::class).not()
|
||||
) {
|
||||
val allSupertypes = potentialSubtype.getAllSuperTypes().map { it.declaration }
|
||||
val declarationsToAnalyze = mutableSetOf<KSDeclaration>()
|
||||
declarationsToAnalyze.addAll(it.declarations)
|
||||
val analyzed = mutableSetOf<KSDeclaration>()
|
||||
|
||||
for (currentClass in classes) {
|
||||
val regexes = classesRegexes[currentClass]
|
||||
val simpleName = potentialSubtype.simpleName.getShortName()
|
||||
when {
|
||||
currentClass !in allSupertypes
|
||||
|| regexes ?.first ?.matches(simpleName) == false
|
||||
|| regexes ?.second ?.matches(simpleName) == true -> continue
|
||||
else -> {
|
||||
classesSubtypes.getOrPut(currentClass) { mutableSetOf() }.add(potentialSubtype)
|
||||
while (declarationsToAnalyze.isNotEmpty()) {
|
||||
val potentialSubtype = declarationsToAnalyze.first()
|
||||
declarationsToAnalyze.remove(potentialSubtype)
|
||||
if (analyzed.add(potentialSubtype)) {
|
||||
if (
|
||||
potentialSubtype is KSClassDeclaration
|
||||
&& potentialSubtype.isAnnotationPresent(ClassCastsExcluded::class).not()
|
||||
) {
|
||||
val allSupertypes = potentialSubtype.getAllSuperTypes().map { it.declaration }
|
||||
|
||||
for (currentClass in classes) {
|
||||
val regexes = classesRegexes[currentClass]
|
||||
val simpleName = potentialSubtype.simpleName.getShortName()
|
||||
when {
|
||||
currentClass !in allSupertypes
|
||||
|| regexes ?.first ?.matches(simpleName) == false
|
||||
|| regexes ?.second ?.matches(simpleName) == true -> continue
|
||||
else -> {
|
||||
classesSubtypes.getOrPut(currentClass) { mutableSetOf() }.add(potentialSubtype)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
when (potentialSubtype) {
|
||||
is KSFile -> declarationsToAnalyze.addAll(potentialSubtype.declarations)
|
||||
is KSClassDeclaration ->declarationsToAnalyze.addAll(potentialSubtype.declarations)
|
||||
is KSFunctionDeclaration -> declarationsToAnalyze.addAll(potentialSubtype.declarations)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,15 +110,21 @@ class TelegramBotAPISymbolProcessor(
|
||||
)
|
||||
}
|
||||
}.build()
|
||||
runCatching {
|
||||
outputFolder ?.also {
|
||||
File(it).apply {
|
||||
delete()
|
||||
runCatching { mkdirs() }
|
||||
fileSpec.writeTo(this)
|
||||
|
||||
outputFolder ?.also {
|
||||
File(it, outputFile).apply {
|
||||
val text = StringWriter().use {
|
||||
fileSpec.writeTo(it)
|
||||
it.toString()
|
||||
}
|
||||
} ?: fileSpec.writeTo(codeGenerator, false)
|
||||
}
|
||||
if (exists() == false || readText() != text) {
|
||||
delete()
|
||||
runCatching { parentFile.mkdirs() }
|
||||
createNewFile()
|
||||
writeText(text)
|
||||
}
|
||||
}
|
||||
} ?: fileSpec.writeTo(codeGenerator, false)
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
|
Reference in New Issue
Block a user