diff options
author | Szymon Świstun <sswistun@virtuslab.com> | 2020-01-20 14:55:42 +0100 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-02-12 13:13:18 +0100 |
commit | 50e711d24b517bc93c37d89f258c9dafaa038ad1 (patch) | |
tree | 201c27b6860ac14b6ddc673ff099d74f53b4e15c /core/src/main/kotlin/transformers | |
parent | 5a432c9c62ff95779a495fb354c83f5f7c481a1d (diff) | |
download | dokka-50e711d24b517bc93c37d89f258c9dafaa038ad1.tar.gz dokka-50e711d24b517bc93c37d89f258c9dafaa038ad1.tar.bz2 dokka-50e711d24b517bc93c37d89f258c9dafaa038ad1.zip |
kotlin-as-java plugin
Diffstat (limited to 'core/src/main/kotlin/transformers')
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 } } |