diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Analysis/AnalysisEnvironment.kt | 20 | ||||
-rw-r--r-- | src/Analysis/CoreProjectFileIndex.kt | 489 | ||||
-rw-r--r-- | src/Java/JavaPsiDocumentationBuilder.kt (renamed from src/Java/JavaDocumentationBuilder.kt) | 12 | ||||
-rw-r--r-- | src/Kotlin/DocumentationBuilder.kt | 74 | ||||
-rw-r--r-- | src/Kotlin/KotlinAsJavaDocumentationBuilder.kt | 2 | ||||
-rw-r--r-- | src/main.kt | 14 |
6 files changed, 571 insertions, 40 deletions
diff --git a/src/Analysis/AnalysisEnvironment.kt b/src/Analysis/AnalysisEnvironment.kt index 561ac2f0..af9859d6 100644 --- a/src/Analysis/AnalysisEnvironment.kt +++ b/src/Analysis/AnalysisEnvironment.kt @@ -4,9 +4,13 @@ import com.intellij.core.CoreApplicationEnvironment import com.intellij.core.CoreModuleManager import com.intellij.mock.MockComponentManager import com.intellij.openapi.Disposable +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.OrderEnumerationHandler import com.intellij.openapi.roots.ProjectFileIndex +import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.util.Disposer import com.intellij.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope @@ -70,12 +74,24 @@ public class AnalysisEnvironment(val messageCollector: MessageCollector, body: A val environment = KotlinCoreEnvironment.createForProduction(this, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) val projectComponentManager = environment.project as MockComponentManager - val moduleManager = CoreModuleManager(environment.project, this) + val projectFileIndex = CoreProjectFileIndex(environment.project, + environment.configuration.getList(CommonConfigurationKeys.CONTENT_ROOTS)) + + val moduleManager = object : CoreModuleManager(environment.project, this) { + override fun getModules(): Array<out Module> = arrayOf(projectFileIndex.module) + } + CoreApplicationEnvironment.registerComponentInstance(projectComponentManager.picoContainer, ModuleManager::class.java, moduleManager) + Extensions.registerAreaClass("IDEA_MODULE", null) + CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), + OrderEnumerationHandler.EP_NAME, OrderEnumerationHandler.Factory::class.java) + projectComponentManager.registerService(ProjectFileIndex::class.java, - CoreProjectFileIndex()) + projectFileIndex) + projectComponentManager.registerService(ProjectRootManager::class.java, + CoreProjectRootManager(projectFileIndex)) projectComponentManager.registerService(LibraryModificationTracker::class.java, LibraryModificationTracker(environment.project)) projectComponentManager.registerService(KotlinCacheService::class.java, diff --git a/src/Analysis/CoreProjectFileIndex.kt b/src/Analysis/CoreProjectFileIndex.kt index 916eab73..a1362fde 100644 --- a/src/Analysis/CoreProjectFileIndex.kt +++ b/src/Analysis/CoreProjectFileIndex.kt @@ -1,17 +1,409 @@ package org.jetbrains.dokka +import com.intellij.openapi.Disposable +import com.intellij.openapi.components.BaseComponent +import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.module.Module -import com.intellij.openapi.roots.ContentIterator -import com.intellij.openapi.roots.OrderEntry -import com.intellij.openapi.roots.ProjectFileIndex +import com.intellij.openapi.project.Project +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.projectRoots.SdkAdditionalData +import com.intellij.openapi.projectRoots.SdkModificator +import com.intellij.openapi.projectRoots.SdkTypeId +import com.intellij.openapi.roots.* +import com.intellij.openapi.roots.impl.ProjectOrderEnumerator +import com.intellij.openapi.util.Condition +import com.intellij.openapi.util.Key +import com.intellij.openapi.util.UserDataHolderBase +import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.util.messages.MessageBus import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot +import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot +import org.jetbrains.kotlin.config.ContentRoot +import org.jetbrains.kotlin.config.KotlinSourceRoot +import org.picocontainer.PicoContainer +import java.io.File /** * Workaround for the lack of ability to create a ProjectFileIndex implementation using only * classes from projectModel-{api,impl}. */ -class CoreProjectFileIndex(): ProjectFileIndex { +class CoreProjectFileIndex(val project: Project, contentRoots: List<ContentRoot>) : ProjectFileIndex, ModuleFileIndex { + val sourceRoots = contentRoots.filter { it !is JvmClasspathRoot } + val classpathRoots = contentRoots.filterIsInstance<JvmClasspathRoot>() + + val module: Module = object : UserDataHolderBase(), Module { + override fun isDisposed(): Boolean { + throw UnsupportedOperationException() + } + + override fun getOptionValue(p0: String): String? { + throw UnsupportedOperationException() + } + + override fun clearOption(p0: String) { + throw UnsupportedOperationException() + } + + override fun getName(): String = "<Dokka module>" + + override fun getModuleWithLibrariesScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleWithDependentsScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleContentScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun isLoaded(): Boolean { + throw UnsupportedOperationException() + } + + override fun setOption(p0: String, p1: String) { + throw UnsupportedOperationException() + } + + override fun getModuleWithDependenciesScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleWithDependenciesAndLibrariesScope(p0: Boolean): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getProject(): Project = project + + override fun getModuleContentWithDependenciesScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleFilePath(): String { + throw UnsupportedOperationException() + } + + override fun getModuleTestsWithDependentsScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleScope(p0: Boolean): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleRuntimeScope(p0: Boolean): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleFile(): VirtualFile? { + throw UnsupportedOperationException() + } + + override fun <T : Any?> getExtensions(p0: ExtensionPointName<T>): Array<out T> { + throw UnsupportedOperationException() + } + + override fun getComponent(p0: String): BaseComponent? { + throw UnsupportedOperationException() + } + + override fun <T : Any?> getComponent(p0: Class<T>, p1: T): T { + throw UnsupportedOperationException() + } + + override fun <T : Any?> getComponent(interfaceClass: Class<T>): T? { + if (interfaceClass == ModuleRootManager::class.java) { + return moduleRootManager as T + } + throw UnsupportedOperationException() + } + + override fun getDisposed(): Condition<*> { + throw UnsupportedOperationException() + } + + override fun <T : Any?> getComponents(p0: Class<T>): Array<out T> { + throw UnsupportedOperationException() + } + + override fun getPicoContainer(): PicoContainer { + throw UnsupportedOperationException() + } + + override fun hasComponent(p0: Class<*>): Boolean { + throw UnsupportedOperationException() + } + + override fun getMessageBus(): MessageBus { + throw UnsupportedOperationException() + } + + override fun dispose() { + throw UnsupportedOperationException() + } + } + + private val sdk: Sdk = object : Sdk, RootProvider { + override fun getFiles(rootType: OrderRootType): Array<out VirtualFile> = classpathRoots + .map { StandardFileSystems.local().findFileByPath(it.file.path) } + .filterNotNull() + .toTypedArray() + + override fun addRootSetChangedListener(p0: RootProvider.RootSetChangedListener) { + throw UnsupportedOperationException() + } + + override fun addRootSetChangedListener(p0: RootProvider.RootSetChangedListener, p1: Disposable) { + throw UnsupportedOperationException() + } + + override fun getUrls(p0: OrderRootType): Array<out String> { + throw UnsupportedOperationException() + } + + override fun removeRootSetChangedListener(p0: RootProvider.RootSetChangedListener) { + throw UnsupportedOperationException() + } + + override fun getSdkModificator(): SdkModificator { + throw UnsupportedOperationException() + } + + override fun getName(): String = "<dokka SDK>" + + override fun getRootProvider(): RootProvider = this + + override fun getHomePath(): String? { + throw UnsupportedOperationException() + } + + override fun getVersionString(): String? { + throw UnsupportedOperationException() + } + + override fun getSdkAdditionalData(): SdkAdditionalData? { + throw UnsupportedOperationException() + } + + override fun clone(): Any { + throw UnsupportedOperationException() + } + + override fun getSdkType(): SdkTypeId { + throw UnsupportedOperationException() + } + + override fun getHomeDirectory(): VirtualFile? { + throw UnsupportedOperationException() + } + + override fun <T : Any?> getUserData(p0: Key<T>): T? { + throw UnsupportedOperationException() + } + + override fun <T : Any?> putUserData(p0: Key<T>, p1: T?) { + throw UnsupportedOperationException() + } + } + + private val moduleSourceOrderEntry = object : ModuleSourceOrderEntry { + override fun getFiles(p0: OrderRootType?): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getPresentableName(): String { + throw UnsupportedOperationException() + } + + override fun getUrls(p0: OrderRootType?): Array<out String> { + throw UnsupportedOperationException() + } + + override fun getOwnerModule(): Module = module + + override fun <R : Any?> accept(p0: RootPolicy<R>?, p1: R?): R { + throw UnsupportedOperationException() + } + + override fun isValid(): Boolean { + throw UnsupportedOperationException() + } + + override fun compareTo(other: OrderEntry?): Int { + throw UnsupportedOperationException() + } + + override fun getRootModel(): ModuleRootModel = moduleRootManager + + override fun isSynthetic(): Boolean { + throw UnsupportedOperationException() + } + } + + private val sdkOrderEntry = object : JdkOrderEntry { + override fun getJdkName(): String? { + throw UnsupportedOperationException() + } + + override fun getJdk(): Sdk = sdk + + override fun getFiles(p0: OrderRootType?): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getPresentableName(): String { + throw UnsupportedOperationException() + } + + override fun getUrls(p0: OrderRootType?): Array<out String> { + throw UnsupportedOperationException() + } + + override fun getOwnerModule(): Module { + throw UnsupportedOperationException() + } + + override fun <R : Any?> accept(p0: RootPolicy<R>?, p1: R?): R { + throw UnsupportedOperationException() + } + + override fun isValid(): Boolean { + throw UnsupportedOperationException() + } + + override fun getRootFiles(p0: OrderRootType?): Array<out VirtualFile>? { + throw UnsupportedOperationException() + } + + override fun getRootUrls(p0: OrderRootType?): Array<out String>? { + throw UnsupportedOperationException() + } + + override fun compareTo(other: OrderEntry?): Int { + throw UnsupportedOperationException() + } + + override fun isSynthetic(): Boolean { + throw UnsupportedOperationException() + } + + } + + inner class MyModuleRootManager : ModuleRootManager() { + override fun getExcludeRoots(): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getContentEntries(): Array<out ContentEntry> { + throw UnsupportedOperationException() + } + + override fun getExcludeRootUrls(): Array<out String> { + throw UnsupportedOperationException() + } + + override fun <R : Any?> processOrder(p0: RootPolicy<R>?, p1: R): R { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(p0: Boolean): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(p0: JpsModuleSourceRootType<*>): MutableList<VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(p0: MutableSet<out JpsModuleSourceRootType<*>>): MutableList<VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getContentRoots(): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun orderEntries(): OrderEnumerator = + ProjectOrderEnumerator(project, null).using(object : RootModelProvider { + override fun getModules(): Array<out Module> = arrayOf(module) + + override fun getRootModel(p0: Module): ModuleRootModel = this@MyModuleRootManager + }) + + override fun <T : Any?> getModuleExtension(p0: Class<T>?): T { + throw UnsupportedOperationException() + } + + override fun getDependencyModuleNames(): Array<out String> { + throw UnsupportedOperationException() + } + + override fun getModule(): Module = module + + override fun isSdkInherited(): Boolean { + throw UnsupportedOperationException() + } + + override fun getOrderEntries(): Array<out OrderEntry> = arrayOf(moduleSourceOrderEntry, sdkOrderEntry) + + override fun getSourceRootUrls(): Array<out String> { + throw UnsupportedOperationException() + } + + override fun getSourceRootUrls(p0: Boolean): Array<out String> { + throw UnsupportedOperationException() + } + + override fun getSdk(): Sdk? { + throw UnsupportedOperationException() + } + + override fun getContentRootUrls(): Array<out String> { + throw UnsupportedOperationException() + } + + override fun getModuleDependencies(): Array<out Module> { + throw UnsupportedOperationException() + } + + override fun getModuleDependencies(p0: Boolean): Array<out Module> { + throw UnsupportedOperationException() + } + + override fun getModifiableModel(): ModifiableRootModel { + throw UnsupportedOperationException() + } + + override fun isDependsOn(p0: Module?): Boolean { + throw UnsupportedOperationException() + } + + override fun getFileIndex(): ModuleFileIndex { + return this@CoreProjectFileIndex + } + + override fun getDependencies(): Array<out Module> { + throw UnsupportedOperationException() + } + + override fun getDependencies(p0: Boolean): Array<out Module> { + throw UnsupportedOperationException() + } + } + + val moduleRootManager = MyModuleRootManager() + override fun getContentRootForFile(p0: VirtualFile): VirtualFile? { throw UnsupportedOperationException() } @@ -24,19 +416,15 @@ class CoreProjectFileIndex(): ProjectFileIndex { throw UnsupportedOperationException() } - override fun isInLibrarySource(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } + override fun isInLibrarySource(file: VirtualFile): Boolean = false - override fun getClassRootForFile(p0: VirtualFile): VirtualFile? { - throw UnsupportedOperationException() - } + override fun getClassRootForFile(file: VirtualFile): VirtualFile? = + classpathRoots.firstOrNull { it.contains(file) }?.let { StandardFileSystems.local().findFileByPath(it.file.path) } - override fun getOrderEntriesForFile(p0: VirtualFile): List<OrderEntry> = emptyList() + override fun getOrderEntriesForFile(file: VirtualFile): List<OrderEntry> = + if (classpathRoots.contains(file)) listOf(sdkOrderEntry) else emptyList() - override fun isInLibraryClasses(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } + override fun isInLibraryClasses(file: VirtualFile): Boolean = classpathRoots.contains(file) override fun isExcluded(p0: VirtualFile): Boolean { throw UnsupportedOperationException() @@ -54,7 +442,10 @@ class CoreProjectFileIndex(): ProjectFileIndex { throw UnsupportedOperationException() } - override fun getModuleForFile(p0: VirtualFile): Module? = null + override fun getModuleForFile(file: VirtualFile): Module? = + if (sourceRoots.contains(file)) module else null + + private fun List<ContentRoot>.contains(file: VirtualFile): Boolean = any { it.contains(file) } override fun getModuleForFile(p0: VirtualFile, p1: Boolean): Module? { throw UnsupportedOperationException() @@ -72,7 +463,7 @@ class CoreProjectFileIndex(): ProjectFileIndex { throw UnsupportedOperationException() } - override fun isInSourceContent(p0: VirtualFile): Boolean = false + override fun isInSourceContent(file: VirtualFile): Boolean = sourceRoots.contains(file) override fun iterateContent(p0: ContentIterator): Boolean { throw UnsupportedOperationException() @@ -86,12 +477,74 @@ class CoreProjectFileIndex(): ProjectFileIndex { throw UnsupportedOperationException() } - override fun isInTestSourceContent(p0: VirtualFile): Boolean { + override fun isInTestSourceContent(file: VirtualFile): Boolean = false + + override fun isUnderSourceRootOfType(p0: VirtualFile, p1: MutableSet<out JpsModuleSourceRootType<*>>): Boolean { throw UnsupportedOperationException() } - override fun isUnderSourceRootOfType(p0: VirtualFile, p1: MutableSet<out JpsModuleSourceRootType<*>>): Boolean { + override fun getOrderEntryForFile(p0: VirtualFile): OrderEntry? { + throw UnsupportedOperationException() + } +} + +class CoreProjectRootManager(val projectFileIndex: CoreProjectFileIndex) : ProjectRootManager() { + override fun orderEntries(): OrderEnumerator { + throw UnsupportedOperationException() + } + + override fun orderEntries(p0: MutableCollection<out Module>): OrderEnumerator { throw UnsupportedOperationException() } + + override fun getContentRootsFromAllModules(): Array<out VirtualFile>? { + throw UnsupportedOperationException() + } + + override fun setProjectSdk(p0: Sdk?) { + throw UnsupportedOperationException() + } + + override fun setProjectSdkName(p0: String?) { + throw UnsupportedOperationException() + } + + override fun getModuleSourceRoots(p0: MutableSet<out JpsModuleSourceRootType<*>>): MutableList<VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getContentSourceRoots(): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getFileIndex(): ProjectFileIndex = projectFileIndex + + override fun getProjectSdkName(): String? { + throw UnsupportedOperationException() + } + + override fun getProjectSdk(): Sdk? { + throw UnsupportedOperationException() + } + + override fun getContentRoots(): Array<out VirtualFile> { + throw UnsupportedOperationException() + } + + override fun getContentRootUrls(): MutableList<String> { + throw UnsupportedOperationException() + } + } +fun ContentRoot.contains(file: VirtualFile) = when (this) { + is JvmContentRoot -> { + val path = if (file.fileSystem.protocol == StandardFileSystems.JAR_PROTOCOL) + StandardFileSystems.getVirtualFileForJar(file)?.path ?: file.path + else + file.path + File(path).startsWith(this.file.absoluteFile) + } + is KotlinSourceRoot -> File(file.path).startsWith(File(this.path).absoluteFile) + else -> false +} diff --git a/src/Java/JavaDocumentationBuilder.kt b/src/Java/JavaPsiDocumentationBuilder.kt index e0cc53a0..a5ee891e 100644 --- a/src/Java/JavaDocumentationBuilder.kt +++ b/src/Java/JavaPsiDocumentationBuilder.kt @@ -197,10 +197,14 @@ private fun mapTypeName(psiType: PsiType): String = when (psiType) { else -> psiType.canonicalText } -class JavaDocumentationBuilder(private val options: DocumentationOptions, - private val refGraph: NodeReferenceGraph, - private val docParser: JavaDocumentationParser = JavadocParser(refGraph)) { - fun appendFile(file: PsiJavaFile, module: DocumentationModule) { +interface JavaDocumentationBuilder { + fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) +} + +class JavaPsiDocumentationBuilder(private val options: DocumentationOptions, + private val refGraph: NodeReferenceGraph, + private val docParser: JavaDocumentationParser = JavadocParser(refGraph)) : JavaDocumentationBuilder { + override fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) { if (file.classes.all { skipElement(it) }) { return } diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt index b5b079de..7dc4075b 100644 --- a/src/Kotlin/DocumentationBuilder.kt +++ b/src/Kotlin/DocumentationBuilder.kt @@ -1,7 +1,9 @@ package org.jetbrains.dokka -import com.intellij.openapi.project.Project import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiDocCommentOwner +import com.intellij.psi.PsiJavaFile +import com.intellij.psi.PsiNamedElement import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.dokka.DocumentationNode.Kind import org.jetbrains.kotlin.builtins.KotlinBuiltIns @@ -9,6 +11,8 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfo import org.jetbrains.kotlin.idea.kdoc.KDocFinder import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink import org.jetbrains.kotlin.idea.resolve.ResolutionFacade @@ -16,6 +20,9 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor +import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor +import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtParameter @@ -25,6 +32,8 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.isDocumentedAnnotation +import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.getPsi @@ -55,7 +64,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, val session: ResolveSession, val options: DocumentationOptions, val refGraph: NodeReferenceGraph, - val logger: DokkaLogger) { + val logger: DokkaLogger) : JavaDocumentationBuilder { val visibleToDocumentation = setOf(Visibilities.PROTECTED, Visibilities.PUBLIC) val boringBuiltinClasses = setOf( "kotlin.Unit", "kotlin.Byte", "kotlin.Short", "kotlin.Int", "kotlin.Long", "kotlin.Char", "kotlin.Boolean", @@ -65,7 +74,14 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, KtTokens.OPEN_KEYWORD, KtTokens.FINAL_KEYWORD, KtTokens.ABSTRACT_KEYWORD, KtTokens.SEALED_KEYWORD, KtTokens.OVERRIDE_KEYWORD) - fun parseDocumentation(descriptor: DeclarationDescriptor): Content { + + fun parseDocumentation(descriptor: DeclarationDescriptor): Content = parseDocumentationAndDetails(descriptor).first + + fun parseDocumentationAndDetails(descriptor: DeclarationDescriptor): Pair<Content, (DocumentationNode) -> Unit> { + if (descriptor is JavaClassDescriptor || descriptor is JavaCallableMemberDescriptor) { + return parseJavadoc(descriptor) + } + val kdoc = KDocFinder.findKDoc(descriptor) ?: findStdlibKDoc(descriptor) if (kdoc == null) { if (options.reportUndocumented && !descriptor.isDeprecated() && @@ -73,7 +89,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, descriptor !is PropertyAccessorDescriptor) { logger.warn("No documentation for ${descriptor.signatureWithSourceLocation()}") } - return Content.Empty + return Content.Empty to { node -> } } var kdocText = kdoc.getContent() // workaround for code fence parsing problem in IJ markdown parser @@ -100,7 +116,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } } } - return content + return content to { node -> } } /** @@ -132,6 +148,20 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, return null } + fun parseJavadoc(descriptor: DeclarationDescriptor): Pair<Content, (DocumentationNode) -> Unit> { + val psi = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi + if (psi is PsiDocCommentOwner) { + val parseResult = JavadocParser(refGraph).parseDocumentation(psi as PsiNamedElement) + return parseResult.content to { node -> + parseResult.deprecatedContent?.let { + val deprecationNode = DocumentationNode("", it, DocumentationNode.Kind.Modifier) + node.append(deprecationNode, DocumentationReference.Kind.Deprecation) + } + } + } + return Content.Empty to { node -> } + } + fun DeclarationDescriptor.signature(): String = when(this) { is ClassDescriptor, is PackageFragmentDescriptor -> DescriptorUtils.getFqName(this).asString() is PropertyDescriptor -> containingDeclaration.signature() + "#" + name + receiverSignature() @@ -246,8 +276,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } fun <T> DocumentationNode(descriptor: T, kind: Kind): DocumentationNode where T : DeclarationDescriptor, T : Named { - val doc = parseDocumentation(descriptor) + val (doc, callback) = parseDocumentationAndDetails(descriptor) val node = DocumentationNode(descriptor.name.asString(), doc, kind).withModifiers(descriptor) + callback(node) return node } @@ -274,7 +305,7 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } fun DocumentationNode.appendVisibility(descriptor: DeclarationDescriptorWithVisibility) { - val modifier = descriptor.visibility.toString() + val modifier = descriptor.visibility.normalize().displayName appendTextNode(modifier, DocumentationNode.Kind.Modifier) } @@ -393,18 +424,20 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, (!options.skipDeprecated || !isDeprecated()) } - fun DocumentationNode.appendMembers(descriptors: Iterable<DeclarationDescriptor>) { - descriptors.forEach { descriptor -> + fun DocumentationNode.appendMembers(descriptors: Iterable<DeclarationDescriptor>): List<DocumentationNode> { + val nodes = descriptors.map { descriptor -> if (descriptor is CallableMemberDescriptor && descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { val baseDescriptor = descriptor.overriddenDescriptors.firstOrNull() if (baseDescriptor != null) { link(this, baseDescriptor, DocumentationReference.Kind.InheritedMember) } + null } else { appendChild(descriptor, DocumentationReference.Kind.Member) } } + return nodes.filterNotNull() } fun DocumentationNode.appendInPageChildren(descriptors: Iterable<DeclarationDescriptor>, kind: DocumentationReference.Kind) { @@ -464,6 +497,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } val members = defaultType.memberScope.getAllDescriptors().filter { it != companionObjectDescriptor } node.appendMembers(members) + node.appendMembers(staticScope.getDescriptors()).forEach { + it.appendTextNode("static", Kind.Modifier) + } val companionObjectDescriptor = companionObjectDescriptor if (companionObjectDescriptor != null) { node.appendMembers(companionObjectDescriptor.defaultType.memberScope.getAllDescriptors()) @@ -583,6 +619,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } node.appendAnnotations(this) node.appendModifiers(this) + if (varargElementType != null && node.details(Kind.Modifier).none { it.name == "vararg" }) { + node.appendTextNode("vararg", Kind.Modifier) + } register(this, node) return node } @@ -678,6 +717,23 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } } } + + override fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) { + val packageNode = module.findOrCreatePackageNode(file.packageName, packageContent) + + file.classes.forEach { + val javaDescriptorResolver = KotlinCacheService.getInstance(file.project).getProjectService(JvmPlatform, + it.getModuleInfo(), javaClass<JavaDescriptorResolver>()) + + val descriptor = javaDescriptorResolver.resolveClass(JavaClassImpl(it)) + if (descriptor == null) { + logger.warn("Cannot find descriptor for Java class ${it.qualifiedName}") + } + else { + packageNode.appendChild(descriptor, DocumentationReference.Kind.Member) + } + } + } } private fun AnnotationDescriptor.isDocumented(): Boolean { diff --git a/src/Kotlin/KotlinAsJavaDocumentationBuilder.kt b/src/Kotlin/KotlinAsJavaDocumentationBuilder.kt index a32e9a1f..1bd930e2 100644 --- a/src/Kotlin/KotlinAsJavaDocumentationBuilder.kt +++ b/src/Kotlin/KotlinAsJavaDocumentationBuilder.kt @@ -20,7 +20,7 @@ class KotlinAsJavaDocumentationBuilder() : PackageDocumentationBuilder { return } - val javaDocumentationBuilder = JavaDocumentationBuilder(documentationBuilder.options, + val javaDocumentationBuilder = JavaPsiDocumentationBuilder(documentationBuilder.options, documentationBuilder.refGraph, KotlinAsJavaDocumentationParser(documentationBuilder)) diff --git a/src/main.kt b/src/main.kt index d0e693e9..46b9a2dc 100644 --- a/src/main.kt +++ b/src/main.kt @@ -162,7 +162,7 @@ class DokkaGenerator(val logger: DokkaLogger, val packageDocumentationBuilder = injector.getInstance(PackageDocumentationBuilder::class.java) val documentation = buildDocumentationModule(environment, moduleName, options, includes, { isSample(it) }, - packageDocumentationBuilder, logger) + packageDocumentationBuilder, null, logger) val timeAnalyse = System.currentTimeMillis() - startAnalyse logger.info("done in ${timeAnalyse / 1000} secs") @@ -206,9 +206,10 @@ fun buildDocumentationModule(environment: AnalysisEnvironment, includes: List<String> = listOf(), filesToDocumentFilter: (PsiFile) -> Boolean = { file -> true }, packageDocumentationBuilder: PackageDocumentationBuilder? = null, + javaDocumentationBuilder: JavaDocumentationBuilder? = null, logger: DokkaLogger): DocumentationModule { - val documentation = environment.withContext { environment, resolutionFacade, session -> - val fragmentFiles = environment.getSourceFiles().filter(filesToDocumentFilter) + val documentation = environment.withContext { coreEnvironment, resolutionFacade, session -> + val fragmentFiles = coreEnvironment.getSourceFiles().filter(filesToDocumentFilter) val analyzer = resolutionFacade.getFrontendService(LazyTopDownAnalyzerForTopLevel::class.java) analyzer.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, fragmentFiles) @@ -231,9 +232,10 @@ fun buildDocumentationModule(environment: AnalysisEnvironment, } } - val javaFiles = environment.getJavaSourceFiles().filter(filesToDocumentFilter) - val javaDocumentationBuilder = JavaDocumentationBuilder(options, refGraph) - javaFiles.map { javaDocumentationBuilder.appendFile(it, documentationModule) } + val javaFiles = coreEnvironment.getJavaSourceFiles().filter(filesToDocumentFilter) + with(javaDocumentationBuilder ?: documentationBuilder) { + javaFiles.map { appendFile(it, documentationModule, packageDocs.packageContent) } + } refGraph.resolveReferences() |