aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/kotlin/Analysis/AnalysisEnvironment.kt44
-rw-r--r--core/src/main/kotlin/Formats/StructuredFormatService.kt25
-rw-r--r--core/src/main/kotlin/Kotlin/DocumentationBuilder.kt96
-rw-r--r--core/src/main/kotlin/Kotlin/KotlinLanguageService.kt8
-rw-r--r--core/src/main/kotlin/Model/DocumentationNode.kt5
-rw-r--r--core/src/test/kotlin/format/MarkdownFormatTest.kt7
-rw-r--r--core/src/test/kotlin/javadoc/JavadocTest.kt17
-rw-r--r--core/src/test/kotlin/model/TypeAliasTest.kt123
-rw-r--r--core/testdata/format/exceptionClass.md2
-rw-r--r--core/testdata/format/exceptionClass.package.md2
-rw-r--r--core/testdata/format/typeAliases.kt27
-rw-r--r--core/testdata/format/typeAliases.md63
-rw-r--r--core/testdata/format/typeAliases.package.md24
-rw-r--r--core/testdata/javadoc/typealiases.kt11
-rw-r--r--core/testdata/typealias/asTypeBoundWithVariance.kt7
-rw-r--r--core/testdata/typealias/chain.kt8
-rw-r--r--core/testdata/typealias/deprecated.kt7
-rw-r--r--core/testdata/typealias/documented.kt9
-rw-r--r--core/testdata/typealias/functional.kt10
-rw-r--r--core/testdata/typealias/generic.kt7
-rw-r--r--core/testdata/typealias/inheritanceFromTypeAlias.kt7
-rw-r--r--core/testdata/typealias/simple.kt5
22 files changed, 449 insertions, 65 deletions
diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt
index e365207c..b192794e 100644
--- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt
+++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt
@@ -30,14 +30,17 @@ import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
+import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
+import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
+import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import java.io.File
@@ -82,28 +85,57 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
return environment
}
+ fun createSourceModuleSearchScope(project: Project, sourceFiles: List<KtFile>): GlobalSearchScope {
+ // TODO: Fix when going to implement dokka for JS
+ return TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
+ }
+
+
fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade {
+
val projectContext = ProjectContext(environment.project)
val sourceFiles = environment.getSourceFiles()
+
+ val library = object : ModuleInfo {
+ override val name: Name = Name.special("<library>")
+ override fun dependencies(): List<ModuleInfo> = listOf(this)
+ }
val module = object : ModuleInfo {
override val name: Name = Name.special("<module>")
- override fun dependencies(): List<ModuleInfo> = listOf(this)
+ override fun dependencies(): List<ModuleInfo> = listOf(this, library)
}
+ val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles)
+
val builtIns = JvmBuiltIns(projectContext.storageManager)
val resolverForProject = JvmAnalyzerFacade.setupResolverForProject(
"Dokka",
projectContext,
- listOf(module),
- { ModuleContent(sourceFiles, GlobalSearchScope.allScope(environment.project)) },
- JvmPlatformParameters { module },
+ listOf(library, module),
+ {
+ when (it) {
+ library -> ModuleContent(emptyList(), GlobalSearchScope.notScope(sourcesScope))
+ module -> ModuleContent(sourceFiles, sourcesScope)
+ else -> throw IllegalArgumentException("Unexpected module info")
+ }
+ },
+ JvmPlatformParameters {
+ val file = (it as JavaClassImpl).psi.containingFile.virtualFile
+ if (file in sourcesScope)
+ module
+ else
+ library
+ },
CompilerEnvironment,
- packagePartProviderFactory = { info, content -> JvmPackagePartProvider(environment, content.moduleContentScope) },
+ packagePartProviderFactory = {
+ info, content ->
+ JvmPackagePartProvider(environment, content.moduleContentScope)
+ },
builtIns = builtIns
)
-
+ resolverForProject.resolverForModule(library) // Required before module to initialize library properly
val resolverForModule = resolverForProject.resolverForModule(module)
val moduleDescriptor = resolverForProject.descriptorForModule(module)
builtIns.initialize(moduleDescriptor, true)
diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt
index f24c9c2d..a7a50f91 100644
--- a/core/src/main/kotlin/Formats/StructuredFormatService.kt
+++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt
@@ -23,11 +23,9 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
body()
if (checkEndsWith && to.endsWith(suffix)) {
to.setLength(to.length - suffix.length)
- }
- else if (to.length > startLength + prefix.length) {
+ } else if (to.length > startLength + prefix.length) {
to.append(suffix)
- }
- else {
+ } else {
to.setLength(startLength)
}
}
@@ -124,8 +122,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
val child = content.children.singleOrNull()
if (child is ContentParagraph) {
appendContent(child.children)
- }
- else {
+ } else {
appendContent(content.children)
}
}
@@ -361,7 +358,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
}
inner class SingleNodePageBuilder(val node: DocumentationNode)
- : PageBuilder(listOf(node)) {
+ : PageBuilder(listOf(node)) {
override fun build() {
super.build()
@@ -372,14 +369,15 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
}
appendSection("Packages", node.members(NodeKind.Package))
- appendSection("Types", node.members.filter { it.kind in NodeKind.classLike && it.kind != NodeKind.AnnotationClass && it.kind != NodeKind.Exception })
+ appendSection("Types", node.members.filter { it.kind in NodeKind.classLike && it.kind != NodeKind.TypeAlias && it.kind != NodeKind.AnnotationClass && it.kind != NodeKind.Exception })
appendSection("Annotations", node.members(NodeKind.AnnotationClass))
appendSection("Exceptions", node.members(NodeKind.Exception))
+ appendSection("Type Aliases", node.members(NodeKind.TypeAlias))
appendSection("Extensions for External Classes", node.members(NodeKind.ExternalClass))
appendSection("Enum Values", node.members(NodeKind.EnumItem), sortMembers = false)
appendSection("Constructors", node.members(NodeKind.Constructor))
appendSection("Properties", node.members(NodeKind.Property))
- appendSection("Inherited Properties", node.inheritedMembers(NodeKind.Property))
+ appendSection("Inherited Properties", node.inheritedMembers(NodeKind.Property))
appendSection("Functions", node.members(NodeKind.Function))
appendSection("Inherited Functions", node.inheritedMembers(NodeKind.Function))
appendSection("Companion Object Properties", node.members(NodeKind.CompanionObjectProperty))
@@ -394,6 +392,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
NodeKind.Object,
NodeKind.AnnotationClass,
NodeKind.Exception,
+ NodeKind.TypeAlias,
NodeKind.Constructor,
NodeKind.Property,
NodeKind.Package,
@@ -472,7 +471,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
}
inner class AllTypesNodeBuilder(val node: DocumentationNode)
- : PageBuilder(listOf(node)) {
+ : PageBuilder(listOf(node)) {
override fun build() {
appendContent(node.owner!!.summary)
@@ -508,12 +507,10 @@ abstract class StructuredOutputBuilder(val to: StringBuilder,
if (singleNode != null) {
if (singleNode.kind == NodeKind.AllTypes) {
AllTypesNodeBuilder(singleNode).build()
- }
- else {
+ } else {
SingleNodePageBuilder(singleNode).build()
}
- }
- else {
+ } else {
PageBuilder(nodes).build()
}
}
diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
index ecb6edf2..f922a25b 100644
--- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
+++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
@@ -25,10 +25,7 @@ import org.jetbrains.kotlin.resolve.findTopMostOverriddenDescriptors
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.resolve.source.getPsi
-import org.jetbrains.kotlin.types.ErrorUtils
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.TypeProjection
-import org.jetbrains.kotlin.types.TypeUtils
+import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.supertypes
@@ -61,13 +58,12 @@ interface PackageDocumentationBuilder {
}
class DocumentationBuilder
- @Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val descriptorDocumentationParser: DescriptorDocumentationParser,
- val options: DocumentationOptions,
- val refGraph: NodeReferenceGraph,
- val logger: DokkaLogger,
- val linkResolver: DeclarationLinkResolver)
-{
+@Inject constructor(val resolutionFacade: DokkaResolutionFacade,
+ val descriptorDocumentationParser: DescriptorDocumentationParser,
+ val options: DocumentationOptions,
+ val refGraph: NodeReferenceGraph,
+ val logger: DokkaLogger,
+ val linkResolver: DeclarationLinkResolver) {
val boringBuiltinClasses = setOf(
"kotlin.Unit", "kotlin.Byte", "kotlin.Short", "kotlin.Int", "kotlin.Long", "kotlin.Char", "kotlin.Boolean",
"kotlin.Float", "kotlin.Double", "kotlin.String", "kotlin.Array", "kotlin.Any")
@@ -97,7 +93,7 @@ class DocumentationBuilder
return node
}
- private fun DocumentationNode.withModifiers(descriptor: DeclarationDescriptor) : DocumentationNode{
+ private fun DocumentationNode.withModifiers(descriptor: DeclarationDescriptor): DocumentationNode {
if (descriptor is MemberDescriptor) {
appendVisibility(descriptor)
if (descriptor !is ConstructorDescriptor) {
@@ -124,15 +120,15 @@ class DocumentationBuilder
appendTextNode(modifier, NodeKind.Modifier)
}
- fun DocumentationNode.appendSupertypes(descriptor: ClassDescriptor) {
- val superTypes = descriptor.typeConstructor.supertypes
- for (superType in superTypes) {
- if (!ignoreSupertype(superType)) {
- appendType(superType, NodeKind.Supertype)
- val superclass = superType?.constructor?.declarationDescriptor
- link(superclass, descriptor, RefKind.Inheritor)
- link(descriptor, superclass, RefKind.Superclass)
- }
+ fun DocumentationNode.appendSupertype(descriptor: ClassDescriptor, superType: KotlinType) {
+ val unwrappedType = superType.unwrap()
+ if (unwrappedType is AbbreviatedType) {
+ appendSupertype(descriptor, unwrappedType.abbreviation)
+ } else if (!ignoreSupertype(unwrappedType)) {
+ appendType(unwrappedType, NodeKind.Supertype)
+ val superclass = unwrappedType.constructor.declarationDescriptor
+ link(superclass, descriptor, RefKind.Inheritor)
+ link(descriptor, superclass, RefKind.Superclass)
}
}
@@ -148,8 +144,7 @@ class DocumentationBuilder
fun DocumentationNode.appendProjection(projection: TypeProjection, kind: NodeKind = NodeKind.Type) {
if (projection.isStarProjection) {
appendTextNode("*", NodeKind.Type)
- }
- else {
+ } else {
appendType(projection.type, kind, projection.projectionKind.label)
}
}
@@ -157,14 +152,17 @@ class DocumentationBuilder
fun DocumentationNode.appendType(kotlinType: KotlinType?, kind: NodeKind = NodeKind.Type, prefix: String = "") {
if (kotlinType == null)
return
+ (kotlinType.unwrap() as? AbbreviatedType)?.let {
+ return appendType(it.abbreviation)
+ }
+
val classifierDescriptor = kotlinType.constructor.declarationDescriptor
val name = when (classifierDescriptor) {
is ClassDescriptor -> {
if (classifierDescriptor.isCompanionObject) {
classifierDescriptor.containingDeclaration.name.asString() +
"." + classifierDescriptor.name.asString()
- }
- else {
+ } else {
classifierDescriptor.name.asString()
}
}
@@ -182,8 +180,7 @@ class DocumentationBuilder
val jdkLink = linkResolver.buildJdkLink(classifierDescriptor)
if (jdkLink != null) {
node.append(DocumentationNode(jdkLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link)
- }
- else {
+ } else {
link(node, classifierDescriptor,
if (classifierDescriptor.isBoringBuiltinClass()) RefKind.HiddenLink else RefKind.Link)
}
@@ -197,7 +194,7 @@ class DocumentationBuilder
}
fun ClassifierDescriptor.isBoringBuiltinClass(): Boolean =
- DescriptorUtils.getFqName(this).asString() in boringBuiltinClasses
+ DescriptorUtils.getFqName(this).asString() in boringBuiltinClasses
fun DocumentationNode.appendAnnotations(annotated: Annotated) {
annotated.annotations.filter { it.isDocumented() }.forEach {
@@ -250,8 +247,7 @@ class DocumentationBuilder
link(this, baseDescriptor, inheritedLinkKind)
}
null
- }
- else {
+ } else {
val descriptorToUse = if (descriptor is ConstructorDescriptor) descriptor else descriptor.original
appendChild(descriptorToUse, RefKind.Member)
}
@@ -378,9 +374,25 @@ class DocumentationBuilder
is TypeParameterDescriptor -> build()
is ValueParameterDescriptor -> build()
is ReceiverParameterDescriptor -> build()
+ is TypeAliasDescriptor -> build()
else -> throw IllegalStateException("Descriptor $this is not known")
}
+ fun TypeAliasDescriptor.build(): DocumentationNode {
+ val node = nodeForDescriptor(this, NodeKind.TypeAlias)
+
+ node.appendAnnotations(this)
+ node.appendModifiers(this)
+ node.appendInPageChildren(typeConstructor.parameters, RefKind.Detail)
+
+ node.appendType(underlyingType, NodeKind.TypeAliasUnderlyingType)
+
+ node.appendSourceLink(source)
+
+ register(this, node)
+ return node
+ }
+
fun ClassDescriptor.build(): DocumentationNode {
val kind = when {
kind == ClassKind.OBJECT -> NodeKind.Object
@@ -392,7 +404,9 @@ class DocumentationBuilder
else -> NodeKind.Class
}
val node = nodeForDescriptor(this, kind)
- node.appendSupertypes(this)
+ typeConstructor.supertypes.forEach {
+ node.appendSupertype(this, it)
+ }
if (getKind() != ClassKind.OBJECT && getKind() != ClassKind.ENUM_ENTRY) {
node.appendInPageChildren(typeConstructor.parameters, RefKind.Detail)
val constructorsToDocument = if (getKind() == ClassKind.ENUM_CLASS)
@@ -572,8 +586,7 @@ class DocumentationBuilder
var receiverClass: DeclarationDescriptor = type.constructor.declarationDescriptor!!
if ((receiverClass as? ClassDescriptor)?.isCompanionObject ?: false) {
receiverClass = receiverClass.containingDeclaration!!
- }
- else if (receiverClass is TypeParameterDescriptor) {
+ } else if (receiverClass is TypeParameterDescriptor) {
val upperBoundClass = receiverClass.upperBounds.singleOrNull()?.constructor?.declarationDescriptor
if (upperBoundClass != null) {
receiverClass = upperBoundClass
@@ -648,11 +661,10 @@ class KotlinPackageDocumentationBuilder : PackageDocumentationBuilder {
}
class KotlinJavaDocumentationBuilder
- @Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val documentationBuilder: DocumentationBuilder,
- val options: DocumentationOptions,
- val logger: DokkaLogger) : JavaDocumentationBuilder
-{
+@Inject constructor(val resolutionFacade: DokkaResolutionFacade,
+ val documentationBuilder: DocumentationBuilder,
+ val options: DocumentationOptions,
+ val logger: DokkaLogger) : JavaDocumentationBuilder {
override fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) {
val classDescriptors = file.classes.map {
val javaDescriptorResolver = resolutionFacade.getFrontendService(JavaDescriptorResolver::class.java)
@@ -731,8 +743,12 @@ fun CallableMemberDescriptor.getExtensionClassDescriptor(): ClassifierDescriptor
return null
}
-fun DeclarationDescriptor.signature(): String = when(this) {
- is ClassDescriptor, is PackageFragmentDescriptor, is PackageViewDescriptor -> DescriptorUtils.getFqName(this).asString()
+fun DeclarationDescriptor.signature(): String = when (this) {
+ is ClassDescriptor,
+ is PackageFragmentDescriptor,
+ is PackageViewDescriptor,
+ is TypeAliasDescriptor -> DescriptorUtils.getFqName(this).asString()
+
is PropertyDescriptor -> containingDeclaration.signature() + "$" + name + receiverSignature()
is FunctionDescriptor -> containingDeclaration.signature() + "$" + name + parameterSignature()
is ValueParameterDescriptor -> containingDeclaration.signature() + "/" + name
diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
index a0d8f95d..6fcf3772 100644
--- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
+++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
@@ -315,6 +315,7 @@ class KotlinLanguageService : LanguageService {
NodeKind.Interface -> keyword("interface ")
NodeKind.EnumItem -> keyword("enum val ")
NodeKind.Object -> keyword("object ")
+ NodeKind.TypeAlias -> keyword("typealias ")
else -> throw IllegalArgumentException("Node $node is not a class-like object")
}
@@ -322,6 +323,13 @@ class KotlinLanguageService : LanguageService {
renderTypeParametersForNode(node, renderMode)
renderSupertypesForNode(node, renderMode)
renderExtraTypeParameterConstraints(node, renderMode)
+
+ if (node.kind == NodeKind.TypeAlias) {
+ nbsp()
+ symbol("=")
+ nbsp()
+ renderType(node.detail(NodeKind.TypeAliasUnderlyingType), renderMode)
+ }
}
private fun ContentBlock.renderFunction(node: DocumentationNode,
diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt
index 9aacbca0..def0f626 100644
--- a/core/src/main/kotlin/Model/DocumentationNode.kt
+++ b/core/src/main/kotlin/Model/DocumentationNode.kt
@@ -13,6 +13,7 @@ enum class NodeKind {
Exception,
EnumItem,
Object,
+ TypeAlias,
Constructor,
Function,
@@ -30,6 +31,8 @@ enum class NodeKind {
UpperBound,
LowerBound,
+ TypeAliasUnderlyingType,
+
Modifier,
NullabilityModifier,
@@ -55,7 +58,7 @@ enum class NodeKind {
OverloadGroupNote;
companion object {
- val classLike = setOf(Class, Interface, Enum, AnnotationClass, Exception, Object)
+ val classLike = setOf(Class, Interface, Enum, AnnotationClass, Exception, Object, TypeAlias)
}
}
diff --git a/core/src/test/kotlin/format/MarkdownFormatTest.kt b/core/src/test/kotlin/format/MarkdownFormatTest.kt
index 7f0922ba..6e4c44c8 100644
--- a/core/src/test/kotlin/format/MarkdownFormatTest.kt
+++ b/core/src/test/kotlin/format/MarkdownFormatTest.kt
@@ -27,8 +27,6 @@ class MarkdownFormatTest {
verifyMarkdownPackage("annotationClass", withKotlinRuntime = true)
}
- //TODO: Enable after typealias support
- @Ignore("Disabled until we will correctly support typealias")
@Test fun exceptionClass() {
verifyMarkdownNode("exceptionClass", withKotlinRuntime = true)
verifyMarkdownPackage("exceptionClass", withKotlinRuntime = true)
@@ -229,6 +227,11 @@ class MarkdownFormatTest {
verifyMarkdownNodeByName("qualifiedNameLink", "foo", withKotlinRuntime = true)
}
+ @Test fun typeAliases() {
+ verifyMarkdownNode("typeAliases")
+ verifyMarkdownPackage("typeAliases")
+ }
+
private fun verifyMarkdownPackage(fileName: String, withKotlinRuntime: Boolean = false) {
verifyOutput("testdata/format/$fileName.kt", ".package.md", withKotlinRuntime = withKotlinRuntime) { model, output ->
markdownService.createOutputBuilder(output, tempLocation).appendNodes(model.members)
diff --git a/core/src/test/kotlin/javadoc/JavadocTest.kt b/core/src/test/kotlin/javadoc/JavadocTest.kt
index 41d22b47..4c0f7f0f 100644
--- a/core/src/test/kotlin/javadoc/JavadocTest.kt
+++ b/core/src/test/kotlin/javadoc/JavadocTest.kt
@@ -1,5 +1,6 @@
package org.jetbrains.dokka.javadoc
+import com.sun.javadoc.Type
import org.jetbrains.dokka.DokkaConsoleLogger
import org.jetbrains.dokka.tests.verifyModel
import org.junit.Assert.*
@@ -107,6 +108,22 @@ class JavadocTest {
}
}
+ @Test fun testTypeAliases() {
+ verifyJavadoc("testdata/javadoc/typealiases.kt", withKotlinRuntime = true) { doc ->
+ assertNull(doc.classNamed("B"))
+ assertNull(doc.classNamed("D"))
+
+ assertEquals("A", doc.classNamed("C")!!.superclass().name())
+ val methodParamType = doc.classNamed("TypealiasesKt")!!.methods()
+ .find { it.name() == "some" }!!.parameters().first()
+ .type()
+ assertEquals("kotlin.jvm.functions.Function1", methodParamType.qualifiedTypeName())
+ assertEquals("? super A, C", methodParamType.asParameterizedType().typeArguments()
+ .map(Type::qualifiedTypeName).joinToString())
+ }
+ }
+
+
private fun verifyJavadoc(name: String,
withJdk: Boolean = false,
withKotlinRuntime: Boolean = false,
diff --git a/core/src/test/kotlin/model/TypeAliasTest.kt b/core/src/test/kotlin/model/TypeAliasTest.kt
new file mode 100644
index 00000000..812fd9dc
--- /dev/null
+++ b/core/src/test/kotlin/model/TypeAliasTest.kt
@@ -0,0 +1,123 @@
+package org.jetbrains.dokka.tests
+
+import junit.framework.TestCase.assertEquals
+import org.jetbrains.dokka.Content
+import org.jetbrains.dokka.NodeKind
+import org.junit.Test
+
+class TypeAliasTest {
+ @Test
+ fun testSimple() {
+ verifyModel("testdata/typealias/simple.kt") {
+ val pkg = it.members.single()
+ with(pkg.member(NodeKind.TypeAlias)) {
+ assertEquals(Content.Empty, content)
+ assertEquals("B", name)
+ assertEquals("A", detail(NodeKind.TypeAliasUnderlyingType).name)
+ }
+ }
+ }
+
+ @Test
+ fun testInheritanceFromTypeAlias() {
+ verifyModel("testdata/typealias/inheritanceFromTypeAlias.kt") {
+ val pkg = it.members.single()
+ with(pkg.member(NodeKind.TypeAlias)) {
+ assertEquals(Content.Empty, content)
+ assertEquals("Same", name)
+ assertEquals("Some", detail(NodeKind.TypeAliasUnderlyingType).name)
+ assertEquals("My", inheritors.single().name)
+ }
+ with(pkg.members(NodeKind.Class).find { it.name == "My" }!!) {
+ assertEquals("Same", detail(NodeKind.Supertype).name)
+ }
+ }
+ }
+
+ @Test
+ fun testChain() {
+ verifyModel("testdata/typealias/chain.kt") {
+ val pkg = it.members.single()
+ with(pkg.members(NodeKind.TypeAlias).find { it.name == "B" }!!) {
+ assertEquals(Content.Empty, content)
+ assertEquals("A", detail(NodeKind.TypeAliasUnderlyingType).name)
+ }
+ with(pkg.members(NodeKind.TypeAlias).find { it.name == "C" }!!) {
+ assertEquals(Content.Empty, content)
+ assertEquals("B", detail(NodeKind.TypeAliasUnderlyingType).name)
+ }
+ }
+ }
+
+ @Test
+ fun testDocumented() {
+ verifyModel("testdata/typealias/documented.kt") {
+ val pkg = it.members.single()
+ with(pkg.member(NodeKind.TypeAlias)) {
+ assertEquals("Just typealias", content.summary.toTestString())
+ }
+ }
+ }
+
+ @Test
+ fun testDeprecated() {
+ verifyModel("testdata/typealias/deprecated.kt") {
+ val pkg = it.members.single()
+ with(pkg.member(NodeKind.TypeAlias)) {
+ assertEquals(Content.Empty, content)
+ assertEquals("Deprecated", deprecation!!.name)
+ assertEquals("\"Not mainstream now\"", deprecation!!.detail(NodeKind.Parameter).detail(NodeKind.Value).name)
+ }
+ }
+ }
+
+ @Test
+ fun testGeneric() {
+ verifyModel("testdata/typealias/generic.kt") {
+ val pkg = it.members.single()
+ with(pkg.members(NodeKind.TypeAlias).find { it.name == "B" }!!) {
+ assertEquals("Any", detail(NodeKind.TypeAliasUnderlyingType).detail(NodeKind.Type).name)
+ }
+
+ with(pkg.members(NodeKind.TypeAlias).find { it.name == "C" }!!) {
+ assertEquals("T", detail(NodeKind.TypeAliasUnderlyingType).detail(NodeKind.Type).name)
+ assertEquals("T", detail(NodeKind.TypeParameter).name)
+ }
+ }
+ }
+
+ @Test
+ fun testFunctional() {
+ verifyModel("testdata/typealias/functional.kt") {
+ val pkg = it.members.single()
+ with(pkg.member(NodeKind.TypeAlias)) {
+ assertEquals("Function1", detail(NodeKind.TypeAliasUnderlyingType).name)
+ val typeParams = detail(NodeKind.TypeAliasUnderlyingType).details(NodeKind.Type)
+ assertEquals("A", typeParams.first().name)
+ assertEquals("B", typeParams.last().name)
+ }
+
+ with(pkg.member(NodeKind.Function)) {
+ assertEquals("Spell", detail(NodeKind.Parameter).detail(NodeKind.Type).name)
+ }
+ }
+ }
+
+ @Test
+ fun testAsTypeBoundWithVariance() {
+ verifyModel("testdata/typealias/asTypeBoundWithVariance.kt") {
+ val pkg = it.members.single()
+ with(pkg.members(NodeKind.Class).find { it.name == "C" }!!) {
+ val tParam = detail(NodeKind.TypeParameter)
+ assertEquals("out", tParam.detail(NodeKind.Modifier).name)
+ assertEquals("B", tParam.detail(NodeKind.Type).link(NodeKind.TypeAlias).name)
+ }
+
+ with(pkg.members(NodeKind.Class).find { it.name == "D" }!!) {
+ val tParam = detail(NodeKind.TypeParameter)
+ assertEquals("in", tParam.detail(NodeKind.Modifier).name)
+ assertEquals("B", tParam.detail(NodeKind.Type).link(NodeKind.TypeAlias).name)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/core/testdata/format/exceptionClass.md b/core/testdata/format/exceptionClass.md
index df3457d7..e3714ecc 100644
--- a/core/testdata/format/exceptionClass.md
+++ b/core/testdata/format/exceptionClass.md
@@ -2,7 +2,7 @@
# MyException
-`class MyException : `[`Exception`](http://docs.oracle.com/javase/6/docs/api/java/lang/Exception.html)
+`class MyException : Exception`
### Constructors
diff --git a/core/testdata/format/exceptionClass.package.md b/core/testdata/format/exceptionClass.package.md
index e27dd0ab..e10478e4 100644
--- a/core/testdata/format/exceptionClass.package.md
+++ b/core/testdata/format/exceptionClass.package.md
@@ -4,5 +4,5 @@
### Exceptions
-| [MyException](test/-my-exception/index) | `class MyException : `[`Exception`](http://docs.oracle.com/javase/6/docs/api/java/lang/Exception.html) |
+| [MyException](test/-my-exception/index) | `class MyException : Exception` |
diff --git a/core/testdata/format/typeAliases.kt b/core/testdata/format/typeAliases.kt
new file mode 100644
index 00000000..9657963e
--- /dev/null
+++ b/core/testdata/format/typeAliases.kt
@@ -0,0 +1,27 @@
+
+class A
+class B
+class C<T>
+
+typealias D = A
+typealias E = D
+
+typealias F = (A) -> B
+
+typealias G = C<A>
+typealias H<T> = C<T>
+
+typealias I<T> = H<T>
+typealias J = H<A>
+
+typealias K = H<J>
+
+typealias L = (K, B) -> J
+
+/**
+ * Documented
+ */
+typealias M = A
+
+@Deprecated("!!!")
+typealias N = A \ No newline at end of file
diff --git a/core/testdata/format/typeAliases.md b/core/testdata/format/typeAliases.md
new file mode 100644
index 00000000..55e9317e
--- /dev/null
+++ b/core/testdata/format/typeAliases.md
@@ -0,0 +1,63 @@
+[test](test/index) / [A](test/-a/index)
+
+# A
+
+`class A`[test](test/index) / [B](test/-b/index)
+
+# B
+
+`class B`[test](test/index) / [C](test/-c/index)
+
+# C
+
+`class C<T>`[test](test/index) / [D](test/-d)
+
+# D
+
+`typealias D = `[`A`](test/-a/index)[test](test/index) / [E](test/-e)
+
+# E
+
+`typealias E = `[`D`](test/-d)[test](test/index) / [F](test/-f)
+
+# F
+
+`typealias F = (`[`A`](test/-a/index)`) -> `[`B`](test/-b/index)[test](test/index) / [G](test/-g)
+
+# G
+
+`typealias G = `[`C`](test/-c/index)`<`[`A`](test/-a/index)`>`[test](test/index) / [H](test/-h)
+
+# H
+
+`typealias H<T> = `[`C`](test/-c/index)`<T>`[test](test/index) / [I](test/-i)
+
+# I
+
+`typealias I<T> = `[`H`](test/-h)`<T>`[test](test/index) / [J](test/-j)
+
+# J
+
+`typealias J = `[`H`](test/-h)`<`[`A`](test/-a/index)`>`[test](test/index) / [K](test/-k)
+
+# K
+
+`typealias K = `[`H`](test/-h)`<`[`J`](test/-j)`>`[test](test/index) / [L](test/-l)
+
+# L
+
+`typealias L = (`[`K`](test/-k)`, `[`B`](test/-b/index)`) -> `[`J`](test/-j)[test](test/index) / [M](test/-m)
+
+# M
+
+`typealias M = `[`A`](test/-a/index)
+
+Documented
+
+[test](test/index) / [N](test/-n)
+
+# N
+
+`typealias ~~N~~ = `[`A`](test/-a/index)
+**Deprecated:** !!!
+
diff --git a/core/testdata/format/typeAliases.package.md b/core/testdata/format/typeAliases.package.md
new file mode 100644
index 00000000..0eff1ed5
--- /dev/null
+++ b/core/testdata/format/typeAliases.package.md
@@ -0,0 +1,24 @@
+[test](test/index)
+
+## Package &lt;root&gt;
+
+### Types
+
+| [A](test/-a/index) | `class A` |
+| [B](test/-b/index) | `class B` |
+| [C](test/-c/index) | `class C<T>` |
+
+### Type Aliases
+
+| [D](test/-d) | `typealias D = `[`A`](test/-a/index) |
+| [E](test/-e) | `typealias E = `[`D`](test/-d) |
+| [F](test/-f) | `typealias F = (`[`A`](test/-a/index)`) -> `[`B`](test/-b/index) |
+| [G](test/-g) | `typealias G = `[`C`](test/-c/index)`<`[`A`](test/-a/index)`>` |
+| [H](test/-h) | `typealias H<T> = `[`C`](test/-c/index)`<T>` |
+| [I](test/-i) | `typealias I<T> = `[`H`](test/-h)`<T>` |
+| [J](test/-j) | `typealias J = `[`H`](test/-h)`<`[`A`](test/-a/index)`>` |
+| [K](test/-k) | `typealias K = `[`H`](test/-h)`<`[`J`](test/-j)`>` |
+| [L](test/-l) | `typealias L = (`[`K`](test/-k)`, `[`B`](test/-b/index)`) -> `[`J`](test/-j) |
+| [M](test/-m) | `typealias M = `[`A`](test/-a/index)<br>Documented |
+| [N](test/-n) | `typealias ~~N~~ = `[`A`](test/-a/index) |
+
diff --git a/core/testdata/javadoc/typealiases.kt b/core/testdata/javadoc/typealiases.kt
new file mode 100644
index 00000000..bb09bfad
--- /dev/null
+++ b/core/testdata/javadoc/typealiases.kt
@@ -0,0 +1,11 @@
+class A
+
+typealias B = A
+
+class C : B
+
+typealias D = (A) -> C
+
+fun some(d: D) {
+
+} \ No newline at end of file
diff --git a/core/testdata/typealias/asTypeBoundWithVariance.kt b/core/testdata/typealias/asTypeBoundWithVariance.kt
new file mode 100644
index 00000000..1aef84d6
--- /dev/null
+++ b/core/testdata/typealias/asTypeBoundWithVariance.kt
@@ -0,0 +1,7 @@
+package _typealias.astypebound
+class A
+
+typealias B = A
+
+class C<out T : B>
+class D<in T : B> \ No newline at end of file
diff --git a/core/testdata/typealias/chain.kt b/core/testdata/typealias/chain.kt
new file mode 100644
index 00000000..520be553
--- /dev/null
+++ b/core/testdata/typealias/chain.kt
@@ -0,0 +1,8 @@
+package _typealias.chain
+
+class A
+
+typealias B = A
+
+typealias C = B
+
diff --git a/core/testdata/typealias/deprecated.kt b/core/testdata/typealias/deprecated.kt
new file mode 100644
index 00000000..b53d3a20
--- /dev/null
+++ b/core/testdata/typealias/deprecated.kt
@@ -0,0 +1,7 @@
+package _typealias.deprecated
+
+class Lol
+
+@Deprecated("Not mainstream now")
+typealias Kek = Lol
+
diff --git a/core/testdata/typealias/documented.kt b/core/testdata/typealias/documented.kt
new file mode 100644
index 00000000..3ca110e5
--- /dev/null
+++ b/core/testdata/typealias/documented.kt
@@ -0,0 +1,9 @@
+package _typealias.documented
+
+class A
+
+/**
+ * Just typealias
+ */
+typealias B = A
+
diff --git a/core/testdata/typealias/functional.kt b/core/testdata/typealias/functional.kt
new file mode 100644
index 00000000..dadafa5e
--- /dev/null
+++ b/core/testdata/typealias/functional.kt
@@ -0,0 +1,10 @@
+package _typealias.functional
+
+class A
+class B
+
+typealias Spell = (A) -> B
+
+fun magic(spell: Spell) {
+
+} \ No newline at end of file
diff --git a/core/testdata/typealias/generic.kt b/core/testdata/typealias/generic.kt
new file mode 100644
index 00000000..43bc0e23
--- /dev/null
+++ b/core/testdata/typealias/generic.kt
@@ -0,0 +1,7 @@
+package _typealias.generic
+
+interface A<T>
+
+typealias B = A<Any>
+
+typealias C<T> = A<T> \ No newline at end of file
diff --git a/core/testdata/typealias/inheritanceFromTypeAlias.kt b/core/testdata/typealias/inheritanceFromTypeAlias.kt
new file mode 100644
index 00000000..f929ecd0
--- /dev/null
+++ b/core/testdata/typealias/inheritanceFromTypeAlias.kt
@@ -0,0 +1,7 @@
+package _typealias.inheritance
+
+open class Some
+
+typealias Same = Some
+
+class My : Same \ No newline at end of file
diff --git a/core/testdata/typealias/simple.kt b/core/testdata/typealias/simple.kt
new file mode 100644
index 00000000..d688a84d
--- /dev/null
+++ b/core/testdata/typealias/simple.kt
@@ -0,0 +1,5 @@
+package _typealias.simple
+
+class A
+
+typealias B = A \ No newline at end of file