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

Retain source language information in Documentable tree #2474

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
87 changes: 66 additions & 21 deletions core/src/main/kotlin/model/Documentable.kt
Expand Up @@ -192,9 +192,10 @@ data class DEnumEntry(
override val functions: List<DFunction>,
override val properties: List<DProperty>,
override val classlikes: List<DClasslike>,
override val sources: SourceSetDependent<DocumentableSource>,
override val sourceSets: Set<DokkaSourceSet>,
override val extra: PropertyContainer<DEnumEntry> = PropertyContainer.empty()
) : Documentable(), WithScope, WithExtraProperties<DEnumEntry> {
) : Documentable(), WithScope, WithExtraProperties<DEnumEntry>, WithSources {
override val children: List<Documentable>
get() = (functions + properties + classlikes)

Expand Down Expand Up @@ -321,9 +322,10 @@ data class DParameter(
override val documentation: SourceSetDependent<DocumentationNode>,
override val expectPresentInSet: DokkaSourceSet?,
override val type: Bound,
override val sources: SourceSetDependent<DocumentableSource>,
override val sourceSets: Set<DokkaSourceSet>,
override val extra: PropertyContainer<DParameter> = PropertyContainer.empty()
) : Documentable(), WithExtraProperties<DParameter>, WithType {
) : Documentable(), WithExtraProperties<DParameter>, WithType, WithSources {
override val children: List<Nothing>
get() = emptyList()

Expand All @@ -335,9 +337,10 @@ data class DTypeParameter(
override val documentation: SourceSetDependent<DocumentationNode>,
override val expectPresentInSet: DokkaSourceSet?,
val bounds: List<Bound>,
override val sources: SourceSetDependent<DocumentableSource>,
override val sourceSets: Set<DokkaSourceSet>,
override val extra: PropertyContainer<DTypeParameter> = PropertyContainer.empty()
) : Documentable(), WithExtraProperties<DTypeParameter> {
) : Documentable(), WithExtraProperties<DTypeParameter>, WithSources {

constructor(
dri: DRI,
Expand All @@ -346,13 +349,15 @@ data class DTypeParameter(
documentation: SourceSetDependent<DocumentationNode>,
expectPresentInSet: DokkaSourceSet?,
bounds: List<Bound>,
sources: SourceSetDependent<DocumentableSource>,
sourceSets: Set<DokkaSourceSet>,
extra: PropertyContainer<DTypeParameter> = PropertyContainer.empty()
) : this(
Invariance(TypeParameter(dri, name, presentableName)),
Invariance(TypeParameter(dri, name, presentableName, sources)),
documentation,
expectPresentInSet,
bounds,
sources,
sourceSets,
extra
)
Expand All @@ -374,10 +379,11 @@ data class DTypeAlias(
override val visibility: SourceSetDependent<Visibility>,
override val documentation: SourceSetDependent<DocumentationNode>,
override val expectPresentInSet: DokkaSourceSet?,
override val sources: SourceSetDependent<DocumentableSource>,
override val sourceSets: Set<DokkaSourceSet>,
override val generics: List<DTypeParameter>,
override val extra: PropertyContainer<DTypeAlias> = PropertyContainer.empty()
) : Documentable(), WithType, WithVisibility, WithExtraProperties<DTypeAlias>, WithGenerics {
) : Documentable(), WithType, WithVisibility, WithExtraProperties<DTypeAlias>, WithGenerics, WithSources {
override val children: List<Nothing>
get() = emptyList()

Expand All @@ -386,26 +392,30 @@ data class DTypeAlias(

sealed class Projection
sealed class Bound : Projection()
val Bound.sources get() = (this as WithSources).sources
data class TypeParameter(
val dri: DRI,
val name: String,
val presentableName: String? = null,
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<TypeParameter> = PropertyContainer.empty()
) : Bound(), AnnotationTarget, WithExtraProperties<TypeParameter> {
) : Bound(), AnnotationTarget, WithExtraProperties<TypeParameter>, WithSources {
override fun withNewExtras(newExtras: PropertyContainer<TypeParameter>): TypeParameter =
copy(extra = extra)
}

sealed class TypeConstructor : Bound(), AnnotationTarget {
sealed class TypeConstructor : Bound(), AnnotationTarget, WithSources {
abstract val dri: DRI
abstract val projections: List<Projection>
abstract val presentableName: String?
abstract override val sources: SourceSetDependent<DocumentableSource>
}

data class GenericTypeConstructor(
override val dri: DRI,
override val projections: List<Projection>,
override val presentableName: String? = null,
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<GenericTypeConstructor> = PropertyContainer.empty()
) : TypeConstructor(), WithExtraProperties<GenericTypeConstructor> {
override fun withNewExtras(newExtras: PropertyContainer<GenericTypeConstructor>): GenericTypeConstructor =
Expand All @@ -418,6 +428,7 @@ data class FunctionalTypeConstructor(
val isExtensionFunction: Boolean = false,
val isSuspendable: Boolean = false,
override val presentableName: String? = null,
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<FunctionalTypeConstructor> = PropertyContainer.empty(),
) : TypeConstructor(), WithExtraProperties<FunctionalTypeConstructor> {
override fun withNewExtras(newExtras: PropertyContainer<FunctionalTypeConstructor>): FunctionalTypeConstructor =
Expand All @@ -428,39 +439,65 @@ data class FunctionalTypeConstructor(
data class TypeAliased(
val typeAlias: Bound,
val inner: Bound,
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<TypeAliased> = PropertyContainer.empty()
) : Bound(), AnnotationTarget, WithExtraProperties<TypeAliased> {
) : Bound(), AnnotationTarget, WithExtraProperties<TypeAliased>, WithSources {
override fun withNewExtras(newExtras: PropertyContainer<TypeAliased>): TypeAliased =
copy(extra = newExtras)
}

data class PrimitiveJavaType(
val name: String,
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<PrimitiveJavaType> = PropertyContainer.empty()
) : Bound(), AnnotationTarget, WithExtraProperties<PrimitiveJavaType> {
) : Bound(), AnnotationTarget, WithExtraProperties<PrimitiveJavaType>, WithSources {
override fun withNewExtras(newExtras: PropertyContainer<PrimitiveJavaType>): PrimitiveJavaType =
copy(extra = newExtras)
}

data class JavaObject(override val extra: PropertyContainer<JavaObject> = PropertyContainer.empty()) :
Bound(), AnnotationTarget, WithExtraProperties<JavaObject> {
data class JavaObject(
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<JavaObject> = PropertyContainer.empty()
) :
Bound(), AnnotationTarget, WithExtraProperties<JavaObject>, WithSources {
override fun withNewExtras(newExtras: PropertyContainer<JavaObject>): JavaObject =
copy(extra = newExtras)
}

data class UnresolvedBound(
val name: String,
override val sources: SourceSetDependent<DocumentableSource>,
override val extra: PropertyContainer<UnresolvedBound> = PropertyContainer.empty()
) : Bound(), AnnotationTarget, WithExtraProperties<UnresolvedBound> {
) : Bound(), AnnotationTarget, WithExtraProperties<UnresolvedBound>, WithSources {
override fun withNewExtras(newExtras: PropertyContainer<UnresolvedBound>): UnresolvedBound =
copy(extra = newExtras)
}

// The following Projections are not AnnotationTargets; they cannot be annotated.
data class Nullable(val inner: Bound) : Bound()

sealed class Variance<out T : Bound> : Projection() {
data class Nullable(val inner: Bound) : Bound(), WithSources {
override val sources: SourceSetDependent<DocumentableSource>
get() = when (inner) {
is Nullable -> throw RuntimeException("Nullable Nullable is not a valid type")
is Dynamic -> throw RuntimeException("Nullable Dynamic is not a valid type")
is JavaObject -> inner.sources
is PrimitiveJavaType -> inner.sources
is TypeAliased -> inner.sources
is TypeConstructor -> inner.sources
is TypeParameter -> inner.sources
is UnresolvedBound -> inner.sources
is Void -> inner.sources
}
}

sealed class Variance<out T : Bound> : Projection(), WithSources {
abstract val inner: T

override val sources: SourceSetDependent<DocumentableSource> get() = when (inner) {
is WithSources -> (inner as WithSources).sources
is Dynamic -> TODO()
is Void -> TODO()
else -> throw RuntimeException("Impossible inner Bound for Variance: $inner")
}
}

data class Covariance<out T : Bound>(override val inner: T) : Variance<T>() {
Expand All @@ -475,15 +512,18 @@ data class Invariance<out T : Bound>(override val inner: T) : Variance<T>() {
override fun toString() = ""
}

// Void cannot be an object because not all Void types are the same. For example, a Void declared in Java is of
// platform nullability, while a (non-wrapped) Void declared in Kotlin is non-null.
class Void(override val sources: SourceSetDependent<DocumentableSource>) : Bound(), WithSources
// TODO: should these be WithSources? (that would require they be classes)
object Dynamic : Bound()
object Star : Projection()

object Void : Bound()
object Dynamic : Bound()

fun Variance<TypeParameter>.withDri(dri: DRI) = when (this) {
is Contravariance -> Contravariance(TypeParameter(dri, inner.name, inner.presentableName))
is Covariance -> Covariance(TypeParameter(dri, inner.name, inner.presentableName))
is Invariance -> Invariance(TypeParameter(dri, inner.name, inner.presentableName))
fun Variance<TypeParameter>.withDri(dri: DRI, sources: SourceSetDependent<DocumentableSource>) = when (this) {
is Contravariance -> Contravariance(TypeParameter(dri, inner.name, inner.presentableName, sources))
is Covariance -> Covariance(TypeParameter(dri, inner.name, inner.presentableName, sources))
is Invariance -> Invariance(TypeParameter(dri, inner.name, inner.presentableName, sources))
}

fun Documentable.dfs(predicate: (Documentable) -> Boolean): Documentable? =
Expand Down Expand Up @@ -512,6 +552,11 @@ fun <T> SourceSetDependent<T>?.orEmpty(): SourceSetDependent<T> = this ?: emptyM

interface DocumentableSource {
val path: String
val language: Language
}

data class TypeConstructorWithKind(val typeConstructor: TypeConstructor, val kind: ClassKind)

public fun WithSources.sourceLanguage(sourceSet: DokkaSourceSet) = sources[sourceSet]!!.language

public val WithSources.sourceLanguage: Language get() = this.sources.entries.single().value.language
5 changes: 5 additions & 0 deletions core/src/main/kotlin/model/documentableProperties.kt
Expand Up @@ -46,3 +46,8 @@ data class CheckedExceptions(val exceptions: SourceSetDependent<List<DRI>>) : Ex
}
override val key: ExtraProperty.Key<Documentable, *> = CheckedExceptions
}

enum class Language {
JAVA, KOTLIN, XML, JS, UNKNOWN
}

14 changes: 8 additions & 6 deletions core/src/main/kotlin/model/documentableUtils.kt
Expand Up @@ -9,13 +9,15 @@ fun DTypeParameter.filter(filteredSet: Set<DokkaSourceSet>) =
if (filteredSet.containsAll(sourceSets)) this
else {
val intersection = filteredSet.intersect(sourceSets)
val filteredSources = sources.filtered(intersection)
if (intersection.isEmpty()) null
else DTypeParameter(
variantTypeParameter,
documentation.filtered(intersection),
expectPresentInSet?.takeIf { intersection.contains(expectPresentInSet) },
bounds,
intersection,
extra
variantTypeParameter = variantTypeParameter,
documentation = documentation.filtered(intersection),
expectPresentInSet = expectPresentInSet?.takeIf { intersection.contains(expectPresentInSet) },
bounds = bounds,
sources = filteredSources,
sourceSets = intersection,
extra = extra
)
}
Expand Up @@ -34,3 +34,4 @@ fun PreMergeDocumentableTransformer.perPackageOptions(documentable: Documentable

fun <T> PreMergeDocumentableTransformer.source(documentable: T) where T : Documentable, T : WithSources =
checkNotNull(documentable.sources[sourceSet(documentable)])
{ "Sources were null for ${sourceSet(documentable)} \nfor $documentable" }
16 changes: 10 additions & 6 deletions core/src/test/kotlin/model/DocumentableTest.kt
Expand Up @@ -39,7 +39,7 @@ class DocumentableTest {
modifier = emptyMap(),
sources = emptyMap(),
sourceSets = emptySet(),
type = Void,
type = Void(emptyMap()),
receiver = null,
isConstructor = false,
isExpectActual = false,
Expand All @@ -50,17 +50,19 @@ class DocumentableTest {
documentation = emptyMap(),
expectPresentInSet = null,
extra = PropertyContainer.empty(),
sources = emptyMap(),
sourceSets = emptySet(),
type = Void
type = Void(emptyMap())
),
DParameter(
dri = DRI(),
name = "f0p1",
documentation = emptyMap(),
expectPresentInSet = null,
extra = PropertyContainer.empty(),
sources = emptyMap(),
sourceSets = emptySet(),
type = Void
type = Void(emptyMap())
)
)
),
Expand All @@ -75,7 +77,7 @@ class DocumentableTest {
modifier = emptyMap(),
sources = emptyMap(),
sourceSets = emptySet(),
type = Void,
type = Void(emptyMap()),
receiver = null,
isConstructor = false,
isExpectActual = false,
Expand All @@ -87,7 +89,8 @@ class DocumentableTest {
expectPresentInSet = null,
extra = PropertyContainer.empty(),
sourceSets = emptySet(),
type = Void
sources = emptyMap(),
type = Void(emptyMap())
),
DParameter(
dri = DRI(),
Expand All @@ -96,7 +99,8 @@ class DocumentableTest {
expectPresentInSet = null,
extra = PropertyContainer.empty(),
sourceSets = emptySet(),
type = Void
sources = emptyMap(),
type = Void(emptyMap())
)
)
)
Expand Down