<commit_before>package org.jetbrains.dokka.base.signatures

import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.dri
import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.driOrNull
import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.Nullable
import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages.ContentKind
import org.jetbrains.dokka.pages.ContentNode
import org.jetbrains.dokka.pages.TextStyle
import org.jetbrains.dokka.utilities.DokkaLogger
import kotlin.text.Typography.nbsp

class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) : SignatureProvider,
    JvmSignatureUtils by KotlinSignatureUtils {
    private val contentBuilder = PageContentBuilder(ctcc, this, logger)

    private val ignoredVisibilities = setOf(JavaVisibility.Public, KotlinVisibility.Public)
    private val ignoredModifiers = setOf(JavaModifier.Final, KotlinModifier.Final)
    private val ignoredExtraModifiers = setOf(
        ExtraModifiers.KotlinOnlyModifiers.TailRec,
        ExtraModifiers.KotlinOnlyModifiers.External
    )
    private val platformSpecificModifiers: Map<ExtraModifiers, Set<Platform>> = mapOf(
        ExtraModifiers.KotlinOnlyModifiers.External to setOf(Platform.js)
    )

    override fun signature(documentable: Documentable): List<ContentNode> = when (documentable) {
        is DFunction -> functionSignature(documentable)
        is DProperty -> propertySignature(documentable)
        is DClasslike -> classlikeSignature(documentable)
        is DTypeParameter -> signature(documentable)
        is DEnumEntry -> signature(documentable)
        is DTypeAlias -> signature(documentable)
        else -> throw NotImplementedError(
            "Cannot generate signature for ${documentable::class.qualifiedName} ${documentable.name}"
        )
    }

    private fun <T> PageContentBuilder.DocumentableContentBuilder.processExtraModifiers(t: T)
            where T : Documentable, T : WithExtraProperties<T> {
        sourceSetDependentText(
            t.modifiers()
                .mapValues { entry ->
                    entry.value.filter {
                        it !in ignoredExtraModifiers || entry.key.analysisPlatform in (platformSpecificModifiers[it]
                            ?: emptySet())
                    }
                }
        ) {
            it.toSignatureString()
        }
    }

    private fun signature(e: DEnumEntry): List<ContentNode> =
        e.sourceSets.map {
            contentBuilder.contentFor(
                e,
                ContentKind.Symbol,
                setOf(TextStyle.Monospace, TextStyle.Block) + e.stylesIfDeprecated(it),
                sourceSets = setOf(it)
            ) {
                group(styles = setOf(TextStyle.Block)) {
                    annotationsBlock(e)
                    link(e.name, e.dri, styles = emptySet())
                    e.extra[ConstructorValues]?.let { constructorValues ->
                        constructorValues.values[it]
                        text(constructorValues.values[it]?.joinToString(prefix = "(", postfix = ")") ?: "")
                    }
                }
            }
        }

    private fun actualTypealiasedSignature(c: DClasslike, sourceSet: DokkaSourceSet, aliasedType: Bound) =
        contentBuilder.contentFor(
            c,
            ContentKind.Symbol,
            setOf(TextStyle.Monospace) + ((c as? WithExtraProperties<out Documentable>)?.stylesIfDeprecated(sourceSet)
                ?: emptySet()),
            sourceSets = setOf(sourceSet)
        ) {
            text("typealias ")
            link(c.name.orEmpty(), c.dri)
            text(" = ")
            signatureForProjection(aliasedType)
        }

    @Suppress("UNCHECKED_CAST")
    private fun <T : DClasslike> classlikeSignature(c: T): List<ContentNode> =
        c.sourceSets.map { sourceSetData ->
            (c as? WithExtraProperties<out DClasslike>)?.extra?.get(ActualTypealias)?.underlyingType?.get(sourceSetData)
                ?.let {
                    actualTypealiasedSignature(c, sourceSetData, it)
                } ?: regularSignature(c, sourceSetData)
        }


    private fun regularSignature(c: DClasslike, sourceSet: DokkaSourceSet) =
        contentBuilder.contentFor(
            c,
            ContentKind.Symbol,
            setOf(TextStyle.Monospace) + ((c as? WithExtraProperties<out Documentable>)?.stylesIfDeprecated(sourceSet)
                ?: emptySet()),
            sourceSets = setOf(sourceSet)
        ) {
            annotationsBlock(c)
            text(c.visibility[sourceSet]?.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "")
            if (c is DClass) {
                text(
                    if (c.modifier[sourceSet] !in ignoredModifiers)
                        when {
                            c.extra[AdditionalModifiers]?.content?.contains(ExtraModifiers.KotlinOnlyModifiers.Data) == true -> ""
                            c.modifier[sourceSet] is JavaModifier.Empty -> "${KotlinModifier.Open.name} "
                            else -> c.modifier[sourceSet]?.name?.let { "$it " } ?: ""
                        }
                    else
                        ""
                )
            }
            if (c is DInterface) {
                c.extra[AdditionalModifiers]?.content?.let { additionalModifiers ->
                    sourceSetDependentText(additionalModifiers, setOf(sourceSet)) { extraModifiers ->
                        if (ExtraModifiers.KotlinOnlyModifiers.Fun in extraModifiers) "fun "
                        else ""
                    }
                }
            }
            when (c) {
                is DClass -> {
                    processExtraModifiers(c)
                    text("class ")
                }
                is DInterface -> {
                    processExtraModifiers(c)
                    text("interface ")
                }
                is DEnum -> {
                    processExtraModifiers(c)
                    text("enum ")
                }
                is DObject -> {
                    processExtraModifiers(c)
                    text("object ")
                }
                is DAnnotation -> {
                    processExtraModifiers(c)
                    text("annotation class ")
                }
            }
            link(c.name!!, c.dri)
            if (c is WithGenerics) {
                list(c.generics, prefix = "<", suffix = ">") {
                    +buildSignature(it)
                }
            }
            if (c is WithConstructors) {
                val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null }
                if (pConstructor?.sourceSets?.contains(sourceSet) == true) {
                    if (pConstructor.annotations().values.any { it.isNotEmpty() }) {
                        text(nbsp.toString())
                        annotationsInline(pConstructor)
                        text("constructor")
                    }
                    list(
                        pConstructor.parameters,
                        "(",
                        ")",
                        ",",
                        pConstructor.sourceSets.toSet()
                    ) {
                        annotationsInline(it)
                        text(it.name ?: "", styles = mainStyles.plus(TextStyle.Bold))
                        text(": ")
                        signatureForProjection(it.type)
                    }
                }
            }
            if (c is WithSupertypes) {
                c.supertypes.filter { it.key == sourceSet }.map { (s, typeConstructors) ->
                    list(typeConstructors, prefix = " : ", sourceSets = setOf(s)) {
                        link(it.typeConstructor.dri.sureClassNames, it.typeConstructor.dri, sourceSets = setOf(s))<commit_msg>Add whitespace in parameters of classlike signature<commit_after>package org.jetbrains.dokka.base.signatures

import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.dri
import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.driOrNull
import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.Nullable
import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages.ContentKind
import org.jetbrains.dokka.pages.ContentNode
import org.jetbrains.dokka.pages.TextStyle
import org.jetbrains.dokka.utilities.DokkaLogger
import kotlin.text.Typography.nbsp

class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger) : SignatureProvider,
    JvmSignatureUtils by KotlinSignatureUtils {
    private val contentBuilder = PageContentBuilder(ctcc, this, logger)

    private val ignoredVisibilities = setOf(JavaVisibility.Public, KotlinVisibility.Public)
    private val ignoredModifiers = setOf(JavaModifier.Final, KotlinModifier.Final)
    private val ignoredExtraModifiers = setOf(
        ExtraModifiers.KotlinOnlyModifiers.TailRec,
        ExtraModifiers.KotlinOnlyModifiers.External
    )
    private val platformSpecificModifiers: Map<ExtraModifiers, Set<Platform>> = mapOf(
        ExtraModifiers.KotlinOnlyModifiers.External to setOf(Platform.js)
    )

    override fun signature(documentable: Documentable): List<ContentNode> = when (documentable) {
        is DFunction -> functionSignature(documentable)
        is DProperty -> propertySignature(documentable)
        is DClasslike -> classlikeSignature(documentable)
        is DTypeParameter -> signature(documentable)
        is DEnumEntry -> signature(documentable)
        is DTypeAlias -> signature(documentable)
        else -> throw NotImplementedError(
            "Cannot generate signature for ${documentable::class.qualifiedName} ${documentable.name}"
        )
    }

    private fun <T> PageContentBuilder.DocumentableContentBuilder.processExtraModifiers(t: T)
            where T : Documentable, T : WithExtraProperties<T> {
        sourceSetDependentText(
            t.modifiers()
                .mapValues { entry ->
                    entry.value.filter {
                        it !in ignoredExtraModifiers || entry.key.analysisPlatform in (platformSpecificModifiers[it]
                            ?: emptySet())
                    }
                }
        ) {
            it.toSignatureString()
        }
    }

    private fun signature(e: DEnumEntry): List<ContentNode> =
        e.sourceSets.map {
            contentBuilder.contentFor(
                e,
                ContentKind.Symbol,
                setOf(TextStyle.Monospace, TextStyle.Block) + e.stylesIfDeprecated(it),
                sourceSets = setOf(it)
            ) {
                group(styles = setOf(TextStyle.Block)) {
                    annotationsBlock(e)
                    link(e.name, e.dri, styles = emptySet())
                    e.extra[ConstructorValues]?.let { constructorValues ->
                        constructorValues.values[it]
                        text(constructorValues.values[it]?.joinToString(prefix = "(", postfix = ")") ?: "")
                    }
                }
            }
        }

    private fun actualTypealiasedSignature(c: DClasslike, sourceSet: DokkaSourceSet, aliasedType: Bound) =
        contentBuilder.contentFor(
            c,
            ContentKind.Symbol,
            setOf(TextStyle.Monospace) + ((c as? WithExtraProperties<out Documentable>)?.stylesIfDeprecated(sourceSet)
                ?: emptySet()),
            sourceSets = setOf(sourceSet)
        ) {
            text("typealias ")
            link(c.name.orEmpty(), c.dri)
            text(" = ")
            signatureForProjection(aliasedType)
        }

    @Suppress("UNCHECKED_CAST")
    private fun <T : DClasslike> classlikeSignature(c: T): List<ContentNode> =
        c.sourceSets.map { sourceSetData ->
            (c as? WithExtraProperties<out DClasslike>)?.extra?.get(ActualTypealias)?.underlyingType?.get(sourceSetData)
                ?.let {
                    actualTypealiasedSignature(c, sourceSetData, it)
                } ?: regularSignature(c, sourceSetData)
        }


    private fun regularSignature(c: DClasslike, sourceSet: DokkaSourceSet) =
        contentBuilder.contentFor(
            c,
            ContentKind.Symbol,
            setOf(TextStyle.Monospace) + ((c as? WithExtraProperties<out Documentable>)?.stylesIfDeprecated(sourceSet)
                ?: emptySet()),
            sourceSets = setOf(sourceSet)
        ) {
            annotationsBlock(c)
            text(c.visibility[sourceSet]?.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "")
            if (c is DClass) {
                text(
                    if (c.modifier[sourceSet] !in ignoredModifiers)
                        when {
                            c.extra[AdditionalModifiers]?.content?.contains(ExtraModifiers.KotlinOnlyModifiers.Data) == true -> ""
                            c.modifier[sourceSet] is JavaModifier.Empty -> "${KotlinModifier.Open.name} "
                            else -> c.modifier[sourceSet]?.name?.let { "$it " } ?: ""
                        }
                    else
                        ""
                )
            }
            if (c is DInterface) {
                c.extra[AdditionalModifiers]?.content?.let { additionalModifiers ->
                    sourceSetDependentText(additionalModifiers, setOf(sourceSet)) { extraModifiers ->
                        if (ExtraModifiers.KotlinOnlyModifiers.Fun in extraModifiers) "fun "
                        else ""
                    }
                }
            }
            when (c) {
                is DClass -> {
                    processExtraModifiers(c)
                    text("class ")
                }
                is DInterface -> {
                    processExtraModifiers(c)
                    text("interface ")
                }
                is DEnum -> {
                    processExtraModifiers(c)
                    text("enum ")
                }
                is DObject -> {
                    processExtraModifiers(c)
                    text("object ")
                }
                is DAnnotation -> {
                    processExtraModifiers(c)
                    text("annotation class ")
                }
            }
            link(c.name!!, c.dri)
            if (c is WithGenerics) {
                list(c.generics, prefix = "<", suffix = ">") {
                    +buildSignature(it)
                }
            }
            if (c is WithConstructors) {
                val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null }
                if (pConstructor?.sourceSets?.contains(sourceSet) == true) {
                    if (pConstructor.annotations().values.any { it.isNotEmpty() }) {
                        text(nbsp.toString())
                        annotationsInline(pConstructor)
                        text("constructor")
                    }
                    list(
                        pConstructor.parameters,
                        "(",
                        ")",
                        ", ",
                        pConstructor.sourceSets.toSet()
                    ) {
                        annotationsInline(it)
                        text(it.name ?: "", styles = mainStyles.plus(TextStyle.Bold))
                        text(": ")
                        signatureForProjection(it.type)
                    }
                }
            }
            if (c is WithSupertypes) {
                c.supertypes.filter { it.key == sourceSet }.map { (s, typeConstructors) ->
                    list(typeConstructors, prefix = " : ", sourceSets = setOf(s)) {
                        link(it.typeConstructor.dri.sureClassNames, it.typeConstructor.dri, sourceSets = setOf(s))
{'fraction_non_alphanumeric': 0.09582856798892433, 'fraction_numerical': 0.0, 'mean_word_length': 1.697953881130237, 'pattern_counts': {'":': 2, '<': 27, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5012309', 'n_tokens_mistral': 4393, 'n_tokens_neox': 4156, 'n_words': 683}