Skip to content

Commit

Permalink
add kotlin 2.0.20 support
Browse files Browse the repository at this point in the history
fix annotations resolution
  • Loading branch information
tabilzad committed Oct 2, 2024
1 parent 089fc42 commit 723c194
Show file tree
Hide file tree
Showing 15 changed files with 53 additions and 44 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "2.0.0"
kotlin("jvm") version "2.0.20"
}

buildscript {
Expand Down
2 changes: 1 addition & 1 deletion create-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.vanniktech.maven.publish.SonatypeHost

plugins {
kotlin("jvm")
kotlin("plugin.serialization") version "2.0.0"
kotlin("plugin.serialization") version "2.0.20"
id("com.vanniktech.maven.publish.base")
}

Expand Down
14 changes: 7 additions & 7 deletions create-plugin/src/main/kotlin/io/github/tabilzad/ktor/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import io.github.tabilzad.ktor.output.OpenApiSpec
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
Expand Down Expand Up @@ -181,24 +182,23 @@ private fun addPostBody(it: KtorRouteSpec): OpenApiSpec.RequestBody? {

internal fun FirDeclaration.getKDocComments(configuration: PluginConfiguration): String? {

if(!configuration.useKDocsForDescriptions) return null
if (!configuration.useKDocsForDescriptions) return null

fun String.sanitizeKDoc(): String {
val lines = trim().lines().map { it.trim() }
return lines.filter { it.isNotEmpty() && it != "*" }
.joinToString("\n") { line ->
when {
line.startsWith("/**") -> line.removePrefix("/**").trim()
line.startsWith("*/") -> ""
else -> line.trimMargin("*").trim()
}
line.removePrefix("/**")
.removeSuffix("*/")
.removePrefix("*/")
.trimMargin("*")
}
.trim()
}

return source?.treeStructure?.let {
source?.lighterASTNode?.getChildren(it)
?.firstOrNull { it.tokenType == KtTokens.DOC_COMMENT }
?.firstOrNull { it.tokenType == KtTokens.DOC_COMMENT || it.tokenType == KDocTokens.KDOC }
?.toString()
?.sanitizeKDoc()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import io.github.tabilzad.ktor.k1.visitors.KtorDescriptionBag
import io.github.tabilzad.ktor.k1.visitors.toSwaggerType
import io.github.tabilzad.ktor.k2.visitors.*
import io.github.tabilzad.ktor.output.OpenApiSpec
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
Expand All @@ -22,7 +24,6 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.util.PrivateForInline
Expand All @@ -31,7 +32,7 @@ internal class ExpressionsVisitorK2(
private val config: PluginConfiguration,
private val context: CheckerContext,
private val session: FirSession,
private val log: IrMessageLogger
private val log: MessageCollector?
) : FirDefaultVisitor<List<KtorElement>, KtorElement?>() {

init {
Expand Down Expand Up @@ -179,8 +180,9 @@ internal class ExpressionsVisitorK2(
}

val values = expression.arguments
.filterIsInstance<FirLiteralExpression<String>>()
.map { it.value }
.filterIsInstance<FirLiteralExpression>()
.filter { it.value is String }
.map { it.value as String }

return names.zip(values).toMap()
}
Expand Down Expand Up @@ -313,7 +315,7 @@ internal class ExpressionsVisitorK2(
}

else -> {
log.report(IrMessageLogger.Severity.WARNING, "Endpoints can't have Endpoint as routes", null)
log?.report(CompilerMessageSeverity.WARNING, "Endpoints can't have Endpoint as routes", null)
null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,20 +112,20 @@ fun FirFunction.hasAnnotation(session: FirSession, name: String): Boolean {

fun FirStatement.findAnnotation(name: String): FirAnnotation? {
return annotations.firstOrNull {
it.annotationTypeRef.coneType.renderReadableWithFqNames().contains(name)
it.annotationTypeRef.coneType.fqNameStr()?.contains(name) == true
}
}

fun FirProperty.findAnnotation(name: String?): FirAnnotation? {
if(name == null) return null
return backingField?.annotations?.firstOrNull {
it.annotationTypeRef.coneType.renderReadableWithFqNames().contains(name)
it.annotationTypeRef.coneType.fqNameStr()?.contains(name) == true
}
}

fun FirFunction.findAnnotation(name: String): FirAnnotation? {
return annotations.firstOrNull {
it.annotationTypeRef.coneType.renderReadableWithFqNames().contains(name)
it.annotationTypeRef.coneType.fqNameStr()?.contains(name) == true
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import io.github.tabilzad.ktor.annotations.GenerateOpenApi
import io.github.tabilzad.ktor.buildPluginConfiguration
import io.github.tabilzad.ktor.k1.convertInternalToOpenSpec
import io.github.tabilzad.ktor.serializeAndWriteTo
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.FirSession
Expand All @@ -13,7 +15,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSimpleFunctionChecker
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
import org.jetbrains.kotlin.ir.util.irMessageLogger


/**
Expand All @@ -26,7 +27,11 @@ class SwaggerDeclarationChecker(
configuration: CompilerConfiguration
) : FirSimpleFunctionChecker(MppCheckerKind.Common) {

private val log = configuration.irMessageLogger
private val log = try {
configuration.get(CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
} catch (ex: Throwable) {
null
}
private val config = configuration.buildPluginConfiguration()

override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class QueryParamsVisitor(private val session: FirSession) : FirDefaultVisitor<Un
}


override fun <T> visitLiteralExpression(literalExpression: FirLiteralExpression<T>, data: MutableList<String>) {
override fun visitLiteralExpression(literalExpression: FirLiteralExpression, data: MutableList<String>) {
val element = literalExpression.value
element?.let { data.add(it.toString()) }
}
Expand All @@ -62,12 +62,14 @@ class QueryParamsVisitor(private val session: FirSession) : FirDefaultVisitor<Un
if (fir is FirProperty) {
val init = fir.initializer

if (init is FirLiteralExpression<*>) {
if (init is FirLiteralExpression) {
init.accept(this, data)
}
}
}

@OptIn(PrivateConstantEvaluatorAPI::class)
// TODO(Look into evaluatePropertyInitializer instead of evaluateExpression)
override fun visitArgumentList(argumentList: FirArgumentList, data: MutableList<String>) {

if (argumentList is FirResolvedArgumentList) {
Expand All @@ -77,7 +79,7 @@ class QueryParamsVisitor(private val session: FirSession) : FirDefaultVisitor<Un
FirExpressionEvaluator.evaluateExpression(it, session)
}.filterIsInstance<FirEvaluatorResult.Evaluated>().map {
it.result
}.filterIsInstance<FirLiteralExpression<*>>()
}.filterIsInstance<FirLiteralExpression>()

g.forEach { it.accept(this, data) }

Expand Down Expand Up @@ -111,7 +113,7 @@ class QueryParamsVisitor(private val session: FirSession) : FirDefaultVisitor<Un
v?.resolvedArgumentMapping?.values?.find { it.name.asString() == enumEntryAccessor?.asString() }
val paramLiteral = v?.resolvedArgumentMapping?.entries?.find { it.value == paramName }?.key

val queryParam = (paramLiteral as? FirLiteralExpression<*>)?.value
val queryParam = (paramLiteral as? FirLiteralExpression)?.value
queryParam?.let {
data.add(queryParam.toString())
}
Expand All @@ -122,7 +124,7 @@ class QueryParamsVisitor(private val session: FirSession) : FirDefaultVisitor<Un
if (fir is FirProperty) {
val init = fir.initializer

if (init is FirLiteralExpression<*>) {
if (init is FirLiteralExpression) {
init.accept(this, data)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ internal class RespondsAnnotationVisitor : FirDefaultVisitor<List<KtorK2Response
override fun visitFunctionCall(functionCall: FirFunctionCall, data: KtorK2ResponseBag?): List<KtorK2ResponseBag> {


val status = functionCall.resolvedArgumentMapping?.findValueOfField("status") as? FirLiteralExpression<*>
val status = functionCall.resolvedArgumentMapping?.findValueOfField("status") as? FirLiteralExpression
val type = functionCall.resolvedArgumentMapping?.findValueOfField("type") as? FirGetClassCall
val isCollection = functionCall.resolvedArgumentMapping?.findValueOfField("isCollection") as? FirLiteralExpression<*>
val isCollection = functionCall.resolvedArgumentMapping?.findValueOfField("isCollection") as? FirLiteralExpression
val description =
functionCall.resolvedArgumentMapping?.findValueOfField("description") as? FirLiteralExpression<*>
functionCall.resolvedArgumentMapping?.findValueOfField("description") as? FirLiteralExpression


return listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal class StringArrayLiteralVisitor : FirDefaultVisitor<List<String>, List<
return emptyList()
}

override fun <T> visitLiteralExpression(literalExpression: FirLiteralExpression<T>, data: List<String>): List<String> =
override fun visitLiteralExpression(literalExpression: FirLiteralExpression, data: List<String>): List<String> =
listOf(literalExpression.value.toString())

override fun visitArrayLiteral(arrayLiteral: FirArrayLiteral, data: List<String>): List<String> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ class StringResolutionVisitor : FirDefaultVisitor<String, String>() {
data + dr.accept(this, data)
} ?: data

override fun <T> visitLiteralExpression(literalExpression: FirLiteralExpression<T>, data: String): String =
override fun visitLiteralExpression(literalExpression: FirLiteralExpression, data: String): String =
literalExpression.value.toString()
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,15 @@ private fun loadBaseSources(source: String): List<SourceFile> {
}

private val deps = arrayOf(
"ktor:2.2.4",
"ktor-server-core:2.2.4",
"ktor-resources:2.3.4",
"ktor-server-resources:2.3.4",
"ktor-utils:2.2.4",
"ktor-server-netty:2.2.4",
"ktor-http:2.2.4",
"ktor:2.3.12",
"ktor-server-core:2.3.12",
"ktor-resources:2.3.12",
"ktor-server-resources:2.3.12",
"ktor-utils:2.3.12",
"ktor-server-netty:2.3.12",
"ktor-http:2.3.12",
"kotlinx-coroutines-core:1.6.4",
"moshi:1.14.0",
"kotlinx-serialization-core:1.7.1",
"kotlinx-serialization-core:2.0.20",
"annotations:0.6.2-alpha"
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"kdocsConstructorParameter" : {
"type" : "string",
"description" : "This field is called [kdocsConstructorParameter].\nTis is another line with\n* This is another line with extra *\n* This \\is another \\*line with extra *"
"description" : "This field is called [kdocsConstructorParameter].\n This is another line with\n * This is another line with extra *\n * This \\is another \\*line with extra *"
},
"kdocsLateinitVar" : {
"type" : "string",
Expand Down
5 changes: 2 additions & 3 deletions create-plugin/src/test/resources/sources/KDocs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import io.ktor.server.routing.*
data class KDocsClass(
/**
* This field is called [kdocsConstructorParameter].
* Tis is another line with
* This is another line with
* * This is another line with extra *
* * This \is another \*line with extra *
*/
Expand All @@ -30,8 +30,7 @@ data class KDocsClass(
var kdocsProperty: String? = null

/**
* This field is called [kdocsLateinitVar].
*/
* This field is called [kdocsLateinitVar]. */
lateinit var kdocsLateinitVar: String
}

Expand Down
6 changes: 3 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[versions]
kotlinVersion = "2.0.0"
kotlinVersion = "2.0.20"
classgraph = "4.8.157"
jacksonVersion = "2.15.2"
ktorVersion = "2.2.4"
compilerTestingVersion = "0.5.0-alpha08"
ktorVersion = "2.3.12"
compilerTestingVersion = "0.5.1"
assertJVerison = "3.24.2"

[plugins]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ open class KtorMetaPlugin : KotlinCompilerPluginSupportPlugin {

kotlinCompilation.dependencies {
compileOnly("io.github.tabilzad:ktor-docs-plugin:$ktorDocsVersion")
implementation("io.github.tabilzad:annotations:$ktorDocsVersion")
}

val openApiOutputFile = with(swaggerExtension.pluginOptions) {
Expand Down

0 comments on commit 723c194

Please sign in to comment.