Skip to content

Commit

Permalink
Extract analysis into separate modules
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnatBeresnev committed Jun 16, 2023
1 parent 2611263 commit 333dc06
Show file tree
Hide file tree
Showing 308 changed files with 6,036 additions and 4,345 deletions.
148 changes: 148 additions & 0 deletions analysis/java-analysis-psi/api/java-analysis-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 abstract interface class org/jetbrains/dokka/analysis/java/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/DocCommentCreator {
public abstract fun create (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/analysis/java/DocComment;
}

public final class org/jetbrains/dokka/analysis/java/DocCommentFactory {
public fun <init> (Ljava/util/List;)V
public final fun fromElement (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/analysis/java/DocComment;
}

public final class org/jetbrains/dokka/analysis/java/DocCommentFinder {
public fun <init> (Lorg/jetbrains/dokka/utilities/DokkaLogger;Lorg/jetbrains/dokka/analysis/java/DocCommentFactory;)V
public final fun findClosestToElement (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/analysis/java/DocComment;
}

public abstract interface class org/jetbrains/dokka/analysis/java/DocCommentParser {
public abstract fun canParse (Lorg/jetbrains/dokka/analysis/java/DocComment;)Z
public abstract fun parse (Lorg/jetbrains/dokka/analysis/java/DocComment;Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/model/doc/DocumentationNode;
}

public abstract interface class org/jetbrains/dokka/analysis/java/DocumentationContent {
public abstract fun getTag ()Lorg/jetbrains/dokka/analysis/java/JavadocTag;
public abstract fun resolveSiblings ()Ljava/util/List;
}

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/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 final class org/jetbrains/dokka/analysis/java/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/doctag/InheritDocTagContentProvider {
public abstract fun canConvert (Lorg/jetbrains/dokka/analysis/java/DocumentationContent;)Z
public abstract fun convertToHtml (Lorg/jetbrains/dokka/analysis/java/DocumentationContent;Lorg/jetbrains/dokka/analysis/java/doctag/DocTagParserContext;)Ljava/lang/String;
}

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/DocCommentFinder;)V
public fun parseDocumentation (Lcom/intellij/psi/PsiNamedElement;)Lorg/jetbrains/dokka/model/doc/DocumentationNode;
}

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 getLineNumber ()Ljava/lang/Integer;
public fun getPath ()Ljava/lang/String;
public final fun getPsi ()Lcom/intellij/psi/PsiNamedElement;
}

22 changes: 22 additions & 0 deletions analysis/java-analysis-psi/build.gradle.kts
@@ -0,0 +1,22 @@
plugins {
id("org.jetbrains.conventions.kotlin-jvm")
}

dependencies {
// TODO [beresnev] extract into versions.toml
val idea_version = "203.8084.24" // must match the version used in kotlin

compileOnly(projects.core)

api("com.jetbrains.intellij.java:java-psi:$idea_version")

implementation(projects.analysis.markdown)

implementation("com.jetbrains.intellij.platform:util:$idea_version")
implementation("com.jetbrains.intellij.java:java-psi-impl:$idea_version")
implementation("com.jetbrains.intellij.platform:util-rt:$idea_version")
implementation("com.jetbrains.intellij.platform:jps-model-impl:$idea_version")

implementation(libs.kotlinx.coroutines.core)
implementation(libs.jsoup)
}
@@ -0,0 +1,82 @@
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.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
@@ -0,0 +1,13 @@
package org.jetbrains.dokka.analysis.java

import org.jetbrains.dokka.InternalDokkaApi

/**
* MUST override equals and hashcode
*/
@InternalDokkaApi
interface DocComment {
fun hasTag(tag: JavadocTag): Boolean

fun resolveTag(tag: JavadocTag): List<DocumentationContent>
}
@@ -0,0 +1,9 @@
package org.jetbrains.dokka.analysis.java

import com.intellij.psi.PsiNamedElement
import org.jetbrains.dokka.InternalDokkaApi

@InternalDokkaApi
interface DocCommentCreator {
fun create(element: PsiNamedElement): DocComment?
}
@@ -0,0 +1,20 @@
package org.jetbrains.dokka.analysis.java

import com.intellij.psi.PsiNamedElement
import org.jetbrains.dokka.InternalDokkaApi

@InternalDokkaApi
class DocCommentFactory(
private val docCommentCreators: List<DocCommentCreator>
) {
fun fromElement(element: PsiNamedElement): DocComment? {
docCommentCreators.forEach { creator ->
val comment = creator.create(element)
if (comment != null) {
return comment
}
}
return null
}
}

@@ -0,0 +1,64 @@
package org.jetbrains.dokka.analysis.java

import com.intellij.psi.PsiClass
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.javadoc.PsiDocComment
import org.jetbrains.dokka.InternalDokkaApi
import org.jetbrains.dokka.analysis.java.util.from
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.utilities.DokkaLogger

@InternalDokkaApi
class DocCommentFinder(
private val logger: DokkaLogger,
private val docCommentFactory: DocCommentFactory,
) {
fun findClosestToElement(element: PsiNamedElement): DocComment? {
val docComment = docCommentFactory.fromElement(element)
if (docComment != null) {
return docComment
}

return if (element is PsiMethod) {
findClosestToMethod(element)
} else {
element.children
.filterIsInstance<PsiDocComment>()
.firstOrNull()
?.let { JavaDocComment(it) }
}
}

private fun findClosestToMethod(method: PsiMethod): DocComment? {
val superMethods = method.findSuperMethods()
if (superMethods.isEmpty()) return null

if (superMethods.size == 1) {
return findClosestToElement(superMethods.single())
}

val superMethodDocumentation = superMethods.map { superMethod -> findClosestToElement(superMethod) }.distinct()
if (superMethodDocumentation.size == 1) {
return superMethodDocumentation.single()
}

logger.debug(
"Conflicting documentation for ${DRI.from(method)}" +
"${superMethods.map { DRI.from(it) }}"
)

/* Prioritize super class over interface */
val indexOfSuperClass = superMethods.indexOfFirst { superMethod ->
val parent = superMethod.parent
if (parent is PsiClass) !parent.isInterface
else false
}

return if (indexOfSuperClass >= 0) {
superMethodDocumentation[indexOfSuperClass]
} else {
superMethodDocumentation.first()
}
}
}
@@ -0,0 +1,11 @@
package org.jetbrains.dokka.analysis.java

import com.intellij.psi.PsiNamedElement
import org.jetbrains.dokka.InternalDokkaApi
import org.jetbrains.dokka.model.doc.DocumentationNode

@InternalDokkaApi
interface DocCommentParser {
fun canParse(docComment: DocComment): Boolean
fun parse(docComment: DocComment, context: PsiNamedElement): DocumentationNode
}
@@ -0,0 +1,10 @@
package org.jetbrains.dokka.analysis.java

import org.jetbrains.dokka.InternalDokkaApi

@InternalDokkaApi
interface DocumentationContent {
val tag: JavadocTag

fun resolveSiblings(): List<DocumentationContent>
}

0 comments on commit 333dc06

Please sign in to comment.