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

addKdoc not working as expected when property is involved #1797

Closed
PhilippNowak96 opened this issue Jan 9, 2024 · 2 comments · Fixed by #1800
Closed

addKdoc not working as expected when property is involved #1797

PhilippNowak96 opened this issue Jan 9, 2024 · 2 comments · Fixed by #1800
Labels

Comments

@PhilippNowak96
Copy link

Describe the bug

When having a data class with primary constructor parameters and corresponding property specs, adding a KDoc to the parameter adds it to the property doc itself instead of the class doc.

To Reproduce

I took some of the example from #843. Here is a failing unit test for my case:

@Test
fun kdocTest() {
    val taco = TypeSpec.classBuilder("Taco")
        .addModifiers(KModifier.DATA)
        .addKdoc("Some class description")
        .primaryConstructor(
            FunSpec.constructorBuilder()
                .addParameter(
                    ParameterSpec.builder("mild", Boolean::class)
                        .addKdoc("Whether the taco is mild (ew) or crunchy (ye).")
                        .build()
                )
                .build()
        )
        .addProperty(
            PropertySpec.builder("mild", Boolean::class)
                .initializer("mild")
                .build()
        )
        .build()

    val expected = """
    |/**
    | * Some class description
    | *
    | * @param mild Whether the taco is mild (ew) or crunchy (ye).
    | */
    |public data class Taco(
    |  public val mild: kotlin.Boolean,
    |)
    |""".trimMargin()

    assertEquals(expected, taco.toString())
}

Expected behavior

/**
 * Some class description
 *
 * @param mild Whether the taco is mild (ew) or crunchy (ye).
 */
public data class Taco(
  public val mild: kotlin.Boolean,
)

Actual output


/**
 * Some class description
 */
public data class Taco(
  /**
   * Whether the taco is mild (ew) or crunchy (ye).
   */
  public val mild: kotlin.Boolean,
)

Additional context

We managed to find a workaround. If you add the same KDoc to the PropertySpec and add something like a single whitespace at the end of the KDoc for the ParameterSpec it's kinda working. So something like

val taco = TypeSpec.classBuilder("Taco")
    .addModifiers(KModifier.DATA)
    .addKdoc("Some class description")
    .primaryConstructor(
        FunSpec.constructorBuilder()
            .addParameter(
                ParameterSpec.builder("mild", Boolean::class)
                    .addKdoc("Whether the taco is mild (ew) or crunchy (ye). ")
                    .build()
            )
            .build()
    )
    .addProperty(
        PropertySpec.builder("mild", Boolean::class)
            .addKdoc("Whether the taco is mild (ew) or crunchy (ye).")
            .initializer("mild")
            .build()
    )
    .build()

puts out the following code:

/**
 * Some class description
 *
 * @param mild Whether the taco is mild (ew) or crunchy (ye). 
 */
public data class Taco(
  /**
   * Whether the taco is mild (ew) or crunchy (ye).
   */
  public val mild: kotlin.Boolean,
)

but it would be nice if it just works the way that adding KDoc to the ParameterSpec adds it to the class documentation and adding it to the PropertySpec adds it to the property.

If we are doing something wrong, please let me know.

@Egorand
Copy link
Collaborator

Egorand commented Jan 10, 2024

Currently this is by design, see the following comment:

/**
* Returns KDoc comments including those of the primary constructor and its parameters.
*
* If the primary constructor parameter is not mapped to a property, or if the property doesn't
* have its own KDoc - the parameter's KDoc will be attached to the parameter. Otherwise, if both
* the parameter and the property have KDoc - the property's KDoc will be attached to the
* property/parameter, and the parameter's KDoc will be printed in the type header.
*/

That said, I think it makes sense to always render parameter docs in the class header: if they're attached to the parameter itself, pressing F1 on the class name or on the constructor keyword does not show the docs, as it would when the doc is part of the class header.

image image

@PhilippNowak96
Copy link
Author

Thank you very much for the fast change! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants