Skip to content

Commit

Permalink
Update Analysis API to 2.0.20-dev-6911 (#3652)
Browse files Browse the repository at this point in the history
* Update Analysis API to 2.0.20-dev-6911

List of changes:
- KT-68462
- partially KT-68884
and others

* Fix sequences

* Rename
  • Loading branch information
vmishenev committed Jun 25, 2024
1 parent bb5a2b1 commit 75fd544
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 176 deletions.
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

0 comments on commit 75fd544

Please sign in to comment.