diff options
| author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-07-05 10:04:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-05 10:04:55 +0200 |
| commit | 9559158bfeeb274e9ccf1b4563f1b23b42afc493 (patch) | |
| tree | 3ece0887623cfe2b7148af23001867a1dd5e6597 /subprojects/analysis-java-psi | |
| parent | cbd9733d3dd2f52992e98e7cebd072091a572529 (diff) | |
| download | dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.tar.gz dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.tar.bz2 dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.zip | |
Decompose Kotlin/Java analysis (#3034)
* Extract analysis into separate modules
Diffstat (limited to 'subprojects/analysis-java-psi')
35 files changed, 2764 insertions, 0 deletions
diff --git a/subprojects/analysis-java-psi/README.md b/subprojects/analysis-java-psi/README.md new file mode 100644 index 00000000..d2bbd080 --- /dev/null +++ b/subprojects/analysis-java-psi/README.md @@ -0,0 +1,5 @@ +# Analysis: Java PSI + +An internal module for parsing Java sources. Defines no stable public API and is not published anywhere. + +Used by the Kotlin analysis artifacts to provide support for mixed-language (Kotlin+Java) projects. diff --git a/subprojects/analysis-java-psi/api/analysis-java-psi.api b/subprojects/analysis-java-psi/api/analysis-java-psi.api new file mode 100644 index 00000000..404249f8 --- /dev/null +++ b/subprojects/analysis-java-psi/api/analysis-java-psi.api @@ -0,0 +1,148 @@ +public final class org/jetbrains/dokka/analysis/java/AuthorJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field INSTANCE Lorg/jetbrains/dokka/analysis/java/AuthorJavadocTag; +} + +public abstract interface class org/jetbrains/dokka/analysis/java/BreakingAbstractionKotlinLightMethodChecker { + public abstract fun isLightAnnotation (Lcom/intellij/psi/PsiAnnotation;)Z + public abstract fun isLightAnnotationAttribute (Lcom/intellij/lang/jvm/annotation/JvmAnnotationAttribute;)Z +} + +public final class org/jetbrains/dokka/analysis/java/DeprecatedJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field INSTANCE Lorg/jetbrains/dokka/analysis/java/DeprecatedJavadocTag; +} + +public final class org/jetbrains/dokka/analysis/java/DescriptionJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field INSTANCE Lorg/jetbrains/dokka/analysis/java/DescriptionJavadocTag; +} + +public final class org/jetbrains/dokka/analysis/java/ExceptionJavadocTag : org/jetbrains/dokka/analysis/java/ThrowingExceptionJavadocTag { + public static final field Companion Lorg/jetbrains/dokka/analysis/java/ExceptionJavadocTag$Companion; + public static final field name Ljava/lang/String; + public fun <init> (Ljava/lang/String;)V +} + +public final class org/jetbrains/dokka/analysis/java/ExceptionJavadocTag$Companion { +} + +public final class org/jetbrains/dokka/analysis/java/JavaAnalysisPlugin : org/jetbrains/dokka/plugability/DokkaPlugin { + public fun <init> ()V + public final fun getDocCommentCreators ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; + public final fun getDocCommentFinder ()Lorg/jetbrains/dokka/analysis/java/doccomment/DocCommentFinder; + public final fun getDocCommentParsers ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; + public final fun getInheritDocTagContentProviders ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; + public final fun getKotlinLightMethodChecker ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; + public final fun getProjectProvider ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; + public final fun getSourceRootsExtractor ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; +} + +public abstract class org/jetbrains/dokka/analysis/java/JavadocTag { + public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getName ()Ljava/lang/String; +} + +public final class org/jetbrains/dokka/analysis/java/ParamJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field Companion Lorg/jetbrains/dokka/analysis/java/ParamJavadocTag$Companion; + public static final field name Ljava/lang/String; + public fun <init> (Lcom/intellij/psi/PsiMethod;Ljava/lang/String;I)V + public final fun getMethod ()Lcom/intellij/psi/PsiMethod; + public final fun getParamIndex ()I + public final fun getParamName ()Ljava/lang/String; +} + +public final class org/jetbrains/dokka/analysis/java/ParamJavadocTag$Companion { +} + +public abstract interface class org/jetbrains/dokka/analysis/java/ProjectProvider { + public abstract fun getProject (Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/plugability/DokkaContext;)Lcom/intellij/openapi/project/Project; +} + +public final class org/jetbrains/dokka/analysis/java/ReturnJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field INSTANCE Lorg/jetbrains/dokka/analysis/java/ReturnJavadocTag; +} + +public final class org/jetbrains/dokka/analysis/java/SeeJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field Companion Lorg/jetbrains/dokka/analysis/java/SeeJavadocTag$Companion; + public static final field name Ljava/lang/String; + public fun <init> (Ljava/lang/String;)V + public final fun getQualifiedReference ()Ljava/lang/String; +} + +public final class org/jetbrains/dokka/analysis/java/SeeJavadocTag$Companion { +} + +public final class org/jetbrains/dokka/analysis/java/SinceJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public static final field INSTANCE Lorg/jetbrains/dokka/analysis/java/SinceJavadocTag; +} + +public abstract interface class org/jetbrains/dokka/analysis/java/SourceRootsExtractor { + public abstract fun extract (Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/plugability/DokkaContext;)Ljava/util/List; +} + +public abstract class org/jetbrains/dokka/analysis/java/ThrowingExceptionJavadocTag : org/jetbrains/dokka/analysis/java/JavadocTag { + public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getExceptionQualifiedName ()Ljava/lang/String; +} + +public final class org/jetbrains/dokka/analysis/java/ThrowsJavadocTag : org/jetbrains/dokka/analysis/java/ThrowingExceptionJavadocTag { + public static final field Companion Lorg/jetbrains/dokka/analysis/java/ThrowsJavadocTag$Companion; + public static final field name Ljava/lang/String; + public fun <init> (Ljava/lang/String;)V +} + +public final class org/jetbrains/dokka/analysis/java/ThrowsJavadocTag$Companion { +} + +public abstract interface class org/jetbrains/dokka/analysis/java/doccomment/DocComment { + public abstract fun hasTag (Lorg/jetbrains/dokka/analysis/java/JavadocTag;)Z + public abstract fun resolveTag (Lorg/jetbrains/dokka/analysis/java/JavadocTag;)Ljava/util/List; +} + +public abstract interface class org/jetbrains/dokka/analysis/java/doccomment/DocCommentCreator { + public abstract fun create (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/analysis/java/doccomment/DocComment; +} + +public final class org/jetbrains/dokka/analysis/java/doccomment/DocCommentFactory { + public fun <init> (Ljava/util/List;)V + public final fun fromElement (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/analysis/java/doccomment/DocComment; +} + +public final class org/jetbrains/dokka/analysis/java/doccomment/DocCommentFinder { + public fun <init> (Lorg/jetbrains/dokka/utilities/DokkaLogger;Lorg/jetbrains/dokka/analysis/java/doccomment/DocCommentFactory;)V + public final fun findClosestToElement (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/analysis/java/doccomment/DocComment; +} + +public abstract interface class org/jetbrains/dokka/analysis/java/doccomment/DocumentationContent { + public abstract fun getTag ()Lorg/jetbrains/dokka/analysis/java/JavadocTag; + public abstract fun resolveSiblings ()Ljava/util/List; +} + +public abstract interface class org/jetbrains/dokka/analysis/java/parsers/DocCommentParser { + public abstract fun canParse (Lorg/jetbrains/dokka/analysis/java/doccomment/DocComment;)Z + public abstract fun parse (Lorg/jetbrains/dokka/analysis/java/doccomment/DocComment;Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/model/doc/DocumentationNode; +} + +public final class org/jetbrains/dokka/analysis/java/parsers/JavadocParser : org/jetbrains/dokka/analysis/java/parsers/JavaDocumentationParser { + public fun <init> (Ljava/util/List;Lorg/jetbrains/dokka/analysis/java/doccomment/DocCommentFinder;)V + public fun parseDocumentation (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/model/doc/DocumentationNode; +} + +public final class org/jetbrains/dokka/analysis/java/parsers/doctag/DocTagParserContext { + public fun <init> ()V + public final fun getDocumentationNode (Ljava/lang/String;)Lorg/jetbrains/dokka/model/doc/DocumentationNode; + public final fun getDri (Ljava/lang/String;)Lorg/jetbrains/dokka/links/DRI; + public final fun store (Lorg/jetbrains/dokka/links/DRI;)Ljava/lang/String; + public final fun store (Lorg/jetbrains/dokka/model/doc/DocumentationNode;)Ljava/lang/String; +} + +public abstract interface class org/jetbrains/dokka/analysis/java/parsers/doctag/InheritDocTagContentProvider { + public abstract fun canConvert (Lorg/jetbrains/dokka/analysis/java/doccomment/DocumentationContent;)Z + public abstract fun convertToHtml (Lorg/jetbrains/dokka/analysis/java/doccomment/DocumentationContent;Lorg/jetbrains/dokka/analysis/java/parsers/doctag/DocTagParserContext;)Ljava/lang/String; +} + +public final class org/jetbrains/dokka/analysis/java/util/PsiDocumentableSource : org/jetbrains/dokka/model/DocumentableSource { + public fun <init> (Lcom/intellij/psi/PsiNamedElement;)V + public fun computeLineNumber ()Ljava/lang/Integer; + public fun getPath ()Ljava/lang/String; + public final fun getPsi ()Lcom/intellij/psi/PsiNamedElement; +} + diff --git a/subprojects/analysis-java-psi/build.gradle.kts b/subprojects/analysis-java-psi/build.gradle.kts new file mode 100644 index 00000000..88d043ee --- /dev/null +++ b/subprojects/analysis-java-psi/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("org.jetbrains.conventions.kotlin-jvm") +} + +dependencies { + compileOnly(projects.core) + + api(libs.intellij.java.psi.api) + + implementation(projects.subprojects.analysisMarkdownJb) + + implementation(libs.intellij.java.psi.impl) + implementation(libs.intellij.platform.util.api) + implementation(libs.intellij.platform.util.rt) + + implementation(libs.kotlinx.coroutines.core) + implementation(libs.jsoup) +} diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/DefaultPsiToDocumentableTranslator.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/DefaultPsiToDocumentableTranslator.kt new file mode 100644 index 00000000..72cf45d9 --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/DefaultPsiToDocumentableTranslator.kt @@ -0,0 +1,83 @@ +package org.jetbrains.dokka.analysis.java + +import com.intellij.openapi.vfs.VirtualFileManager +import com.intellij.psi.PsiJavaFile +import com.intellij.psi.PsiKeyword +import com.intellij.psi.PsiManager +import com.intellij.psi.PsiModifierListOwner +import kotlinx.coroutines.coroutineScope +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.analysis.java.parsers.DokkaPsiParser +import org.jetbrains.dokka.analysis.java.parsers.JavaPsiDocCommentParser +import org.jetbrains.dokka.analysis.java.parsers.JavadocParser +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.model.JavaVisibility +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.query +import org.jetbrains.dokka.plugability.querySingle +import org.jetbrains.dokka.transformers.sources.AsyncSourceToDocumentableTranslator +import org.jetbrains.dokka.utilities.parallelMap +import org.jetbrains.dokka.utilities.parallelMapNotNull + +internal class DefaultPsiToDocumentableTranslator : AsyncSourceToDocumentableTranslator { + + override suspend fun invokeSuspending(sourceSet: DokkaSourceSet, context: DokkaContext): DModule { + return coroutineScope { + val projectProvider = context.plugin<JavaAnalysisPlugin>().querySingle { projectProvider } + val project = projectProvider.getProject(sourceSet, context) + + val sourceRootsExtractor = context.plugin<JavaAnalysisPlugin>().querySingle { sourceRootsExtractor } + val sourceRoots = sourceRootsExtractor.extract(sourceSet, context) + + val localFileSystem = VirtualFileManager.getInstance().getFileSystem("file") + + val psiFiles = sourceRoots.parallelMap { sourceRoot -> + sourceRoot.absoluteFile.walkTopDown().mapNotNull { + localFileSystem.findFileByPath(it.path)?.let { vFile -> + PsiManager.getInstance(project).findFile(vFile) as? PsiJavaFile + } + }.toList() + }.flatten() + + val docParser = createPsiParser(sourceSet, context) + + DModule( + name = context.configuration.moduleName, + packages = psiFiles.parallelMapNotNull { it }.groupBy { it.packageName }.toList() + .parallelMap { (packageName: String, psiFiles: List<PsiJavaFile>) -> + docParser.parsePackage(packageName, psiFiles) + }, + documentation = emptyMap(), + expectPresentInSet = null, + sourceSets = setOf(sourceSet) + ) + } + } + + private fun createPsiParser(sourceSet: DokkaSourceSet, context: DokkaContext): DokkaPsiParser { + val projectProvider = context.plugin<JavaAnalysisPlugin>().querySingle { projectProvider } + val docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers } + return DokkaPsiParser( + sourceSetData = sourceSet, + project = projectProvider.getProject(sourceSet, context), + logger = context.logger, + javadocParser = JavadocParser( + docCommentParsers = docCommentParsers, + docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder + ), + javaPsiDocCommentParser = docCommentParsers.single { it is JavaPsiDocCommentParser } as JavaPsiDocCommentParser, + lightMethodChecker = context.plugin<JavaAnalysisPlugin>().querySingle { kotlinLightMethodChecker } + ) + } +} + +internal fun PsiModifierListOwner.getVisibility() = modifierList?.let { + val ml = it.children.toList() + when { + ml.any { it.text == PsiKeyword.PUBLIC } || it.hasModifierProperty("public") -> JavaVisibility.Public + ml.any { it.text == PsiKeyword.PROTECTED } || it.hasModifierProperty("protected") -> JavaVisibility.Protected + ml.any { it.text == PsiKeyword.PRIVATE } || it.hasModifierProperty("private") -> JavaVisibility.Private + else -> JavaVisibility.Default + } +} ?: JavaVisibility.Default diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/JavaAnalysisPlugin.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/JavaAnalysisPlugin.kt new file mode 100644 index 00000000..8884d444 --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/JavaAnalysisPlugin.kt @@ -0,0 +1,106 @@ +package org.jetbrains.dokka.analysis.java + +import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiAnnotation +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.InternalDokkaApi +import org.jetbrains.dokka.analysis.java.doccomment.DocCommentCreator +import org.jetbrains.dokka.analysis.java.doccomment.DocCommentFactory +import org.jetbrains.dokka.analysis.java.doccomment.DocCommentFinder +import org.jetbrains.dokka.analysis.java.doccomment.JavaDocCommentCreator +import org.jetbrains.dokka.analysis.java.parsers.DocCommentParser +import org.jetbrains.dokka.analysis.java.parsers.doctag.InheritDocTagContentProvider +import org.jetbrains.dokka.analysis.java.parsers.JavaPsiDocCommentParser +import org.jetbrains.dokka.analysis.java.parsers.doctag.InheritDocTagResolver +import org.jetbrains.dokka.analysis.java.parsers.doctag.PsiDocTagParser +import org.jetbrains.dokka.analysis.java.util.NoopIntellijLoggerFactory +import org.jetbrains.dokka.plugability.* +import java.io.File + + +@InternalDokkaApi +interface ProjectProvider { + fun getProject(sourceSet: DokkaSourceSet, context: DokkaContext): Project +} + +@InternalDokkaApi +interface SourceRootsExtractor { + fun extract(sourceSet: DokkaSourceSet, context: DokkaContext): List<File> +} + +@InternalDokkaApi +interface BreakingAbstractionKotlinLightMethodChecker { + // TODO [beresnev] not even sure it's needed, but left for compatibility and to preserve behaviour + fun isLightAnnotation(annotation: PsiAnnotation): Boolean + fun isLightAnnotationAttribute(attribute: JvmAnnotationAttribute): Boolean +} + +@InternalDokkaApi +class JavaAnalysisPlugin : DokkaPlugin() { + + // single + val projectProvider by extensionPoint<ProjectProvider>() + + // single + val sourceRootsExtractor by extensionPoint<SourceRootsExtractor>() + + // multiple + val docCommentCreators by extensionPoint<DocCommentCreator>() + + // multiple + val docCommentParsers by extensionPoint<DocCommentParser>() + + // none or more + val inheritDocTagContentProviders by extensionPoint<InheritDocTagContentProvider>() + + // TODO [beresnev] figure out a better way depending on what it's used for + val kotlinLightMethodChecker by extensionPoint<BreakingAbstractionKotlinLightMethodChecker>() + + private val docCommentFactory by lazy { + DocCommentFactory(query { docCommentCreators }.reversed()) + } + + val docCommentFinder by lazy { + DocCommentFinder(logger, docCommentFactory) + } + + internal val javaDocCommentCreator by extending { + docCommentCreators providing { JavaDocCommentCreator() } + } + + private val psiDocTagParser by lazy { + PsiDocTagParser( + inheritDocTagResolver = InheritDocTagResolver( + docCommentFactory = docCommentFactory, + docCommentFinder = docCommentFinder, + contentProviders = query { inheritDocTagContentProviders } + ) + ) + } + + internal val javaDocCommentParser by extending { + docCommentParsers providing { + JavaPsiDocCommentParser( + psiDocTagParser + ) + } + } + + internal val psiToDocumentableTranslator by extending { + CoreExtensions.sourceToDocumentableTranslator providing { DefaultPsiToDocumentableTranslator() } + } + + @OptIn(DokkaPluginApiPreview::class) + override fun pluginApiPreviewAcknowledgement(): PluginApiPreviewAcknowledgement = PluginApiPreviewAcknowledgement + + private companion object { + init { + // Suppress messages emitted by the IntelliJ logger since + // there's not much the end user can do about it + Logger.setFactory(NoopIntellijLoggerFactory()) + } + } +} diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/JavadocTag.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/JavadocTag.kt new file mode 100644 index 00000000..f5cd550f --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/JavadocTag.kt @@ -0,0 +1,48 @@ +package org.jetbrains.dokka.analysis.java + +import com.intellij.psi.PsiMethod +import org.jetbrains.dokka.InternalDokkaApi + +@InternalDokkaApi +sealed class JavadocTag(val name: String) + +object AuthorJavadocTag : JavadocTag("author") +object DeprecatedJavadocTag : JavadocTag("deprecated") +object DescriptionJavadocTag : JavadocTag("description") +object ReturnJavadocTag : JavadocTag("return") +object SinceJavadocTag : JavadocTag("since") + +class ParamJavadocTag( + val method: PsiMethod, + val paramName: String, + val paramIndex: Int +) : JavadocTag(name) { + companion object { + const val name: String = "param" + } +} + +class SeeJavadocTag( + val qualifiedReference: String +) : JavadocTag(name) { + companion object { + const val name: String = "see" + } +} + +sealed class ThrowingExceptionJavadocTag( + name: String, + val exceptionQualifiedName: String? +) : JavadocTag(name) + +class ThrowsJavadocTag(exceptionQualifiedName: String?) : ThrowingExceptionJavadocTag(name, exceptionQualifiedName) { + companion object { + const val name: String = "throws" + } +} + +class ExceptionJavadocTag(exceptionQualifiedName: String?) : ThrowingExceptionJavadocTag(name, exceptionQualifiedName) { + companion object { + const val name: String = "exception" + } +} diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/SynheticElementDocumentationProvider.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/SynheticElementDocumentationProvider.kt new file mode 100644 index 00000000..d780bb40 --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/SynheticElementDocumentationProvider.kt @@ -0,0 +1,42 @@ +package org.jetbrains.dokka.analysis.java + +import com.intellij.openapi.project.Project +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.SyntheticElement +import com.intellij.psi.javadoc.PsiDocComment +import org.jetbrains.dokka.analysis.java.parsers.JavaPsiDocCommentParser +import org.jetbrains.dokka.model.doc.DocumentationNode + +private const val ENUM_VALUEOF_TEMPLATE_PATH = "/dokka/docs/javadoc/EnumValueOf.java.template" +private const val ENUM_VALUES_TEMPLATE_PATH = "/dokka/docs/javadoc/EnumValues.java.template" + +internal class SyntheticElementDocumentationProvider( + private val javadocParser: JavaPsiDocCommentParser, + private val project: Project +) { + fun isDocumented(psiElement: PsiElement): Boolean = psiElement is PsiMethod + && (psiElement.isSyntheticEnumValuesMethod() || psiElement.isSyntheticEnumValueOfMethod()) + + fun getDocumentation(psiElement: PsiElement): DocumentationNode? { + val psiMethod = psiElement as? PsiMethod ?: return null + val templatePath = when { + psiMethod.isSyntheticEnumValuesMethod() -> ENUM_VALUES_TEMPLATE_PATH + psiMethod.isSyntheticEnumValueOfMethod() -> ENUM_VALUEOF_TEMPLATE_PATH + else -> return null + } + val docComment = loadSyntheticDoc(templatePath) ?: return null + return javadocParser.parsePsiDocComment(docComment, psiElement) + } + + private fun loadSyntheticDoc(path: String): PsiDocComment? { + val text = javaClass.getResource(path)?.readText() ?: return null + return JavaPsiFacade.getElementFactory(project).createDocCommentFromText(text) + } +} + +private fun PsiMethod.isSyntheticEnumValuesMethod() = this.isSyntheticEnumFunction() && this.name == "values" +private fun PsiMethod.isSyntheticEnumValueOfMethod() = this.isSyntheticEnumFunction() && this.name == "valueOf" +private fun PsiMethod.isSyntheticEnumFunction() = this is SyntheticElement && this.containingClass?.isEnum == true + diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocComment.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocComment.kt new file mode 100644 index 00000000..6cc32233 --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocComment.kt @@ -0,0 +1,14 @@ +package org.jetbrains.dokka.analysis.java.doccomment + +import org.jetbrains.dokka.InternalDokkaApi +import org.jetbrains.dokka.analysis.java.JavadocTag + +/** + * MUST override equals and hashcode + */ +@InternalDokkaApi +interface DocComment { + fun hasTag(tag: JavadocTag): Boolean + + fun resolveTag(tag: JavadocTag): List<DocumentationContent> +} diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocCommentCreator.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocCommentCreator.kt new file mode 100644 index 00000000..3d7d4247 --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocCommentCreator.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dokka.analysis.java.doccomment + +import com.intellij.psi.PsiNamedElement +import org.jetbrains.dokka.InternalDokkaApi + +@InternalDokkaApi +interface DocCommentCreator { + fun create(element: PsiNamedElement): DocComment? +} diff --git a/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocCommentFactory.kt b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocCommentFactory.kt new file mode 100644 index 00000000..96245ac2 --- /dev/null +++ b/subprojects/analysis-java-psi/src/main/kotlin/org/jetbrains/dokka/analysis/java/doccomment/DocCommentFactory.kt @@ -0,0 +1,20 @@ +package org.jetbrains.dokka.analysis.java.doccomment + +import com.intellij.psi.PsiNamedElement +import org.jetbrains.dokka.InternalDokkaApi + +@InternalDokkaApi +class DocCommentFactory( + private val docCommentCreators: List<DocCommentCreator> +) { < |
