question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Enum members should not reveal constructor calls

See original GitHub issue

Describe the bug I have a Kotlin project that includes several enum classes. There is a single source file astronomy.kt that contains all the code and documentation comments. I am using Dokka to generate “GitHub Flavored Markdown” (gfm). When Dokka encounters an enum declaration like this…

/**
 * The enumeration of celestial bodies supported by Astronomy Engine.
 */
enum class Body(
    internal val massProduct: Double?,
    internal val orbitalPeriod: Double?,
    internal val vsopModel: VsopModel?
) {
    /**
     * The planet Mercury.
     */
    Mercury(
        MERCURY_GM,
        87.969,
        VsopModel(vsopLonMercury, vsopLatMercury, vsopRadMercury)
    ),

    /**
     * The planet Venus.
     */
    Venus(
        VENUS_GM,
        224.701,
        VsopModel(vsopLonVenus, vsopLatVenus, vsopRadVenus)
    ),

    /*... etc ... */
}

… it inappropriately generates markdown that includes internal implementation details. Specifically, the members are listed with the internal details of the constructor calls. Enum constructors are required to be private, and in my case, the properties I am initializing are all marked internal. Here is an example of how the above Kotlin declaration for Venus gets converted to Markdown:

| [Venus](-venus/index.md) | [jvm]<br>[Venus](-venus/index.md)(VENUS_GM, 224.701, VsopModel(vsopLonVenus, vsopLatVenus, vsopRadVenus))<br>The planet Venus. |

Expected behaviour The example for Venus above should look like this:

| [Venus](-venus/index.md) | [jvm]<br>The planet Venus. |

Outside users should not see internal implementation details of the enum member’s construction. In general, I don’t want source code leaking into my documentation; only the public parts of the interface should be exposed.

Screenshots N/A

To Reproduce

  1. Clone the Astronomy Engine repository and change into its directory.
  2. git checkout kotlin
  3. cd source/kotlin
  4. ./gradlew dokkaGfm
  5. Look at the file source/kotlin/build/dokka/gfm/astronomy/io.github.cosinekitty.astronomy/-body/index.md. All of the internal constructor parameters are visible in the documentation. The same thing occurs in the markdown files for each individual enum member, such as source/kotlin/build/dokka/gfm/astronomy/io.github.cosinekitty.astronomy/-body/-venus/index.md.

Dokka configuration Configuration of dokka used to reproduce the bug:

plugins {
    java
    kotlin("jvm") version "1.6.10"
    `maven-publish`
    id("org.jetbrains.dokka") version "1.6.10"
}

group = "io.github.cosinekitty"
version = "0.0.1"

repositories {
    mavenCentral()
}

dependencies {
    dokkaHtmlPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.6.10")
    val junit5Version = "5.8.2"
    testImplementation("org.junit.jupiter:junit-jupiter-api:$junit5Version")
    testImplementation("org.junit.jupiter:junit-jupiter-params:$junit5Version")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junit5Version")
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}

configure<JavaPluginExtension> {
    sourceCompatibility = JavaVersion.VERSION_1_8
}

val sourceJar by tasks.creating(Jar::class) {
    dependsOn(tasks["classes"])
    archiveClassifier.set("sources")
    from(sourceSets["main"].allSource)
}

task("fatJar", type = Jar::class) {
    from(configurations.runtimeClasspath.get().map(::zipTree))
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    with(tasks.jar.get())
}

publishing {
    publications {
        register("mavenJava", MavenPublication::class) {
            from(components["kotlin"])
            artifact(sourceJar)
        }
    }
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
    kotlinOptions {
        allWarningsAsErrors = true
    }
}

tasks.dokkaGfm.configure {
    dokkaSourceSets {
        named("main") {
            includeNonPublic.set(false)
            reportUndocumented.set(true)
        }
    }
}

Installation

  • Operating system: macOS/Windows/Linux: The bug happens in all 3: macOS, Windows 10, and multiple flavors of Debian Linux.
  • Build tool: Gradle v7.4.1
  • Dokka version: 1.6.10

Additional context

$ ./gradlew --version

------------------------------------------------------------
Gradle 7.4.1
------------------------------------------------------------

Build time:   2022-03-09 15:04:47 UTC
Revision:     36dc52588e09b4b72f2010bc07599e0ee0434e2e

Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          11.0.13 (JetBrains s.r.o. 11.0.13+7-b1751.25)
OS:           Linux 4.19.0-20-amd64 amd64

Are you willing to provide a PR? I am happy to provide whatever help the maintainers could use to reproduce/diagnose this bug. Thank you!

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:17 (17 by maintainers)

github_iconTop GitHub Comments

3reactions
IgnatBeresnevcommented, May 13, 2022

@ebraminio yep, seems like you got to it even before I did 😃

1reaction
IgnatBeresnevcommented, Apr 25, 2022

I wonder if these issues are really specific to GFM

Good thought, some bugs are indeed not specific to GFM and reside on the lower level. I’ll check your reports for html format as well, thanks!

Enum support is somewhat poor at the moment and need to be refined, we’ll definitely get to it sometime soon.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why can't enum constructors be protected or public in Java?
All constructors of an enum class are implicitly private, even if the private modifier are omitted. – crazyStart. Jul 12, 2017 at 9:33....
Read more >
Why Enum Class Can Have a Private Constructor Only in Java?
We need the enum constructor to be private because enums define a finite set of values (SMALL, MEDIUM, LARGE). If the constructor was...
Read more >
Classes and enums with private members should have a ...
Non-abstract classes and enums with non- static , private members should explicitly initialize those members, either in a constructor or with a default ......
Read more >
Enum Class (System) - Microsoft Learn
When you define a method or property that takes an enumerated constant as a value, consider validating the value. The reason is that...
Read more >
Enum - Java Programming Tutorial
A better approach is to define our own list of permissible values in a construct called enumeration (or enum ), introduced in JDK...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found