aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/model/additionalExtras.kt
blob: 1db8e59dee42909e275071c33c342f40ea383281 (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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

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

public class AdditionalModifiers(
    public val content: SourceSetDependent<Set<ExtraModifiers>>
) : ExtraProperty<Documentable> {

    public 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(): Int = content.hashCode()
    override val key: ExtraProperty.Key<Documentable, *> = AdditionalModifiers
}

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

public data class Annotations(
    private val myContent: SourceSetDependent<List<Annotation>>
) : ExtraProperty<AnnotationTarget> {
    public 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

    public 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()

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

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

public sealed class AnnotationParameterValue

public data class AnnotationValue(val annotation: Annotations.Annotation) : AnnotationParameterValue()

public data class ArrayValue(val value: List<AnnotationParameterValue>) : AnnotationParameterValue()

public data class EnumValue(val enumName: String, val enumDri: DRI) : AnnotationParameterValue()

public data class ClassValue(val className: String, val classDRI: DRI) : AnnotationParameterValue()

public abstract class LiteralValue : AnnotationParameterValue() {
    public abstract fun text() : String
}
public data class IntValue(val value: Int) : LiteralValue() {
    override fun text(): String = value.toString()
}

public data class LongValue(val value: Long) : LiteralValue() {
    override fun text(): String = value.toString()
}

public data class FloatValue(val value: Float) : LiteralValue() {
    override fun text(): String = value.toString()
}

public data class DoubleValue(val value: Double) : LiteralValue() {
    override fun text(): String = value.toString()
}

public object NullValue : LiteralValue() {
    override fun text(): String = "null"
}

public data class BooleanValue(val value: Boolean) : LiteralValue() {
    override fun text(): String = value.toString()
}

public data class StringValue(val value: String) : LiteralValue() {
    override fun text(): String = value
    override fun toString(): String = value
}

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

public 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

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

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