aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/model/additionalExtras.kt
blob: 1f6f6d27a2087eacb16964a635b4e6c81fdba3de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package org.jetbrains.dokka.model

import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.properties.ExtraProperty
import org.jetbrains.dokka.model.properties.MergeStrategy

class AdditionalModifiers(val content: SourceSetDependent<Set<ExtraModifiers>>) : ExtraProperty<Documentable> {
    companion object : ExtraProperty.Key<Documentable, AdditionalModifiers> {
        override fun mergeStrategyFor(
            left: AdditionalModifiers,
            right: AdditionalModifiers
        ): MergeStrategy<Documentable> = MergeStrategy.Replace(AdditionalModifiers(left.content + right.content))
    }

    override fun equals(other: Any?): Boolean =
        if (other is AdditionalModifiers) other.content == content else false

    override fun hashCode() = content.hashCode()
    override val key: ExtraProperty.Key<Documentable, *> = AdditionalModifiers
}

fun SourceSetDependent<Set<ExtraModifiers>>.toAdditionalModifiers() = AdditionalModifiers(this)

data class Annotations(
    private val myContent: SourceSetDependent<List<Annotation>>
) : ExtraProperty<AnnotationTarget> {
    companion object : ExtraProperty.Key<AnnotationTarget, Annotations> {
        override fun mergeStrategyFor(left: Annotations, right: Annotations): MergeStrategy<AnnotationTarget> =
            MergeStrategy.Replace(Annotations(left.myContent + right.myContent))
    }

    override val key: ExtraProperty.Key<AnnotationTarget, *> = Annotations

    data class Annotation(
        val dri: DRI,
        val params: Map<String, AnnotationParameterValue>,
        val mustBeDocumented: Boolean = false,
        val scope: AnnotationScope = AnnotationScope.DIRECT
    ) {
        override fun equals(other: Any?): Boolean = when (other) {
            is Annotation -> dri == other.dri
            else -> false
        }

        override fun hashCode(): Int = dri.hashCode()
    }

    @Deprecated("Use directAnnotations or fileLevelAnnotations")
    val content: SourceSetDependent<List<Annotation>>
        get() = myContent

    val directAnnotations: SourceSetDependent<List<Annotation>> = annotationsByScope(AnnotationScope.DIRECT)

    val fileLevelAnnotations: SourceSetDependent<List<Annotation>> = annotationsByScope(AnnotationScope.FILE)

    private fun annotationsByScope(scope: AnnotationScope): SourceSetDependent<List<Annotation>> =
        myContent.entries.mapNotNull { (key, value) ->
            val withoutFileLevel = value.filter { it.scope == scope }
            if (withoutFileLevel.isEmpty()) null
            else Pair(key, withoutFileLevel)
        }.toMap()

    enum class AnnotationScope {
        DIRECT, FILE, GETTER, SETTER
    }
}

fun SourceSetDependent<List<Annotations.Annotation>>.toAnnotations() = Annotations(this)

sealed class AnnotationParameterValue
data class AnnotationValue(val annotation: Annotations.Annotation) : AnnotationParameterValue()
data class ArrayValue(val value: List<AnnotationParameterValue>) : AnnotationParameterValue()
data class EnumValue(val enumName: String, val enumDri: DRI) : AnnotationParameterValue()
data class ClassValue(val className: String, val classDRI: DRI) : AnnotationParameterValue()
abstract class LiteralValue : AnnotationParameterValue() {
    abstract fun text() : String
}
data class IntValue(val value: Int) : LiteralValue() {
    override fun text(): String = value.toString()
}

data class LongValue(val value: Long) : LiteralValue() {
    override fun text(): String = value.toString()
}
data class FloatValue(val value: Float) : LiteralValue() {
    override fun text(): String = value.toString()
}
data class DoubleValue(val value: Double) : LiteralValue() {
    override fun text(): String = value.toString()
}
object NullValue : LiteralValue() {
    override fun text(): String = "null"
}
data class BooleanValue(val value: Boolean) : LiteralValue() {
    override fun text(): String = value.toString()
}
data class StringValue(val value: String) : LiteralValue() {
    override fun text(): String = value
    override fun toString(): String = value
}


object PrimaryConstructorExtra : ExtraProperty<DFunction>, ExtraProperty.Key<DFunction, PrimaryConstructorExtra> {
    override val key: ExtraProperty.Key<DFunction, *> = this
}

data class ActualTypealias(
    val typeAlias: DTypeAlias
) : ExtraProperty<DClasslike> {

    @Suppress("unused")
    @Deprecated(message = "It can be removed soon. Use [typeAlias.underlyingType]", ReplaceWith("this.typeAlias.underlyingType"))
    val underlyingType: SourceSetDependent<Bound>
        get() = typeAlias.underlyingType

    companion object : ExtraProperty.Key<DClasslike, ActualTypealias> {
        override fun mergeStrategyFor(
            left: ActualTypealias,
            right: ActualTypealias
        ) = MergeStrategy.Fail {
            throw IllegalStateException("Adding [ActualTypealias] should be after merging all documentables")
        }
    }

    override val key: ExtraProperty.Key<DClasslike, ActualTypealias> = ActualTypealias
}