aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/transformers
diff options
context:
space:
mode:
authorSzymon Świstun <sswistun@virtuslab.com>2020-01-20 14:55:42 +0100
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-02-12 13:13:18 +0100
commit50e711d24b517bc93c37d89f258c9dafaa038ad1 (patch)
tree201c27b6860ac14b6ddc673ff099d74f53b4e15c /core/src/main/kotlin/transformers
parent5a432c9c62ff95779a495fb354c83f5f7c481a1d (diff)
downloaddokka-50e711d24b517bc93c37d89f258c9dafaa038ad1.tar.gz
dokka-50e711d24b517bc93c37d89f258c9dafaa038ad1.tar.bz2
dokka-50e711d24b517bc93c37d89f258c9dafaa038ad1.zip
kotlin-as-java plugin
Diffstat (limited to 'core/src/main/kotlin/transformers')
-rw-r--r--core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt192
-rw-r--r--core/src/main/kotlin/transformers/documentation/DefaultDocumentationNodeMerger.kt13
-rw-r--r--core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt46
3 files changed, 184 insertions, 67 deletions
diff --git a/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt b/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt
index 651bd223..dd2d1681 100644
--- a/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt
+++ b/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt
@@ -5,10 +5,10 @@ import org.jetbrains.dokka.links.Callable
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.links.withClass
import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.ClassKind
import org.jetbrains.dokka.model.Enum
import org.jetbrains.dokka.model.Function
import org.jetbrains.dokka.model.Property
-import org.jetbrains.dokka.model.ClassKind
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.pages.PlatformData
import org.jetbrains.dokka.parsers.MarkdownParser
@@ -31,21 +31,26 @@ object DefaultDescriptorToDocumentationTranslator : DescriptorToDocumentationTra
platformData: PlatformData,
context: DokkaContext
) = DokkaDescriptorVisitor(platformData, context.platforms[platformData]?.facade!!).run {
- packageFragments.map { visitPackageFragmentDescriptor(it, DRIWithPlatformInfo(DRI.topLevel, null, emptyList())) }
+ packageFragments.map {
+ visitPackageFragmentDescriptor(
+ it,
+ DRIWithPlatformInfo(DRI.topLevel, null, emptyList())
+ )
+ }
}.let { Module(moduleName, it) }
}
-internal data class DRIWithPlatformInfo(
+data class DRIWithPlatformInfo(
val dri: DRI,
val expected: PlatformInfo?,
val actual: List<PlatformInfo>
)
-private fun DRI.withEmptyInfo() = DRIWithPlatformInfo(this, null, emptyList())
+fun DRI.withEmptyInfo() = DRIWithPlatformInfo(this, null, emptyList())
-internal class DokkaDescriptorVisitor(
+open class DokkaDescriptorVisitor(
private val platformData: PlatformData,
private val resolutionFacade: DokkaResolutionFacade
) : DeclarationDescriptorVisitorEmptyBodies<Documentable, DRIWithPlatformInfo>() {
@@ -59,6 +64,7 @@ internal class DokkaDescriptorVisitor(
): Package {
val driWithPlatform = DRI(packageName = descriptor.fqName.asString()).withEmptyInfo()
val scope = descriptor.getMemberScope()
+
return Package(
dri = driWithPlatform.dri,
functions = scope.functions(driWithPlatform),
@@ -67,10 +73,11 @@ internal class DokkaDescriptorVisitor(
)
}
- override fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Classlike = when (descriptor.kind) {
- org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent)
- else -> classDescriptor(descriptor, parent)
- }
+ override fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Classlike =
+ when (descriptor.kind) {
+ org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent)
+ else -> classDescriptor(descriptor, parent)
+ }
fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Enum {
val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo()
@@ -80,14 +87,19 @@ internal class DokkaDescriptorVisitor(
return Enum(
dri = driWithPlatform.dri,
name = descriptor.name.asString(),
- entries = scope.classlikes(driWithPlatform).filter { it.kind == KotlinClassKindTypes.ENUM_ENTRY }.map { EnumEntry(it) },
+ entries = scope.classlikes(driWithPlatform).filter { it.kind == KotlinClassKindTypes.ENUM_ENTRY }.map {
+ EnumEntry(
+ it
+ )
+ },
constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) },
functions = scope.functions(driWithPlatform),
properties = scope.properties(driWithPlatform),
classlikes = scope.classlikes(driWithPlatform),
expected = descriptor.takeIf { it.isExpect }?.resolveClassDescriptionData(),
actual = listOfNotNull(descriptorData),
- extra = mutableSetOf() // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet()
+ extra = mutableSetOf(), // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet()
+ visibility = mapOf(platformData to descriptor.visibility)
)
}
@@ -101,23 +113,26 @@ internal class DokkaDescriptorVisitor(
dri = driWithPlatform.dri,
name = descriptor.name.asString(),
kind = KotlinClassKindTypes.valueOf(descriptor.kind.toString()),
- constructors = descriptor.constructors.map { visitConstructorDescriptor(
- it,
- if(it.isPrimary)
- DRIWithPlatformInfo(
- driWithPlatform.dri,
- expected?.info.filterTagWrappers(listOf(Constructor::class)),
- actual.filterTagWrappers(listOf(Constructor::class))
- )
- else
- DRIWithPlatformInfo(driWithPlatform.dri, null, emptyList())
- ) },
+ constructors = descriptor.constructors.map {
+ visitConstructorDescriptor(
+ it,
+ if (it.isPrimary)
+ DRIWithPlatformInfo(
+ driWithPlatform.dri,
+ expected?.info.filterTagWrappers(listOf(Constructor::class)),
+ actual.filterTagWrappers(listOf(Constructor::class))
+ )
+ else
+ DRIWithPlatformInfo(driWithPlatform.dri, null, emptyList())
+ )
+ },
functions = scope.functions(driWithPlatform),
properties = scope.properties(driWithPlatform),
classlikes = scope.classlikes(driWithPlatform),
expected = expected,
actual = actual,
- extra = mutableSetOf() // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet()
+ extra = mutableSetOf(), // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet()
+ visibility = mapOf(platformData to descriptor.visibility)
)
}
@@ -125,19 +140,24 @@ internal class DokkaDescriptorVisitor(
val expected = descriptor.takeIf { it.isExpect }?.resolveDescriptorData()
val actual = listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData())
val dri = parent.dri.copy(callable = Callable.from(descriptor))
+
return Property(
dri = dri,
name = descriptor.name.asString(),
- receiver = descriptor.extensionReceiverParameter?.let { visitReceiverParameterDescriptor(
- it,
- DRIWithPlatformInfo(
- dri,
- expected?.filterTagWrappers(listOf(Receiver::class)),
- actual.filterTagWrappers(listOf(Receiver::class))
+ receiver = descriptor.extensionReceiverParameter?.let {
+ visitReceiverParameterDescriptor(
+ it,
+ DRIWithPlatformInfo(
+ dri,
+ expected?.filterTagWrappers(listOf(Receiver::class)),
+ actual.filterTagWrappers(listOf(Receiver::class))
+ )
)
- ) },
+ },
expected = expected,
- actual = actual
+ actual = actual,
+ accessors = descriptor.accessors.map { visitPropertyAccessorDescriptor(it, descriptor, dri) },
+ visibility = mapOf(platformData to descriptor.visibility)
)
}
@@ -145,28 +165,35 @@ internal class DokkaDescriptorVisitor(
val expected = descriptor.takeIf { it.isExpect }?.resolveDescriptorData()
val actual = listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData())
val dri = parent.dri.copy(callable = Callable.from(descriptor))
+
return Function(
dri = dri,
name = descriptor.name.asString(),
returnType = descriptor.returnType?.let { KotlinTypeWrapper(it) },
isConstructor = false,
- receiver = descriptor.extensionReceiverParameter?.let { visitReceiverParameterDescriptor(
- it,
- DRIWithPlatformInfo(
- dri,
- expected?.filterTagWrappers(listOf(Receiver::class)),
- actual.filterTagWrappers(listOf(Receiver::class))
+ receiver = descriptor.extensionReceiverParameter?.let {
+ visitReceiverParameterDescriptor(
+ it,
+ DRIWithPlatformInfo(
+ dri,
+ expected?.filterTagWrappers(listOf(Receiver::class)),
+ actual.filterTagWrappers(listOf(Receiver::class))
+ )
)
- ) },
- parameters = descriptor.valueParameters.mapIndexed { index, desc -> parameter(index, desc,
- DRIWithPlatformInfo(
- dri,
- expected.filterTagWrappers(listOf(Param::class), desc.name.asString()),
- actual.filterTagWrappers(listOf(Param::class), desc.name.asString())
+ },
+ parameters = descriptor.valueParameters.mapIndexed { index, desc ->
+ parameter(
+ index, desc,
+ DRIWithPlatformInfo(
+ dri,
+ expected.filterTagWrappers(listOf(Param::class), desc.name.asString()),
+ actual.filterTagWrappers(listOf(Param::class), desc.name.asString())
+ )
)
- ) },
+ },
expected = expected,
- actual = actual
+ actual = actual,
+ visibility = mapOf(platformData to descriptor.visibility)
)
}
@@ -178,15 +205,19 @@ internal class DokkaDescriptorVisitor(
returnType = KotlinTypeWrapper(descriptor.returnType),
isConstructor = true,
receiver = null,
- parameters = descriptor.valueParameters.mapIndexed { index, desc -> parameter(index, desc,
- DRIWithPlatformInfo(
- dri,
- parent.expected.filterTagWrappers(listOf(Param::class)),
- parent.actual.filterTagWrappers(listOf(Param::class))
+ parameters = descriptor.valueParameters.mapIndexed { index, desc ->
+ parameter(
+ index, desc,
+ DRIWithPlatformInfo(
+ dri,
+ parent.expected.filterTagWrappers(listOf(Param::class)),
+ parent.actual.filterTagWrappers(listOf(Param::class))
+ )
)
- ) },
+ },
expected = parent.expected ?: descriptor.takeIf { it.isExpect }?.resolveDescriptorData(),
- actual = parent.actual
+ actual = parent.actual,
+ visibility = mapOf(platformData to descriptor.visibility)
)
}
@@ -201,6 +232,50 @@ internal class DokkaDescriptorVisitor(
actual = parent.actual
)
+ open fun visitPropertyAccessorDescriptor(
+ descriptor: PropertyAccessorDescriptor,
+ propertyDescriptor: PropertyDescriptor,
+ parent: DRI
+ ): Function {
+ val dri = parent.copy(callable = Callable.from(descriptor))
+ val isGetter = descriptor is PropertyGetterDescriptor
+
+ fun PropertyDescriptor.asParameter(parent: DRI) =
+ Parameter(
+ parent.copy(target = 1),
+ this.name.asString(),
+ KotlinTypeWrapper(this.type),
+ descriptor.takeIf { it.isExpect }?.resolveDescriptorData(),
+ listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData())
+ )
+
+ val name = run {
+ val modifier = if (isGetter) "get" else "set"
+ val rawName = propertyDescriptor.name.asString()
+ "$modifier${rawName[0].toUpperCase()}${rawName.drop(1)}"
+ }
+
+ descriptor.visibility
+ val parameters =
+ if (isGetter) {
+ emptyList()
+ } else {
+ listOf(propertyDescriptor.asParameter(dri))
+ }
+
+ return Function(
+ dri,
+ name,
+ descriptor.returnType?.let { KotlinTypeWrapper(it) },
+ false,
+ null,
+ parameters,
+ descriptor.takeIf { it.isExpect }?.resolveDescriptorData(),
+ listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()),
+ visibility = mapOf(platformData to descriptor.visibility)
+ )
+ }
+
private fun parameter(index: Int, descriptor: ValueParameterDescriptor, parent: DRIWithPlatformInfo) =
Parameter(
dri = parent.dri.copy(target = index + 1),
@@ -229,6 +304,7 @@ internal class DokkaDescriptorVisitor(
val doc = findKDoc()
val parser: MarkdownParser = MarkdownParser(resolutionFacade, this)
val docHeader = parser.parseFromKDocTag(doc)
+
return BasePlatformInfo(docHeader, listOf(platformData))
}
@@ -237,8 +313,11 @@ internal class DokkaDescriptorVisitor(
(getSuperInterfaces() + getAllSuperclassesWithoutAny()).map { DRI.from(it) })
}
- private fun PlatformInfo?.filterTagWrappers(types: List<KClass<out TagWrapper>>, name: String? = null): PlatformInfo? {
- if(this == null)
+ private fun PlatformInfo?.filterTagWrappers(
+ types: List<KClass<out TagWrapper>>,
+ name: String? = null
+ ): PlatformInfo? {
+ if (this == null)
return null
return BasePlatformInfo(
DocumentationNode(
@@ -248,7 +327,10 @@ internal class DokkaDescriptorVisitor(
)
}
- private fun List<PlatformInfo>.filterTagWrappers(types: List<KClass<out TagWrapper>>, name: String? = null): List<PlatformInfo> =
+ private fun List<PlatformInfo>.filterTagWrappers(
+ types: List<KClass<out TagWrapper>>,
+ name: String? = null
+ ): List<PlatformInfo> =
this.map { it.filterTagWrappers(types, name)!! }
}
diff --git a/core/src/main/kotlin/transformers/documentation/DefaultDocumentationNodeMerger.kt b/core/src/main/kotlin/transformers/documentation/DefaultDocumentationNodeMerger.kt
index ec67ea88..0d7fa249 100644
--- a/core/src/main/kotlin/transformers/documentation/DefaultDocumentationNodeMerger.kt
+++ b/core/src/main/kotlin/transformers/documentation/DefaultDocumentationNodeMerger.kt
@@ -52,7 +52,8 @@ fun Function.mergeWith(other: Function): Function = Function(
if (receiver != null && other.receiver != null) receiver.mergeWith(other.receiver) else null,
merge(parameters + other.parameters, Parameter::mergeWith),
expected?.mergeWith(other.expected),
- (actual + other.actual).merge()
+ (actual + other.actual).merge(),
+ visibility = (visibility + other.visibility)
)
fun Property.mergeWith(other: Property) = Property(
@@ -60,7 +61,9 @@ fun Property.mergeWith(other: Property) = Property(
name,
if (receiver != null && other.receiver != null) receiver.mergeWith(other.receiver) else null,
expected?.mergeWith(other.expected),
- (actual + other.actual).merge()
+ (actual + other.actual).merge(),
+ accessors = (this.accessors + other.accessors).distinct(),
+ visibility = (visibility + other.visibility)
)
fun Classlike.mergeWith(other: Classlike): Classlike = when {
@@ -78,7 +81,8 @@ fun Class.mergeWith(other: Class) = Class(
properties = merge(properties + other.properties, Property::mergeWith),
classlikes = merge(classlikes + other.classlikes, Classlike::mergeWith),
expected = expected?.mergeWith(other.expected),
- actual = (actual + other.actual).mergeClassPlatformInfo()
+ actual = (actual + other.actual).mergeClassPlatformInfo(),
+ visibility = (visibility + other.visibility)
)
fun Enum.mergeWith(other: Enum) = Enum(
@@ -90,7 +94,8 @@ fun Enum.mergeWith(other: Enum) = Enum(
expected = expected?.mergeWith(other.expected),
actual = (actual + other.actual).mergeClassPlatformInfo(),
entries = (this.entries + other.entries.distinctBy { it.dri }.toList()),
- constructors = merge(constructors + other.constructors, Function::mergeWith)
+ constructors = merge(constructors + other.constructors, Function::mergeWith),
+ visibility = visibility
)
fun Parameter.mergeWith(other: Parameter) = Parameter(
diff --git a/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt b/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt
index 05c07070..2078faa7 100644
--- a/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt
+++ b/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt
@@ -12,6 +12,7 @@ import org.jetbrains.dokka.model.Function
import org.jetbrains.dokka.pages.PlatformData
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.utilities.DokkaLogger
+import org.jetbrains.kotlin.descriptors.Visibilities
object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator {
@@ -47,6 +48,14 @@ object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator {
return listOf(BasePlatformInfo(comment, listOf(platformData)))
}
+ private fun PsiModifierListOwner.getVisibility() = modifierList?.children?.toList()?.let { ml ->
+ when {
+ ml.any { it.text == PsiKeyword.PUBLIC } -> Visibilities.PUBLIC
+ ml.any { it.text == PsiKeyword.PROTECTED } -> Visibilities.PROTECTED
+ else -> Visibilities.PRIVATE
+ }
+ } ?: Visibilities.PRIVATE
+
fun parseClass(psi: PsiClass, parent: DRI): Class = with(psi) {
val kind = when {
isAnnotationType -> JavaClassKindTypes.ANNOTATION_CLASS
@@ -62,6 +71,7 @@ object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator {
link(superClass, node, RefKind.Inheritor)
}
}*/
+
return Class(
dri,
name.orEmpty(),
@@ -72,7 +82,8 @@ object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator {
innerClasses.map { parseClass(it, dri) },
null,
emptyList(),
- mutableSetOf()
+ mutableSetOf(),
+ visibility = mapOf(platformData to psi.getVisibility())
)
}
@@ -101,7 +112,8 @@ object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator {
)
},
null,
- getComment(psi)
+ getComment(psi),
+ visibility = mapOf(platformData to psi.getVisibility())
)
}
@@ -118,7 +130,9 @@ object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator {
psi.name,
null,
null,
- getComment(psi)
+ getComment(psi),
+ accessors = emptyList(),
+ visibility = mapOf(platformData to psi.getVisibility())
)
}
}
@@ -132,16 +146,28 @@ enum class JavaClassKindTypes : ClassKind {
ANNOTATION_CLASS;
}
-class JavaTypeWrapper(
- type: PsiType
-) : TypeWrapper {
+class JavaTypeWrapper : TypeWrapper {
override val constructorFqName: String?
override val constructorNamePathSegments: List<String>
- override val arguments: List<JavaTypeWrapper>
+ override val arguments: List<TypeWrapper>
override val dri: DRI?
+ val isPrimitive: Boolean
+
+ constructor(
+ constructorNamePathSegments: List<String>,
+ arguments: List<TypeWrapper>,
+ dri: DRI?,
+ isPrimitiveType: Boolean
+ ) {
+ this.constructorFqName = constructorNamePathSegments.joinToString(".")
+ this.constructorNamePathSegments = constructorNamePathSegments
+ this.arguments = arguments
+ this.dri = dri
+ this.isPrimitive = isPrimitiveType
+ }
- init {
+ constructor(type: PsiType) {
if (type is PsiClassReferenceType) {
val resolved = type.resolve()
constructorFqName = resolved?.qualifiedName
@@ -150,22 +176,26 @@ class JavaTypeWrapper(
if (it is PsiClassReferenceType) JavaTypeWrapper(it) else null
}
dri = fromPsi(type)
+ this.isPrimitive = false
} else if (type is PsiEllipsisType) {
constructorFqName = type.canonicalText
constructorNamePathSegments = listOf(type.canonicalText) // TODO
arguments = emptyList()
dri = DRI("java.lang", "Object") // TODO
+ this.isPrimitive = false
} else if (type is PsiArrayType) {
constructorFqName = type.canonicalText
constructorNamePathSegments = listOf(type.canonicalText)
arguments = emptyList()
dri = (type as? PsiClassReferenceType)?.let { fromPsi(it) } // TODO
+ this.isPrimitive = false
} else {
type as PsiPrimitiveType
constructorFqName = type.name
constructorNamePathSegments = type.name.split('.')
arguments = emptyList()
dri = null
+ this.isPrimitive = true
}
}