Skip to content

Commit

Permalink
@vmishenev Update Analysis API to 2.0.20-dev-6501 (#3651)
Browse files Browse the repository at this point in the history
List of changes:
* KT-65215 - Rename analysis-api-providers to `analysis-api-platform-interface`
* KT-69055
* KT-53669
* partially KT-67786
* partially KT-68882
* partially KT-68857
* KT-68341
* get rid of the `api-fe10`
  • Loading branch information
vmishenev authored Jun 20, 2024
1 parent 880ac65 commit bb5a2b1
Show file tree
Hide file tree
Showing 12 changed files with 38 additions and 70 deletions.
3 changes: 1 addition & 2 deletions dokka-subprojects/analysis-kotlin-symbols/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 39,9 @@ dependencies {
listOf(
libs.kotlin.high.level.api.impl,
libs.kotlin.high.level.api.fir,
libs.kotlin.high.level.api.fe10,
libs.kotlin.low.level.api.fir,
libs.kotlin.analysis.project.structure,
libs.kotlin.analysis.api.providers,
libs.kotlin.analysis.api.platform,
libs.kotlin.symbol.light.classes,
).forEach {
runtimeOnly(it) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 27,14 @@ internal fun KaSession.getJavaDocDocumentationFrom(
symbol: KaSymbol,
javadocParser: JavadocParser
): DocumentationNode? {
if (symbol.origin == KaSymbolOrigin.JAVA) {
if (symbol.origin == KaSymbolOrigin.JAVA_SOURCE) {
return (symbol.psi as? PsiNamedElement)?.let {
javadocParser.parseDocumentation(it)
}
} 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 ->
if (overrider.origin == KaSymbolOrigin.JAVA)
if (overrider.origin == KaSymbolOrigin.JAVA_SOURCE)
return@getJavaDocDocumentationFrom (overrider.psi as? PsiNamedElement)?.let {
javadocParser.parseDocumentation(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 68,6 @@ internal fun createAnalysisSession(

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 44,7 @@ internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClas
if (supersMap[dri] == null) {
val supertypes = kotlinType.getDirectSuperTypes(shouldApproximate = true).filterNot { it.isAny }
val supertypesDriWithKType = supertypes.mapNotNull { supertype ->
supertype.expandedClassSymbol?.let {
supertype.expandedSymbol?.let {
getDRIFromClassLike(it) to supertype
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 27,7 @@ import org.jetbrains.dokka.plugability.query
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.startOffset
Expand Down Expand Up @@ -98,29 96,6 @@ private class SymbolSampleAnalysisEnvironment(
return SampleSnippet(imports, body)
}

// TODO: remove after KT-53669 and use [org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe] from Analysis API
private inline fun <reified PSI : PsiElement> KtSymbol.kotlinAndJavaSourcePsiSafe(): PSI? {
// TODO: support Java sources after KT-53669
val sourcePsi = when (origin) {
KaSymbolOrigin.SOURCE -> this.psi
KaSymbolOrigin.JAVA -> this.psi

KaSymbolOrigin.SOURCE_MEMBER_GENERATED -> null
KaSymbolOrigin.LIBRARY -> null
KaSymbolOrigin.SAM_CONSTRUCTOR -> null
KaSymbolOrigin.INTERSECTION_OVERRIDE -> null
KaSymbolOrigin.SUBSTITUTION_OVERRIDE -> null
KaSymbolOrigin.DELEGATED -> null
KaSymbolOrigin.JAVA_SYNTHETIC_PROPERTY -> null
KaSymbolOrigin.PROPERTY_BACKING_FIELD -> null
KaSymbolOrigin.PLUGIN -> null
KaSymbolOrigin.JS_DYNAMIC -> null
KaSymbolOrigin.NATIVE_FORWARD_DECLARATION -> null
}

return sourcePsi as? PSI
}

private fun findPsiElement(sourceSet: DokkaSourceSet, fqLink: String): PsiElement? {
// fallback to default roots of the source set even if sample roots are assigned,
// because `@sample` tag can contain links to functions from project sources
Expand All @@ -132,7 107,7 @@ private class SymbolSampleAnalysisEnvironment(
val ktSourceModule = this.getModuleOrNull(sourceSet) ?: return null
return analyze(ktSourceModule) {
resolveKDocTextLinkToSymbol(fqLink)
?.kotlinAndJavaSourcePsiSafe()
?.sourcePsiSafe()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 59,19 @@ internal class AnnotationTranslator {
private fun KaSession.mustBeDocumented(annotationApplication: KaAnnotationApplication): Boolean {
if (annotationApplication.isNoExistedInSource()) return false
val annotationClass = getClassOrObjectSymbolByClassId(annotationApplication.classId ?: return false)
return annotationClass?.hasAnnotation(mustBeDocumentedAnnotation)
return annotationClass?.let { mustBeDocumentedAnnotation in it.annotations }
?: false
}

private fun KaSession.toDokkaAnnotation(annotationApplication: KaAnnotationApplication) =
Annotations.Annotation(
dri = annotationApplication.classId?.createDRI()
?: DRI(packageName = "", classNames = ERROR_CLASS_NAME), // classId might be null on a non-existing annotation call,
params = if (annotationApplication is KaAnnotationApplicationWithArgumentsInfo) annotationApplication.arguments.associate {
params = annotationApplication.arguments.associate {
it.name.asString() to toDokkaAnnotationValue(
it.expression
)
} else emptyMap(),
},
mustBeDocumented = mustBeDocumented(annotationApplication),
scope = annotationApplication.useSiteTarget?.toDokkaAnnotationScope() ?: Annotations.AnnotationScope.DIRECT
)
Expand Down Expand Up @@ -112,7 112,7 @@ internal class AnnotationTranslator {
type.classId.createDRI()
)
else -> ClassValue(
type.asStringForDebugging(),
type.toString(),
DRI(packageName = "", classNames = ERROR_CLASS_NAME)
)
}
Expand Down Expand Up @@ -140,7 140,7 @@ internal class AnnotationTranslator {
* @see ParameterName
*/
internal fun KaAnnotated.getPresentableName(): String? =
this.annotationsByClassId(parameterNameAnnotation)
this.annotations[parameterNameAnnotation]
.firstOrNull()?.arguments?.firstOrNull { it.name == Name.identifier("name") }?.expression?.let { it as? KaConstantAnnotationValue }
?.let { it.constantValue.value.toString() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 8,6 @@ import org.jetbrains.dokka.links.*
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaNamedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaSymbolKind
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaSymbolWithKind
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaSymbolWithTypeParameters
import org.jetbrains.kotlin.analysis.api.types.*
import org.jetbrains.kotlin.name.CallableId
Expand Down Expand Up @@ -108,7 106,6 @@ private fun KaSession.getDRIFromReceiverType(type: KaType): DRI {

is KaCapturedType -> throw IllegalStateException("Unexpected non-denotable type while creating DRI $type")
is KaFlexibleType -> throw IllegalStateException("Unexpected non-denotable type while creating DRI $type")
is KaIntegerLiteralType -> throw IllegalStateException("Unexpected non-denotable type while creating DRI $type")
is KaIntersectionType -> throw IllegalStateException("Unexpected non-denotable type while creating DRI $type")
}
}
Expand All @@ -128,7 125,7 @@ internal fun KaSession.getDRIFromSymbol(symbol: KaSymbol): DRI =
}

private fun KaSession.getDRIFromNonCallablePossibleLocalSymbol(symbol: KaSymbol): DRI {
if ((symbol as? KaSymbolWithKind)?.symbolKind == KaSymbolKind.LOCAL) {
if (symbol.location == KaSymbolLocation.LOCAL) {
return symbol.getContainingSymbol()?.let { getDRIFromNonCallablePossibleLocalSymbol(it) }
?: throw IllegalStateException("Can't get containing symbol for local symbol")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 129,8 @@ internal class DokkaSymbolVisitor(
): DPackage {
val dri = getDRIFromPackage(packageSymbol)
val scope = packageSymbol.getPackageScope()
val callables = scope.getCallableSymbols().toList().filterSymbolsInSourceSet(moduleFiles)
val classifiers = scope.getClassifierSymbols().toList().filterSymbolsInSourceSet(moduleFiles)
val callables = scope.callables.toList().filterSymbolsInSourceSet(moduleFiles)
val classifiers = scope.classifiers.toList().filterSymbolsInSourceSet(moduleFiles)

val functions = callables.filterIsInstance<KaFunctionSymbol>().map { visitFunctionSymbol(it, dri) }
val properties = callables.filterIsInstance<KaPropertySymbol>().map { visitPropertySymbol(it, dri) }
Expand Down Expand Up @@ -389,6 389,7 @@ internal class DokkaSymbolVisitor(
* @param includeStaticScope a flag to add static members, e.g. `valueOf`, `values` and `entries` members for Enum.
* See [org.jetbrains.kotlin.analysis.api.components.KaScopeProvider.getStaticDeclaredMemberScope] for what a static scope is.
*/
@OptIn(KaExperimentalApi::class) // due to getSyntheticJavaPropertiesScope
private fun KaSession.getDokkaScopeFrom(
namedClassOrObjectSymbol: KaNamedClassOrObjectSymbol,
dri: DRI,
Expand All @@ -397,13 398,13 @@ internal class DokkaSymbolVisitor(
// getCombinedMemberScope additionally includes a static scope, see [getCombinedMemberScope]
// e.g. getStaticMemberScope contains `valueOf`, `values` and `entries` members for Enum
val scope = if(includeStaticScope) namedClassOrObjectSymbol.getCombinedMemberScope() else namedClassOrObjectSymbol.getMemberScope()
val constructors = scope.getConstructors().map { visitConstructorSymbol(it) }.toList()
val constructors = scope.constructors.map { visitConstructorSymbol(it) }.toList()

val callables = scope.getCallableSymbols().toList()
val callables = scope.callables.toList()

// Dokka K1 does not show inherited nested and inner classes,
// so it should show only classifiers (classes and objects) explicitly declared
val classifiers = if(includeStaticScope) namedClassOrObjectSymbol.getStaticMemberScope().getClassifierSymbols() else emptySequence()
val classifiers = if(includeStaticScope) namedClassOrObjectSymbol.getStaticMemberScope().classifiers else emptySequence()

val syntheticJavaProperties =
namedClassOrObjectSymbol.buildSelfClassType().getSyntheticJavaPropertiesScope()?.getCallableSignatures()
Expand All @@ -419,7 420,7 @@ internal class DokkaSymbolVisitor(
.filterOutSyntheticJavaPropBackingField()

fun List<KaFunctionSymbol>.filterOutSyntheticJavaPropAccessors() = filterNot { fn ->
if (fn.origin == KaSymbolOrigin.JAVA && fn.callableId != null)
if ((fn.origin == KaSymbolOrigin.JAVA_SOURCE || fn.origin == KaSymbolOrigin.JAVA_LIBRARY) && fn.callableId != null)
syntheticJavaProperties.any { fn.callableId == it.javaGetterSymbol.callableId || fn.callableId == it.javaSetterSymbol?.callableId }
else false
}
Expand Down Expand Up @@ -784,7 785,7 @@ internal class DokkaSymbolVisitor(
dri: DRI
): DTypeParameter {
val upperBoundsOrNullableAny =
typeParameterSymbol.upperBounds.takeIf { it.isNotEmpty() } ?: listOf(this.builtinTypes.NULLABLE_ANY)
typeParameterSymbol.upperBounds.takeIf { it.isNotEmpty() } ?: listOf(this.builtinTypes.nullableAny)
return DTypeParameter(
variantTypeParameter = TypeParameter(
dri = dri.copy(target = PointingToGenericParameters(index)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 6,6 @@ package org.jetbrains.dokka.analysis.kotlin.symbols.translators

import org.jetbrains.dokka.links.*
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.KaStarTypeProjection
import org.jetbrains.kotlin.analysis.api.KaTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.KaTypeProjection
import org.jetbrains.kotlin.analysis.api.types.*

internal fun KaSession.getTypeReferenceFrom(type: KaType): TypeReference =
Expand All @@ -30,7 27,7 @@ private fun KaSession.getTypeReferenceFromPossiblyRecursive(
return when (type) {
is KaNonErrorClassType -> TypeConstructor(
type.classId.asFqNameString(),
type.ownTypeArguments.map {
type.typeArguments.map {
getTypeReferenceFromTypeProjection(
it,
paramTrace
Expand All @@ -40,7 37,7 @@ private fun KaSession.getTypeReferenceFromPossiblyRecursive(

is KaTypeParameterType -> {
val upperBoundsOrNullableAny =
type.symbol.upperBounds.takeIf { it.isNotEmpty() } ?: listOf(this.builtinTypes.NULLABLE_ANY)
type.symbol.upperBounds.takeIf { it.isNotEmpty() } ?: listOf(this.builtinTypes.nullableAny)

TypeParam(bounds = upperBoundsOrNullableAny.map {
getTypeReferenceFromPossiblyRecursive(
Expand Down Expand Up @@ -71,7 68,6 @@ private fun KaSession.getTypeReferenceFromPossiblyRecursive(
paramTrace
)
is KaCapturedType -> throw NotImplementedError()
is KaIntegerLiteralType -> throw NotImplementedError()
is KaIntersectionType -> throw NotImplementedError()
}.let {
if (type.isMarkedNullable) Nullable(it) else it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 10,6 @@ import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.KaStarTypeProjection
import org.jetbrains.kotlin.analysis.api.KaTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.KaTypeProjection
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.types.*
Expand All @@ -38,12 35,12 @@ internal class TypeTranslator(
}

private fun KaSession.toBoundFromTypeAliased(classType: KaNonErrorClassType): TypeAliased {
val classSymbol = classType.classSymbol
val classSymbol = classType.symbol
return if (classSymbol is KaTypeAliasSymbol)
TypeAliased(
typeAlias = GenericTypeConstructor(
dri = getDRIFromNonErrorClassType(classType),
projections = classType.ownTypeArguments.map { toProjection(it) }),
projections = classType.typeArguments.map { toProjection(it) }),
inner = toBoundFrom(classType.fullyExpandedType),
extra = PropertyContainer.withAll(
getDokkaAnnotationsFrom(classType)?.toSourceSetDependent()?.toAnnotations()
Expand All @@ -55,7 52,7 @@ internal class TypeTranslator(
private fun KaSession.toTypeConstructorFrom(classType: KaNonErrorClassType) =
GenericTypeConstructor(
dri = getDRIFromNonErrorClassType(classType),
projections = classType.ownTypeArguments.map { toProjection(it) },
projections = classType.typeArguments.map { toProjection(it) },
presentableName = classType.getPresentableName(),
extra = PropertyContainer.withAll(
getDokkaAnnotationsFrom(classType)?.toSourceSetDependent()?.toAnnotations()
Expand All @@ -65,7 62,7 @@ internal class TypeTranslator(
private fun KaSession.toFunctionalTypeConstructorFrom(functionalType: KaFunctionalType) =
FunctionalTypeConstructor(
dri = getDRIFromNonErrorClassType(functionalType),
projections = functionalType.ownTypeArguments.map { toProjection(it) },
projections = functionalType.typeArguments.map { toProjection(it) },
isExtensionFunction = functionalType.receiverType != null,
isSuspendable = functionalType.isSuspend,
presentableName = functionalType.getPresentableName(),
Expand All @@ -77,7 74,9 @@ internal class TypeTranslator(
fun KaSession.toBoundFrom(type: KaType): Bound =
when (type) {
is KaUsualClassType -> {
if (type.classSymbol is KaTypeAliasSymbol) toBoundFromTypeAliased(type)
// after KT-66996, [type] is an expanded type
val abbreviatedType = type.abbreviatedType
if (abbreviatedType != null) toBoundFromTypeAliased(abbreviatedType)
else toTypeConstructorFrom(type)
}

Expand All @@ -92,7 91,9 @@ internal class TypeTranslator(

is KaClassErrorType -> UnresolvedBound(type.toString())
is KaFunctionalType -> {
if (type.classSymbol is KaTypeAliasSymbol) toBoundFromTypeAliased(type)
// after KT-66996, [type] is an expanded type
val abbreviatedType = type.abbreviatedType
if (abbreviatedType != null) toBoundFromTypeAliased(abbreviatedType)
else toFunctionalTypeConstructorFrom(type)
}
is KaDynamicType -> Dynamic
Expand All @@ -110,7 111,6 @@ internal class TypeTranslator(

is KaTypeErrorType -> UnresolvedBound(type.toString())
is KaCapturedType -> throw NotImplementedError()
is KaIntegerLiteralType -> throw NotImplementedError()
is KaIntersectionType -> throw NotImplementedError()
}.let {
if (type.isMarkedNullable) Nullable(it) else it
Expand All @@ -135,7 135,7 @@ internal class TypeTranslator(

internal fun KaSession.toTypeConstructorWithKindFrom(type: KaType): TypeConstructorWithKind = when (type) {
is KaUsualClassType ->
when (val classSymbol = type.classSymbol) {
when (val classSymbol = type.symbol) {
is KaNamedClassOrObjectSymbol -> TypeConstructorWithKind(
toTypeConstructorFrom(type),
classSymbol.classKind.toDokkaClassKind()
Expand Down Expand Up @@ -173,7 173,6 @@ internal class TypeTranslator(
is KaCapturedType -> throw NotImplementedError()
is KaDynamicType -> throw NotImplementedError()
is KaFlexibleType -> throw NotImplementedError()
is KaIntegerLiteralType -> throw NotImplementedError()
is KaIntersectionType -> throw NotImplementedError()
is KaTypeParameterType -> throw NotImplementedError()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 8,14 @@ import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.driOrNull
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.*
import utils.AbstractModelTest
import utils.OnlyDescriptors
import kotlin.test.Test
import kotlin.test.assertTrue

class TypesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "types") {

@Test
@OnlyDescriptors("#3649")
fun `type with typealias to functional type with parameter`() {
inlineModelTest(
"""
Expand Down Expand Up @@ -42,6 44,7 @@ class TypesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "types")
}

@Test
@OnlyDescriptors("#3649")
fun `type with typealias to functional type`() {
inlineModelTest(
"""
Expand Down
Loading

0 comments on commit bb5a2b1

Please sign in to comment.