Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Analysis API to 2.0.20-dev-6911 #3652

Merged
merged 3 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion dokka-subprojects/analysis-kotlin-symbols/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 40,6 @@ dependencies {
libs.kotlin.high.level.api.impl,
libs.kotlin.high.level.api.fir,
libs.kotlin.low.level.api.fir,
libs.kotlin.analysis.project.structure,
libs.kotlin.analysis.api.platform,
libs.kotlin.symbol.light.classes,
).forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 33,7 @@ internal fun KaSession.getJavaDocDocumentationFrom(
}
} else if (symbol.origin == KaSymbolOrigin.SOURCE && symbol is KaCallableSymbol) {
// Note: javadocParser searches in overridden JAVA declarations for JAVA method, not Kotlin
symbol.getAllOverriddenSymbols().forEach { overrider ->
symbol.allOverriddenSymbols.forEach { overrider ->
if (overrider.origin == KaSymbolOrigin.JAVA_SOURCE)
return@getJavaDocDocumentationFrom (overrider.psi as? PsiNamedElement)?.let {
javadocParser.parseDocumentation(it)
Expand All @@ -49,7 49,7 @@ internal fun KaSession.getKDocDocumentationFrom(symbol: KaSymbol, logger: DokkaL
val kdocLocation = ktElement?.containingFile?.name?.let {
val name = when(symbol) {
is KaCallableSymbol -> symbol.callableId?.toString()
is KaClassOrObjectSymbol -> symbol.classId?.toString()
is KaClassSymbol -> symbol.classId?.toString()
is KaNamedSymbol -> symbol.name.asString()
else -> null
}?.replace('/', '.') // replace to be compatible with K1
Expand All @@ -76,13 76,13 @@ internal data class KDocContent(
val sections: List<KDocSection>
)

internal fun KaSession.findKDoc(symbol: KtSymbol): KDocContent? {
internal fun KaSession.findKDoc(symbol: KaSymbol): KDocContent? {
// Dokka's HACK: primary constructors can be generated
// so [KtSymbol.psi] is undefined for [KtSymbolOrigin.SOURCE_MEMBER_GENERATED] origin
// we need to get psi of a containing class
if(symbol is KtConstructorSymbol && symbol.isPrimary) {
val containingClass = symbol.originalContainingClassForOverride
if (containingClass?.origin != KtSymbolOrigin.SOURCE) return null
if(symbol is KaConstructorSymbol && symbol.isPrimary) {
val containingClass = symbol.fakeOverrideOriginal.containingSymbol as? KaClassSymbol
if (containingClass?.origin != KaSymbolOrigin.SOURCE) return null
val kdoc = (containingClass.psi as? KtDeclaration)?.docComment ?: return null
val constructorSection = kdoc.findSectionByTag(KDocKnownTag.CONSTRUCTOR)
if (constructorSection != null) {
Expand All @@ -96,16 96,16 @@ internal fun KaSession.findKDoc(symbol: KtSymbol): KDocContent? {
}

// for generated function (e.g. `copy`) [KtSymbol.psi] is undefined (although actually returns a class psi), see test `data class kdocs over generated methods`
if (symbol.origin != KtSymbolOrigin.SOURCE) return null
if (symbol.origin != KaSymbolOrigin.SOURCE) return null


val ktElement = symbol.psi as? KtElement
ktElement?.findKDoc()?.let {
return it
}

if (symbol is KtCallableSymbol) {
symbol.getAllOverriddenSymbols().forEach { overrider ->
if (symbol is KaCallableSymbol) {
symbol.allOverriddenSymbols.forEach { overrider ->
findKDoc(overrider)?.let {
return it
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 22,7 @@ internal fun KaSession.hasGeneratedKDocDocumentation(symbol: KaSymbol): Boolean
private fun KaSession.getDocumentationTemplatePath(symbol: KaSymbol): String? =
when (symbol) {
is KaPropertySymbol -> if (isEnumEntriesProperty(symbol)) ENUM_ENTRIES_TEMPLATE_PATH else null
is KaFunctionSymbol -> {
is KaNamedFunctionSymbol -> {
when {
isEnumValuesMethod(symbol) -> ENUM_VALUES_TEMPLATE_PATH
isEnumValueOfMethod(symbol) -> ENUM_VALUEOF_TEMPLATE_PATH
Expand All @@ -35,15 35,15 @@ private fun KaSession.getDocumentationTemplatePath(symbol: KaSymbol): String? =

private fun KaSession.isEnumSpecialMember(symbol: KaPossibleMemberSymbol): Boolean =
symbol.origin == KaSymbolOrigin.SOURCE_MEMBER_GENERATED
&& (symbol.getContainingSymbol() as? KaClassOrObjectSymbol)?.classKind == KaClassKind.ENUM_CLASS
&& (symbol.containingSymbol as? KaClassSymbol)?.classKind == KaClassKind.ENUM_CLASS

private fun KaSession.isEnumEntriesProperty(symbol: KaPropertySymbol): Boolean =
symbol.name == StandardNames.ENUM_ENTRIES && isEnumSpecialMember(symbol)

private fun KaSession.isEnumValuesMethod(symbol: KaFunctionSymbol): Boolean =
private fun KaSession.isEnumValuesMethod(symbol: KaNamedFunctionSymbol): Boolean =
symbol.name == StandardNames.ENUM_VALUES && isEnumSpecialMember(symbol)

private fun KaSession.isEnumValueOfMethod(symbol: KaFunctionSymbol): Boolean =
private fun KaSession.isEnumValueOfMethod(symbol: KaNamedFunctionSymbol): Boolean =
symbol.name == StandardNames.ENUM_VALUE_OF && isEnumSpecialMember(symbol)

internal fun KaSession.getGeneratedKDocDocumentationFrom(symbol: KaSymbol): DocumentationNode? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 39,8 @@ internal fun ModuleAndPackageDocumentationParsingContext(
val sourceModule = kotlinAnalysis.getModule(sourceSet)
val contextPsi = analyze(sourceModule) {
val contextSymbol = when (fragment.classifier) {
Module -> ROOT_PACKAGE_SYMBOL
Package -> getPackageSymbolIfPackageExists(FqName(fragment.name))
Module -> rootPackageSymbol
Package -> findPackage(FqName(fragment.name))
}
contextSymbol?.psi
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 9,8 @@ import com.intellij.openapi.util.Disposer
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.model.SourceSetDependent
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.kotlin.analysis.api.projectStructure.KaSourceModule
import org.jetbrains.kotlin.analysis.api.standalone.StandaloneAnalysisAPISession
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import java.io.Closeable

internal fun SamplesKotlinAnalysis(
Expand All @@ -31,7 31,7 @@ internal fun ProjectKotlinAnalysis(
)

internal class KotlinAnalysis(
private val sourceModules: SourceSetDependent<KtSourceModule>,
private val sourceModules: SourceSetDependent<KaSourceModule>,
private val analysisSession: StandaloneAnalysisAPISession,
private val projectDisposable: Disposable
) : Closeable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 10,8 @@ import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.DokkaSourceSetID
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.projectStructure.KaSourceModule
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleBuilder
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSdkModule
Expand Down Expand Up @@ -57,28 56,27 @@ internal fun getLanguageVersionSettings(
)
}

@OptIn(KtAnalysisApiInternals::class)
internal fun createAnalysisSession(
sourceSets: List<DokkaConfiguration.DokkaSourceSet>,
logger: DokkaLogger,
projectDisposable: Disposable = Disposer.newDisposable("StandaloneAnalysisAPISession.project"),
isSampleProject: Boolean = false
): KotlinAnalysis {
val sourcesModule = mutableMapOf<DokkaConfiguration.DokkaSourceSet, KtSourceModule>()
val sourcesModule = mutableMapOf<DokkaConfiguration.DokkaSourceSet, KaSourceModule>()

val analysisSession = buildStandaloneAnalysisAPISession(
projectDisposable = projectDisposable,
) {
val sortedSourceSets = topologicalSortByDependantSourceSets(sourceSets, logger)

val sourcesModuleBySourceSetId = mutableMapOf<DokkaSourceSetID, KtSourceModule>()
val sourcesModuleBySourceSetId = mutableMapOf<DokkaSourceSetID, KaSourceModule>()

buildKtModuleProvider {
val jdkModule = getJdkHomeFromSystemProperty(logger)?.let { jdkHome ->
buildKtSdkModule {
this.platform = Platform.jvm.toTargetPlatform()
addBinaryRootsFromJdkHome(jdkHome.toPath(), isJre = true)
sdkName = "JDK"
libraryName = "JDK"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 18,9 @@ import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.dokka.plugability.query
import org.jetbrains.dokka.analysis.kotlin.documentable.ExternalDocumentableProvider
import org.jetbrains.kotlin.analysis.api.symbols.KaNamedClassSymbol

internal class SymbolExternalDocumentablesProvider(val context: DokkaContext) : ExternalDocumentableProvider {
private val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis }
Expand All @@ -29,7 29,7 @@ internal class SymbolExternalDocumentablesProvider(val context: DokkaContext) :
val classId = getClassIdFromDRI(dri)

return analyze(kotlinAnalysis.getModule(sourceSet)) {
val symbol = getClassOrObjectSymbolByClassId(classId) as? KtNamedClassOrObjectSymbol?: return@analyze null
val symbol = findClass(classId) as? KaNamedClassSymbol ?: return@analyze null
val javadocParser =
if (sourceSet.analysisPlatform == Platform.jvm)
JavadocParser(
Expand All @@ -39,9 39,9 @@ internal class SymbolExternalDocumentablesProvider(val context: DokkaContext) :
else null
val translator = DokkaSymbolVisitor(sourceSet, sourceSet.displayName, kotlinAnalysis, logger = context.logger, javadocParser)

val parentDRI = symbol.getContainingSymbol()?.let { getDRIFromSymbol(it) } ?: /* top level */ DRI(dri.packageName)
val parentDRI = symbol.containingSymbol?.let { getDRIFromSymbol(it) } ?: /* top level */ DRI(dri.packageName)
with(translator) {
return@analyze visitNamedClassOrObjectSymbol(symbol, parentDRI)
return@analyze visitClassSymbol(symbol, parentDRI)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 13,6 @@ import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.*
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.dokka.analysis.kotlin.internal.ClassHierarchy
import org.jetbrains.dokka.analysis.kotlin.internal.FullClassHierarchyBuilder
import org.jetbrains.dokka.analysis.kotlin.internal.Supertypes
Expand All @@ -23,6 22,7 @@ import org.jetbrains.dokka.analysis.kotlin.symbols.translators.TypeTranslator
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.kotlin.analysis.api.types.KaType
import org.jetbrains.kotlin.psi.KtClassOrObject
import java.util.concurrent.ConcurrentHashMap

Expand All @@ -36,20 36,20 @@ internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClas
return map
}

private fun KaSession.collectSupertypesFromKtType(
driWithKType: Pair<DRI, KtType>,
private fun KaSession.collectSupertypesFromKotlinType(
driWithKType: Pair<DRI, KaType>,
supersMap: MutableMap<DRI, Supertypes>
) {
val (dri, kotlinType) = driWithKType
if (supersMap[dri] == null) {
val supertypes = kotlinType.getDirectSuperTypes(shouldApproximate = true).filterNot { it.isAny }
val supertypes = kotlinType.directSupertypes(shouldApproximate = true).filterNot { it.isAnyType }.toList()
val supertypesDriWithKType = supertypes.mapNotNull { supertype ->
supertype.expandedSymbol?.let {
getDRIFromClassLike(it) to supertype
}
}
supersMap[dri] = supertypesDriWithKType.map { it.first }
supertypesDriWithKType.forEach { collectSupertypesFromKtType(it, supersMap) }
supertypesDriWithKType.forEach { collectSupertypesFromKotlinType(it, supersMap) }
}
}

Expand Down Expand Up @@ -82,8 82,8 @@ internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClas
if (source is KtPsiDocumentableSource) {
(source.psi as? KtClassOrObject)?.let { psi ->
analyze(kotlinAnalysis.getModule(sourceSet)) {
val type = psi.getNamedClassOrObjectSymbol()?.buildSelfClassType() ?: return@analyze
hierarchy[sourceSet]?.let { collectSupertypesFromKtType(documentable.dri to type, it) }
val type = psi.namedClassSymbol?.defaultType ?: return@analyze
hierarchy[sourceSet]?.let { collectSupertypesFromKotlinType(documentable.dri to type, it) }
}
}
} else if (source is PsiDocumentableSource) {
Expand Down Expand Up @@ -114,8 114,8 @@ internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClas
val source = it.sources[sourceSet]
if (source is KtPsiDocumentableSource) {
(source.psi as? KtClassOrObject)?.let { psi ->
val type = psi.getNamedClassOrObjectSymbol()?.buildSelfClassType() ?: return@analyze
collectSupertypesWithKindFromKtType(typeTranslator, with(typeTranslator) {
val type = psi.namedClassSymbol?.defaultType ?: return@analyze
collectSupertypesWithKindFromKotlinType(typeTranslator, with(typeTranslator) {
toTypeConstructorWithKindFrom(type)
} to type, hierarchy)
}
Expand All @@ -125,15 125,15 @@ internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClas
return hierarchy
}

private fun KaSession.collectSupertypesWithKindFromKtType(
private fun KaSession.collectSupertypesWithKindFromKotlinType(
typeTranslator: TypeTranslator,
typeConstructorWithKindWithKType: Pair<TypeConstructorWithKind, KtType>,
typeConstructorWithKindWithKType: Pair<TypeConstructorWithKind, KaType>,
supersMap: MutableMap<DRI, SuperclassesWithKind>
) {
val (typeConstructorWithKind, kotlinType) = typeConstructorWithKindWithKType

if (supersMap[typeConstructorWithKind.typeConstructor.dri] == null) {
val supertypes = kotlinType.getDirectSuperTypes(shouldApproximate = true).filterNot { it.isAny }
val supertypes = kotlinType.directSupertypes(shouldApproximate = true).filterNot { it.isAnyType }.toList()

val supertypesDriWithKType = supertypes.map { supertype ->
with(typeTranslator) {
Expand All @@ -142,7 142,7 @@ internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClas
}
supersMap[typeConstructorWithKind.typeConstructor.dri] =
SuperclassesWithKind(typeConstructorWithKind, supertypesDriWithKType.map { it.first })
supertypesDriWithKType.forEach { collectSupertypesWithKindFromKtType(typeTranslator, it, supersMap) }
supertypesDriWithKType.forEach { collectSupertypesWithKindFromKotlinType(typeTranslator, it, supersMap) }
}
}
}
Loading
Loading