Skip to content

Commit

Permalink
Correctly scape weird package names (#80)
Browse files Browse the repository at this point in the history
* Fix using keywords in package names

* Format
  • Loading branch information
serras committed Jan 8, 2023
1 parent 44a8a9c commit 146b111
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 1 deletion.
13 changes: 13 additions & 0 deletions kopykat-ksp/src/test/kotlin/at/kopyk/MutableCopyTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ class MutableCopyTest {
""".evals("r" to 2)
}

@Test
fun `weird package name, issue #78`() {
"""
|package `this`.`in`.other
|
|data class Person(val name: String, val age: Int)
|
|val p1 = Person("Alex", 1)
|val p2 = p1.copy { age = age + 1 }
|val r = p2.age
""".evals("r" to 2)
}

@Test
fun `mutate one property, nested class`() {
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package at.kopyk.poet
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSName
import com.google.devtools.ksp.symbol.KSPropertyDeclaration
import com.google.devtools.ksp.symbol.Modifier
import com.squareup.kotlinpoet.ClassName
Expand Down Expand Up @@ -44,9 +45,17 @@ public val KSDeclaration.className: ClassName
get() =
when (val parent = parentDeclaration) {
is KSClassDeclaration -> parent.className.append(simpleName.asString())
else -> ClassName(packageName = packageName.asString(), simpleName.asString())
else -> ClassName(packageName = packageName.asStringQuoted(), simpleName.asString())
}

public fun KSName.asStringQuoted(): String =
asString().split('.').joinToString(separator = ".") {
when (it) {
in KEYWORDS -> "`$it`"
else -> it
}
}

public fun TypeName.asTransformLambda(): LambdaTypeName =
LambdaTypeName.get(parameters = arrayOf(this), returnType = this)

Expand All @@ -60,3 +69,94 @@ public fun ClassName.flattenWithSuffix(suffix: String): ClassName {
val mutableSimpleName = (simpleNames + suffix).joinToString(separator = "$")
return ClassName(packageName, mutableSimpleName).copy(this.isNullable, emptyList(), emptyMap())
}

// https://kotlinlang.org/docs/reference/keyword-reference.html
private val KEYWORDS = setOf(
// Hard keywords
"as",
"break",
"class",
"continue",
"do",
"else",
"false",
"for",
"fun",
"if",
"in",
"interface",
"is",
"null",
"object",
"package",
"return",
"super",
"this",
"throw",
"true",
"try",
"typealias",
"typeof",
"val",
"var",
"when",
"while",

// Soft keywords
"by",
"catch",
"constructor",
"delegate",
"dynamic",
"field",
"file",
"finally",
"get",
"import",
"init",
"param",
"property",
"receiver",
"set",
"setparam",
"where",

// Modifier keywords
"actual",
"abstract",
"annotation",
"companion",
"const",
"crossinline",
"data",
"enum",
"expect",
"external",
"final",
"infix",
"inline",
"inner",
"internal",
"lateinit",
"noinline",
"open",
"operator",
"out",
"override",
"private",
"protected",
"public",
"reified",
"sealed",
"suspend",
"tailrec",
"value",
"vararg",

// These aren't keywords anymore but still break some code if unescaped. https://youtrack.jetbrains.com/issue/KT-52315
"header",
"impl",

// Other reserved keywords
"yield",
)

0 comments on commit 146b111

Please sign in to comment.