Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve enum constants when emitting types #1235

Merged
merged 5 commits into from Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 16 additions & 2 deletions kotlinpoet/src/main/java/com/squareup/kotlinpoet/CodeWriter.kt
Expand Up @@ -403,7 +403,7 @@ internal class CodeWriter constructor(
while (c != null) {
val alias = memberImports[c.canonicalName]?.alias
val simpleName = alias ?: c.simpleName
val resolved = resolve(simpleName)
val resolved = resolveClass(simpleName) ?: resolveEnumConstant(simpleName)
nameResolved = resolved != null

// We don't care about nullability and type annotations here, as it's irrelevant for imports.
Expand Down Expand Up @@ -509,7 +509,7 @@ internal class CodeWriter constructor(
* imports.
*/
// TODO(jwilson): also honor superclass members when resolving names.
private fun resolve(simpleName: String): ClassName? {
private fun resolveClass(simpleName: String): ClassName? {
// Match a child of the current (potentially nested) class.
for (i in typeSpecStack.indices.reversed()) {
val typeSpec = typeSpecStack[i]
Expand All @@ -531,6 +531,20 @@ internal class CodeWriter constructor(
return null
}

/**
* Returns the qualified name of the `simpleName` enum constant if it's in the current scope
*/
private fun resolveEnumConstant(simpleName: String): String? {
Egorand marked this conversation as resolved.
Show resolved Hide resolved
if (typeSpecStack.size > 0) {
val typeSpec = typeSpecStack[0]
if (typeSpec.isEnum && typeSpec.enumConstants.keys.contains(simpleName)) {
return "$packageName.${typeSpec.name}.$simpleName"
martinbonnin marked this conversation as resolved.
Show resolved Hide resolved
}
}

return null
}

/** Returns the class named `simpleName` when nested in the class at `stackDepth`. */
private fun stackClassName(stackDepth: Int, simpleName: String): ClassName {
var className = ClassName(packageName, typeSpecStack[0].name!!)
Expand Down
30 changes: 30 additions & 0 deletions kotlinpoet/src/test/java/com/squareup/kotlinpoet/TypeSpecTest.kt
Expand Up @@ -5056,6 +5056,36 @@ class TypeSpecTest {
)
}

// https://github.com/square/kotlinpoet/issues/1234
@Test fun `enum constants are resolved`() {
val file = FileSpec.builder("com.example", "test")
.addType(
TypeSpec.enumBuilder("Foo")
.addProperty(
PropertySpec.builder("rawValue", String::class)
.initializer("%S", "")
.build()
)
.addEnumConstant("String")
.build()
)
.build()

assertThat(file.toString()).isEqualTo(
"""
package com.example

public enum class Foo {
String,
;

public val rawValue: kotlin.String = ""
}

""".trimIndent()
)
}

companion object {
private const val donutsPackage = "com.squareup.donuts"
}
Expand Down