diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-11-10 11:46:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-10 11:46:54 +0100 |
commit | 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch) | |
tree | 1b915207b2b9f61951ddbf0ff2e687efd053d555 /subprojects/analysis-kotlin-descriptors | |
parent | a44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff) | |
download | dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.gz dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.bz2 dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.zip |
Restructure the project to utilize included builds (#3174)
* Refactor and simplify artifact publishing
* Update Gradle to 8.4
* Refactor and simplify convention plugins and build scripts
Fixes #3132
---------
Co-authored-by: Adam <897017+aSemy@users.noreply.github.com>
Co-authored-by: Oleg Yukhnevich <whyoleg@gmail.com>
Diffstat (limited to 'subprojects/analysis-kotlin-descriptors')
90 files changed, 0 insertions, 7317 deletions
diff --git a/subprojects/analysis-kotlin-descriptors/README.md b/subprojects/analysis-kotlin-descriptors/README.md deleted file mode 100644 index fbfd1c8b..00000000 --- a/subprojects/analysis-kotlin-descriptors/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Analysis: Kotlin descriptors - -An internal descriptor-based implementation for [analysis-kotlin-api](../analysis-kotlin-api), also known as K1 or -"the old compiler". - -Contains no stable public API and must not be used by anyone directly, only via [analysis-kotlin-api](../analysis-kotlin-api). - -Can be added as a runtime dependency by the runner. diff --git a/subprojects/analysis-kotlin-descriptors/api/analysis-kotlin-descriptors.api b/subprojects/analysis-kotlin-descriptors/api/analysis-kotlin-descriptors.api deleted file mode 100644 index e69de29b..00000000 --- a/subprojects/analysis-kotlin-descriptors/api/analysis-kotlin-descriptors.api +++ /dev/null diff --git a/subprojects/analysis-kotlin-descriptors/build.gradle.kts b/subprojects/analysis-kotlin-descriptors/build.gradle.kts deleted file mode 100644 index 9690ea6b..00000000 --- a/subprojects/analysis-kotlin-descriptors/build.gradle.kts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -import org.jetbrains.DokkaPublicationBuilder -import org.jetbrains.registerDokkaArtifactPublication - -plugins { - id("org.jetbrains.conventions.kotlin-jvm") - id("org.jetbrains.conventions.maven-publish") - id("com.github.johnrengelman.shadow") -} - -dependencies { - // to override some interfaces (JvmAnnotationEnumFieldValue, JvmAnnotationConstantValue) from compiler since thet are empty there - // should be `api` since we already have it in :analysis-java-psi - api(libs.intellij.java.psi.api) { - isTransitive = false - } - implementation(projects.subprojects.analysisKotlinApi) - implementation(projects.subprojects.analysisKotlinDescriptors.compiler) - implementation(projects.subprojects.analysisKotlinDescriptors.ide) -} - -tasks { - // There are several reasons for shadowing all dependencies in one place: - // 1. Some of the artifacts Dokka depends on, like com.jetbrains.intellij.java:java-psi, are not - // published to Maven Central, so the users would need to add custom repositories to their build scripts. - // 2. There are many intertwining transitive dependencies of different versions, as well as direct copy-paste, - // that can lead to runtime errors due to classpath conflicts, so it's best to let Gradle take care of - // dependency resolution, and then pack everything into a single jar in a single place that can be tuned. - // 3. The compiler and ide modules are internal details that are likely to change, so packing everything into - // a single jar provides some stability for the CLI users, while not exposing too many internals. Publishing - // the compiler, ide and other subprojects separately would make it difficult to refactor the project structure. - shadowJar { - val dokka_version: String by project - - // cannot be named exactly like the artifact (i.e analysis-kotlin-descriptors-VER.jar), - // otherwise leads to obscure test failures when run via CLI, but not via IJ - archiveFileName.set("analysis-kotlin-descriptors-all-$dokka_version.jar") - archiveClassifier.set("") - - // service files are merged to make sure all Dokka plugins - // from the dependencies are loaded, and not just a single one. - mergeServiceFiles() - } -} - -registerDokkaArtifactPublication("analysisKotlinDescriptors") { - artifactId = "analysis-kotlin-descriptors" - component = DokkaPublicationBuilder.Component.Shadow -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/README.md b/subprojects/analysis-kotlin-descriptors/compiler/README.md deleted file mode 100644 index 5676fbf2..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Descriptors: compiler - -An internal module that encapsulates external compiler (`org.jetbrains.kotlin:kotlin-compiler`) dependencies. - -Parses Kotlin sources. - -Exists primarily to make sure that unreliable and coupled external dependencies are somewhat abstracted away, -otherwise everything gets tangled together and breaking changes in such dependencies become very -difficult to resolve. diff --git a/subprojects/analysis-kotlin-descriptors/compiler/api/compiler.api b/subprojects/analysis-kotlin-descriptors/compiler/api/compiler.api deleted file mode 100644 index 373ec268..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/api/compiler.api +++ /dev/null @@ -1,126 +0,0 @@ -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator { - public abstract fun create (Lcom/intellij/mock/MockProject;Lorg/jetbrains/kotlin/descriptors/ModuleDescriptor;Lorg/jetbrains/kotlin/analyzer/ResolverForModule;Lorg/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment;)Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext; -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin : org/jetbrains/dokka/plugability/DokkaPlugin { - public fun <init> ()V - public final fun getAnalysisContextCreator ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; - public final fun getCompilerExtensionPointProvider ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; - public final fun getDescriptorFinder ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; - public final fun getKdocFinder ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; - public final fun getKlibService ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; - public final fun getKotlinAnalysis ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; - public final fun getKotlinSampleProviderFactory ()Lorg/jetbrains/dokka/plugability/Extension; - public final fun getMockApplicationHack ()Lorg/jetbrains/dokka/plugability/ExtensionPoint; -} - -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider { - public abstract fun get ()Ljava/util/List; -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider$CompilerExtensionPoint { - public fun <init> (Lorg/jetbrains/kotlin/extensions/ApplicationExtensionDescriptor;Ljava/util/List;)V - public final fun getExtensionDescriptor ()Lorg/jetbrains/kotlin/extensions/ApplicationExtensionDescriptor; - public final fun getExtensions ()Ljava/util/List; -} - -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder { - public abstract fun findDescriptor (Lorg/jetbrains/kotlin/psi/KtDeclaration;)Lorg/jetbrains/kotlin/descriptors/DeclarationDescriptor; -} - -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder { - public abstract fun find (Lorg/jetbrains/kotlin/descriptors/DeclarationDescriptor;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/kdoc/psi/impl/KDocTag; - public abstract fun findKDoc (Lorg/jetbrains/kotlin/psi/KtElement;)Lorg/jetbrains/kotlin/kdoc/psi/impl/KDocTag; - public abstract fun resolveKDocLink (Lorg/jetbrains/kotlin/descriptors/DeclarationDescriptor;Ljava/lang/String;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Z)Ljava/util/Collection; -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder$DefaultImpls { - public static synthetic fun find$default (Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder;Lorg/jetbrains/kotlin/descriptors/DeclarationDescriptor;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lorg/jetbrains/kotlin/kdoc/psi/impl/KDocTag; - public static synthetic fun resolveKDocLink$default (Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder;Lorg/jetbrains/kotlin/descriptors/DeclarationDescriptor;Ljava/lang/String;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;ZILjava/lang/Object;)Ljava/util/Collection; -} - -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService { - public abstract fun createPackageFragmentProvider (Lorg/jetbrains/kotlin/library/KotlinLibrary;Lorg/jetbrains/kotlin/storage/StorageManager;Lorg/jetbrains/kotlin/library/metadata/KlibMetadataModuleDescriptorFactory;Lorg/jetbrains/kotlin/config/LanguageVersionSettings;Lorg/jetbrains/kotlin/descriptors/ModuleDescriptor;Lorg/jetbrains/kotlin/incremental/components/LookupTracker;)Lorg/jetbrains/kotlin/descriptors/PackageFragmentProvider; - public abstract fun isAnalysisCompatible (Lorg/jetbrains/kotlin/library/KotlinLibrary;)Z -} - -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack { - public abstract fun hack (Lcom/intellij/mock/MockApplication;)V -} - -public abstract interface class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext : java/io/Closeable { - public abstract fun getEnvironment ()Lorg/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment; - public abstract fun getModuleDescriptor ()Lorg/jetbrains/kotlin/descriptors/ModuleDescriptor; - public abstract fun getProject ()Lcom/intellij/openapi/project/Project; - public abstract fun getResolveSession ()Lorg/jetbrains/kotlin/resolve/lazy/ResolveSession; -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment : com/intellij/openapi/Disposable { - public fun <init> (Lorg/jetbrains/kotlin/cli/common/messages/MessageCollector;Lorg/jetbrains/dokka/Platform;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack;Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService;)V - public fun dispose ()V -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DokkaAnalysisConfiguration : org/jetbrains/dokka/plugability/ConfigurableBlock { - public static final field Companion Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DokkaAnalysisConfiguration$Companion; - public static final field DEFAULT_IGNORE_COMMON_BUILT_INS Z - public fun <init> ()V - public fun <init> (Z)V - public synthetic fun <init> (ZILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Z - public final fun copy (Z)Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DokkaAnalysisConfiguration; - public static synthetic fun copy$default (Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DokkaAnalysisConfiguration;ZILjava/lang/Object;)Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DokkaAnalysisConfiguration; - public fun equals (Ljava/lang/Object;)Z - public final fun getIgnoreCommonBuiltIns ()Z - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DokkaAnalysisConfiguration$Companion { -} - -public abstract class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis : java/io/Closeable { - public fun <init> ()V - public fun <init> (Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis;)V - public synthetic fun <init> (Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun get (Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;)Lorg/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext; -} - -public class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/KotlinSampleProvider : org/jetbrains/dokka/analysis/kotlin/internal/SampleProvider { - public fun <init> (Lorg/jetbrains/dokka/plugability/DokkaContext;)V - public fun close ()V - public final fun getContext ()Lorg/jetbrains/dokka/plugability/DokkaContext; - public fun getSample (Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Ljava/lang/String;)Lorg/jetbrains/dokka/analysis/kotlin/internal/SampleProvider$SampleSnippet; - protected fun processBody (Lcom/intellij/psi/PsiElement;)Ljava/lang/String; - protected fun processImports (Lcom/intellij/psi/PsiElement;)Ljava/lang/String; -} - -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/KotlinSampleProviderFactory : org/jetbrains/dokka/analysis/kotlin/internal/SampleProviderFactory { - public fun <init> (Lorg/jetbrains/dokka/plugability/DokkaContext;)V - public fun build ()Lorg/jetbrains/dokka/analysis/kotlin/internal/SampleProvider; - public final fun getContext ()Lorg/jetbrains/dokka/plugability/DokkaContext; -} - -public final class org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl : com/intellij/core/CoreJavaFileManager, org/jetbrains/kotlin/resolve/jvm/KotlinCliJavaFileManager { - public static final field Companion Lorg/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl$Companion; - public fun <init> (Lcom/intellij/psi/PsiManager;)V - public fun findClass (Ljava/lang/String;Lcom/intellij/psi/search/GlobalSearchScope;)Lcom/intellij/psi/PsiClass; - public fun findClass (Lorg/jetbrains/kotlin/load/java/JavaClassFinder$Request;Lcom/intellij/psi/search/GlobalSearchScope;)Lorg/jetbrains/kotlin/load/java/structure/JavaClass; - public final fun findClass (Lorg/jetbrains/kotlin/name/ClassId;Lcom/intellij/psi/search/GlobalSearchScope;)Lorg/jetbrains/kotlin/load/java/structure/JavaClass; - public fun findClasses (Ljava/lang/String;Lcom/intellij/psi/search/GlobalSearchScope;)[Lcom/intellij/psi/PsiClass; - public fun findModules (Ljava/lang/String;Lcom/intellij/psi/search/GlobalSearchScope;)Ljava/util/Collection; - public fun findPackage (Ljava/lang/String;)Lcom/intellij/psi/PsiPackage; - public fun getNonTrivialPackagePrefixes ()Ljava/util/Collection; - public final fun initialize (Lorg/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex;Ljava/util/List;Lorg/jetbrains/kotlin/cli/jvm/index/SingleJavaFileRootsIndex;Z)V - public fun knownClassNamesInPackage (Lorg/jetbrains/kotlin/name/FqName;)Ljava/util/Set; -} - -public final class org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl$Companion { -} - -public final class org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl : org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex { - public fun <init> (Ljava/util/List;)V - public fun findClass (Lorg/jetbrains/kotlin/name/ClassId;Ljava/util/Set;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun getIndexedRoots ()Lkotlin/sequences/Sequence; - public fun traverseDirectoriesInPackage (Lorg/jetbrains/kotlin/name/FqName;Ljava/util/Set;Lkotlin/jvm/functions/Function2;)V -} - diff --git a/subprojects/analysis-kotlin-descriptors/compiler/build.gradle.kts b/subprojects/analysis-kotlin-descriptors/compiler/build.gradle.kts deleted file mode 100644 index d9e8dd75..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/build.gradle.kts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -plugins { - id("org.jetbrains.conventions.kotlin-jvm") -} - -dependencies { - compileOnly(projects.core) - compileOnly(projects.subprojects.analysisKotlinApi) - - api(libs.kotlin.compiler) - - implementation(projects.subprojects.analysisMarkdownJb) - implementation(projects.subprojects.analysisJavaPsi) - - testImplementation(kotlin("test")) - testImplementation(projects.core.contentMatcherTestUtils) - testImplementation(projects.core.testApi) - - // TODO [beresnev] get rid of it - compileOnly(libs.kotlinx.coroutines.core) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt deleted file mode 100644 index 67476a50..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import com.intellij.mock.MockProject -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisContext -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisEnvironment -import org.jetbrains.kotlin.analyzer.ResolverForModule -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.descriptors.ModuleDescriptor - -@InternalDokkaApi -public interface AnalysisContextCreator { - public fun create( - project: MockProject, - moduleDescriptor: ModuleDescriptor, - moduleResolver: ResolverForModule, - kotlinEnvironment: KotlinCoreEnvironment, - analysisEnvironment: AnalysisEnvironment, - ): AnalysisContext -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt deleted file mode 100644 index c59a43b2..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute -import com.intellij.psi.PsiAnnotation -import org.jetbrains.dokka.CoreExtensions -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.analysis.java.BreakingAbstractionKotlinLightMethodChecker -import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.DokkaAnalysisConfiguration -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.KotlinAnalysis -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.ProjectKotlinAnalysis -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.* -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentationReader -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java.* -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DefaultDescriptorToDocumentableTranslator -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.DefaultExternalDocumentablesProvider -import org.jetbrains.dokka.renderers.PostAction -import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.internal.SampleProviderFactory -import org.jetbrains.dokka.plugability.* -import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation - -@Suppress("unused") -@InternalDokkaApi -public class CompilerDescriptorAnalysisPlugin : DokkaPlugin() { - - @InternalDokkaApi - public val kdocFinder: ExtensionPoint<KDocFinder> by extensionPoint() - - @InternalDokkaApi - public val descriptorFinder: ExtensionPoint<DescriptorFinder> by extensionPoint() - - @InternalDokkaApi - public val klibService: ExtensionPoint<KLibService> by extensionPoint() - - @InternalDokkaApi - public val compilerExtensionPointProvider: ExtensionPoint<CompilerExtensionPointProvider> by extensionPoint() - - @InternalDokkaApi - public val mockApplicationHack: ExtensionPoint<MockApplicationHack> by extensionPoint() - - @InternalDokkaApi - public val analysisContextCreator: ExtensionPoint<AnalysisContextCreator> by extensionPoint() - - @InternalDokkaApi - public val kotlinAnalysis: ExtensionPoint<KotlinAnalysis> by extensionPoint() - - internal val documentableAnalyzerImpl by extending { - plugin<InternalKotlinAnalysisPlugin>().documentableSourceLanguageParser providing { CompilerDocumentableSourceLanguageParser() } - } - - internal val defaultKotlinAnalysis by extending { - @OptIn(DokkaPluginApiPreview::class) - kotlinAnalysis providing { ctx -> - val configuration = configuration<CompilerDescriptorAnalysisPlugin, DokkaAnalysisConfiguration>(ctx) - ?: DokkaAnalysisConfiguration() - ProjectKotlinAnalysis( - sourceSets = ctx.configuration.sourceSets, - context = ctx, - analysisConfiguration = configuration - ) - } - } - - internal val descriptorToDocumentableTranslator by extending { - CoreExtensions.sourceToDocumentableTranslator providing ::DefaultDescriptorToDocumentableTranslator - } - - - internal val descriptorFullClassHierarchyBuilder by extending { - plugin<InternalKotlinAnalysisPlugin>().fullClassHierarchyBuilder providing { DescriptorFullClassHierarchyBuilder() } - } - - /** - * StdLib has its own a sample provider - * So it should have a possibility to override this extension - */ - @InternalDokkaApi - public val kotlinSampleProviderFactory: Extension<SampleProviderFactory, *, *> by extending { - plugin<InternalKotlinAnalysisPlugin>().sampleProviderFactory providing ::KotlinSampleProviderFactory - } - - internal val descriptorSyntheticDocumentableDetector by extending { - plugin<InternalKotlinAnalysisPlugin>().syntheticDocumentableDetector providing { DescriptorSyntheticDocumentableDetector() } - } - - internal val moduleAndPackageDocumentationReader by extending { - plugin<InternalKotlinAnalysisPlugin>().moduleAndPackageDocumentationReader providing ::ModuleAndPackageDocumentationReader - } - - internal val kotlinToJavaMapper by extending { - plugin<InternalKotlinAnalysisPlugin>().kotlinToJavaService providing { DescriptorKotlinToJavaMapper() } - } - - internal val descriptorInheritanceBuilder by extending { - plugin<InternalKotlinAnalysisPlugin>().inheritanceBuilder providing { DescriptorInheritanceBuilder() } - } - - internal val defaultExternalDocumentablesProvider by extending { - plugin<InternalKotlinAnalysisPlugin>().externalDocumentablesProvider providing ::DefaultExternalDocumentablesProvider - } - - private val javaAnalysisPlugin by lazy { plugin<JavaAnalysisPlugin>() } - - internal val projectProvider by extending { - javaAnalysisPlugin.projectProvider providing { KotlinAnalysisProjectProvider() } - } - - internal val sourceRootsExtractor by extending { - javaAnalysisPlugin.sourceRootsExtractor providing { KotlinAnalysisSourceRootsExtractor() } - } - - internal val kotlinDocCommentCreator by extending { - javaAnalysisPlugin.docCommentCreators providing { - DescriptorKotlinDocCommentCreator(querySingle { kdocFinder }, querySingle { descriptorFinder }) - } - } - - internal val kotlinDocCommentParser by extending { - javaAnalysisPlugin.docCommentParsers providing { context -> - DescriptorKotlinDocCommentParser( - context, - context.logger - ) - } - } - - internal val inheritDocTagProvider by extending { - javaAnalysisPlugin.inheritDocTagContentProviders providing ::KotlinInheritDocTagContentProvider - } - - internal val kotlinLightMethodChecker by extending { - javaAnalysisPlugin.kotlinLightMethodChecker providing { - object : BreakingAbstractionKotlinLightMethodChecker { - override fun isLightAnnotation(annotation: PsiAnnotation): Boolean { - return annotation is KtLightAbstractAnnotation - } - - override fun isLightAnnotationAttribute(attribute: JvmAnnotationAttribute): Boolean { - return attribute is KtLightAbstractAnnotation - } - } - } - } - - internal val disposeKotlinAnalysisPostAction by extending { - CoreExtensions.postActions with PostAction { querySingle { kotlinAnalysis }.close() } - } - - @OptIn(DokkaPluginApiPreview::class) - override fun pluginApiPreviewAcknowledgement(): PluginApiPreviewAcknowledgement = PluginApiPreviewAcknowledgement -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt deleted file mode 100644 index 2dbc242a..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.DescriptorDocumentableSource -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.WithSources -import org.jetbrains.dokka.analysis.kotlin.internal.DocumentableLanguage -import org.jetbrains.dokka.analysis.kotlin.internal.DocumentableSourceLanguageParser - -internal class CompilerDocumentableSourceLanguageParser : DocumentableSourceLanguageParser { - override fun getLanguage( - documentable: Documentable, - sourceSet: DokkaConfiguration.DokkaSourceSet, - ): DocumentableLanguage? { - val documentableSource = (documentable as? WithSources)?.sources?.get(sourceSet) ?: return null - return when (documentableSource) { - is PsiDocumentableSource -> DocumentableLanguage.JAVA - is DescriptorDocumentableSource -> DocumentableLanguage.KOTLIN - else -> error("Unknown language sources: ${documentableSource::class}") - } - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt deleted file mode 100644 index e42efe41..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor - -@InternalDokkaApi -public interface CompilerExtensionPointProvider { - public fun get(): List<CompilerExtensionPoint> - - public class CompilerExtensionPoint( - public val extensionDescriptor: ApplicationExtensionDescriptor<Any>, - public val extensions: List<Any> - ) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt deleted file mode 100644 index db06647d..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.psi.KtDeclaration - -@InternalDokkaApi -public interface DescriptorFinder { - public fun KtDeclaration.findDescriptor(): DeclarationDescriptor? -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt deleted file mode 100644 index e5367211..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils - -@InternalDokkaApi -public interface KDocFinder { - public fun KtElement.findKDoc(): KDocTag? - - public fun DeclarationDescriptor.find( - descriptorToPsi: (DeclarationDescriptorWithSource) -> PsiElement? = { - DescriptorToSourceUtils.descriptorToDeclaration( - it - ) - } - ): KDocTag? - - public fun resolveKDocLink( - fromDescriptor: DeclarationDescriptor, - qualifiedName: String, - sourceSet: DokkaConfiguration.DokkaSourceSet, - emptyBindingContext: Boolean = false - ): Collection<DeclarationDescriptor> -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt deleted file mode 100644 index fc173298..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.kotlin.library.metadata.KlibMetadataModuleDescriptorFactory -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.storage.StorageManager - -@InternalDokkaApi -public interface KLibService { - public fun KotlinLibrary.createPackageFragmentProvider( - storageManager: StorageManager, - metadataModuleDescriptorFactory: KlibMetadataModuleDescriptorFactory, - languageVersionSettings: LanguageVersionSettings, - moduleDescriptor: ModuleDescriptor, - lookupTracker: LookupTracker - ): PackageFragmentProvider? - - public fun isAnalysisCompatible(kotlinLibrary: KotlinLibrary): Boolean -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt deleted file mode 100644 index 39ca666b..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler - -import com.intellij.mock.MockApplication -import org.jetbrains.dokka.InternalDokkaApi - -@InternalDokkaApi -public interface MockApplicationHack { // ¯\_(ツ)_/¯ - public fun hack(mockApplication: MockApplication) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt deleted file mode 100644 index 8cf05053..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -internal typealias AbsolutePathString = String diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt deleted file mode 100644 index 917a86e7..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.openapi.project.Project -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.AnalysisContextCreator -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.DokkaPluginApiPreview -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.messages.MessageRenderer -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import java.io.Closeable -import java.io.File - -@OptIn(DokkaPluginApiPreview::class) -internal fun createAnalysisContext( - context: DokkaContext, - sourceSets: List<DokkaConfiguration.DokkaSourceSet>, - sourceSet: DokkaConfiguration.DokkaSourceSet, - analysisConfiguration: DokkaAnalysisConfiguration -): AnalysisContext { - val parentSourceSets = sourceSets.filter { it.sourceSetID in sourceSet.dependentSourceSets } - val classpath = sourceSet.classpath + parentSourceSets.flatMap { it.classpath } - val sources = sourceSet.sourceRoots + parentSourceSets.flatMap { it.sourceRoots } - - return createAnalysisContext( - context = context, - classpath = classpath, - sourceRoots = sources, - sourceSet = sourceSet, - analysisConfiguration = analysisConfiguration - ) -} - -@OptIn(DokkaPluginApiPreview::class) -internal fun createAnalysisContext( - context: DokkaContext, - classpath: List<File>, - sourceRoots: Set<File>, - sourceSet: DokkaConfiguration.DokkaSourceSet, - analysisConfiguration: DokkaAnalysisConfiguration -): AnalysisContext { - val analysisEnvironment = AnalysisEnvironment( - DokkaMessageCollector(context.logger), - sourceSet.analysisPlatform, - context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { mockApplicationHack }, - context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { klibService }, - ).apply { - if (analysisPlatform == Platform.jvm) { - configureJdkClasspathRoots() - } - addClasspath(classpath) - addSources(sourceRoots) - - loadLanguageVersionSettings(sourceSet.languageVersion, sourceSet.apiVersion) - } - - val environment = analysisEnvironment.createCoreEnvironment() - return analysisEnvironment.createResolutionFacade( - environment, - context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle<CompilerDescriptorAnalysisPlugin, AnalysisContextCreator> { analysisContextCreator }, - analysisConfiguration.ignoreCommonBuiltIns - ) -} - -internal class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { - override fun clear() { - seenErrors = false - } - - private var seenErrors = false - - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) { - if (severity == CompilerMessageSeverity.ERROR) { - seenErrors = true - } - logger.info(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) - } - - override fun hasErrors() = seenErrors -} - -@InternalDokkaApi -public interface AnalysisContext : Closeable { - public val environment: KotlinCoreEnvironment - public val resolveSession: ResolveSession - public val moduleDescriptor: ModuleDescriptor - public val project: Project -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt deleted file mode 100644 index 5a0fc396..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.core.CoreApplicationEnvironment -import com.intellij.mock.MockApplication -import com.intellij.mock.MockComponentManager -import com.intellij.mock.MockProject -import com.intellij.openapi.Disposable -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Disposer -import com.intellij.openapi.vfs.StandardFileSystems -import com.intellij.psi.PsiNameHelper -import com.intellij.psi.impl.PsiNameHelperImpl -import com.intellij.psi.impl.source.javadoc.JavadocManagerImpl -import com.intellij.psi.javadoc.CustomJavadocTagProvider -import com.intellij.psi.javadoc.JavadocManager -import com.intellij.psi.javadoc.JavadocTagInfo -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.AnalysisContextCreator -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KLibService -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.MockApplicationHack -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve.* -import org.jetbrains.kotlin.analyzer.* -import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters -import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer -import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices -import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory -import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.config.ContentRoot -import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot -import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM -import org.jetbrains.kotlin.cli.jvm.config.* -import org.jetbrains.kotlin.cli.jvm.index.JavaRoot -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.context.ProjectContext -import org.jetbrains.kotlin.context.withModule -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.js.config.JSConfigurationKeys -import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices -import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.ToolingSingleFileKlibResolveStrategy -import org.jetbrains.kotlin.library.resolveSingleFileKlib -import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.CommonPlatforms -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.platform.js.JsPlatforms -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms.unspecifiedJvmPlatform -import org.jetbrains.kotlin.platform.konan.NativePlatforms -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider -import org.jetbrains.kotlin.resolve.CompilerEnvironment -import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices -import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters -import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory -import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices -import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices -import org.jetbrains.kotlin.storage.LockBasedStorageManager -import java.io.File -import org.jetbrains.kotlin.konan.file.File as KFile - -internal const val JAR_SEPARATOR = "!/" - -/** - * Kotlin as a service entry point - * - * Configures environment, analyses files and provides facilities to perform code processing without emitting bytecode - * - * $messageCollector: required by compiler infrastructure and will receive all compiler messages - * $body: optional and can be used to configure environment without creating local variable - */ -@InternalDokkaApi -public class AnalysisEnvironment( - private val messageCollector: MessageCollector, - internal val analysisPlatform: Platform, - private val mockApplicationHack: MockApplicationHack, - private val kLibService: KLibService, -) : Disposable { - private val configuration = CompilerConfiguration() - - init { - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) - } - - internal fun createCoreEnvironment(): KotlinCoreEnvironment { - System.setProperty("idea.io.use.nio2", "true") - System.setProperty("idea.ignore.disabled.plugins", "true") - - val configFiles = when (analysisPlatform) { - Platform.jvm, Platform.common -> EnvironmentConfigFiles.JVM_CONFIG_FILES - Platform.native -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES - Platform.js, Platform.wasm -> EnvironmentConfigFiles.JS_CONFIG_FILES - } - - val environment = KotlinCoreEnvironment.createForProduction(this, configuration, configFiles) - val projectComponentManager = environment.project as MockComponentManager - - CoreApplicationEnvironment.registerExtensionPoint( - environment.project.extensionArea, - JavadocTagInfo.EP_NAME, JavadocTagInfo::class.java - ) - - @Suppress("DEPRECATION") - val extensionArea = Extensions.getRootArea() - - CoreApplicationEnvironment.registerExtensionPoint( - extensionArea, - CustomJavadocTagProvider.EP_NAME, CustomJavadocTagProvider::class.java - ) - - // TODO: figure out why compilation fails with unresolved `CoreApplicationEnvironment.registerApplicationService(...)` - // call, fix it appropriately - with(ApplicationManager.getApplication() as MockApplication) { - mockApplicationHack.hack(this) - } - - projectComponentManager.registerService( - JavadocManager::class.java, - JavadocManagerImpl(environment.project) - ) - - projectComponentManager.registerService( - PsiNameHelper::class.java, - PsiNameHelperImpl(environment.project) - ) - - projectComponentManager.registerService( - CustomJavadocTagProvider::class.java, - CustomJavadocTagProvider { emptyList() } - ) - - return environment - } - - private fun createSourceModuleSearchScope(project: Project, sourceFiles: List<KtFile>): GlobalSearchScope = - when (analysisPlatform) { - Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) - Platform.js, Platform.common, Platform.native, Platform.wasm -> GlobalSearchScope.filesScope( - project, - sourceFiles.map { it.virtualFile }.toSet() - ) - } - - internal fun createResolutionFacade( - environment: KotlinCoreEnvironment, - analysisContextCreator: AnalysisContextCreator, - ignoreCommonBuiltIns: Boolean = false - ): AnalysisContext { - val projectContext = ProjectContext(environment.project, "Dokka") - val sourceFiles = environment.getSourceFiles() - - val targetPlatform = when (analysisPlatform) { - Platform.js, Platform.wasm -> JsPlatforms.defaultJsPlatform - Platform.common -> CommonPlatforms.defaultCommonPlatform - Platform.native -> NativePlatforms.unspecifiedNativePlatform - Platform.jvm -> JvmPlatforms.defaultJvmPlatform - } - - val kotlinLibraries: Map<AbsolutePathString, KotlinLibrary> = resolveKotlinLibraries() - - val commonDependencyContainer = if (analysisPlatform == Platform.common) DokkaKlibMetadataCommonDependencyContainer( - kotlinLibraries.values.toList(), - environment.configuration, - LockBasedStorageManager("DokkaKlibMetadata") - ) else null - - val extraModuleDependencies = kotlinLibraries.values.registerLibraries() + commonDependencyContainer?.moduleInfos.orEmpty() - - val library = object : LibraryModuleInfo { - override val analyzerServices: PlatformDependentAnalyzerServices = - analysisPlatform.analyzerServices() - override val name: Name = Name.special("<library>") - override val platform: TargetPlatform = targetPlatform - override fun dependencies(): List<ModuleInfo> = listOf(this) - override fun getLibraryRoots(): Collection<String> = classpath - .map { libraryFile -> libraryFile.absolutePath } - .filter { path -> path !in kotlinLibraries } - } - - val module = object : ModuleInfo { - override val analyzerServices: PlatformDependentAnalyzerServices = - analysisPlatform.analyzerServices() - override val name: Name = Name.special("<module>") - override val platform: TargetPlatform = targetPlatform - override fun dependencies(): List<ModuleInfo> = - listOf(this, library) + extraModuleDependencies - - /** - * Only for common platform ignore BuiltIns for StdLib since it can cause a conflict - * between BuiltIns from a compiler and ones from source code. - */ - override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns { - return if (analysisPlatform == Platform.common && ignoreCommonBuiltIns) ModuleInfo.DependencyOnBuiltIns.NONE - else super.dependencyOnBuiltIns() - } - } - - val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) - val modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo> = { - when (it) { - library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project)) - is DokkaKlibLibraryInfo -> { - if (it.libraryRoot in kotlinLibraries) - ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - else null - } - is CommonKlibModuleInfo -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - else -> null - } ?: throw IllegalArgumentException("Unexpected module info") - } - - var builtIns: JvmBuiltIns? = null - - val resolverForProject = when (analysisPlatform) { - Platform.jvm -> { - builtIns = JvmBuiltIns( - projectContext.storageManager, - JvmBuiltIns.Kind.FROM_CLASS_LOADER - ) // TODO we should use FROM_DEPENDENCIES - createJvmResolverForProject( - projectContext, - module, - library, - modulesContent, - sourcesScope, - builtIns - ) - } - Platform.common -> createCommonResolverForProject( - projectContext, - module, - modulesContent, - environment, - commonDependencyContainer - ) - Platform.js, Platform.wasm -> createJsResolverForProject(projectContext, module, modulesContent) - Platform.native -> createNativeResolverForProject(projectContext, module, modulesContent) - - } - @Suppress("UNUSED_VARIABLE") // BEWARE!!!! IT's UNUSED, but without it some things don't work - val libraryModuleDescriptor = resolverForProject.descriptorForModule(library) - - val moduleDescriptor = resolverForProject.descriptorForModule(module) - builtIns?.initialize(moduleDescriptor, true) - - @Suppress("UNUSED_VARIABLE") // BEWARE!!!! IT's UNUSED, but without it some things don't work - val resolverForLibrary = resolverForProject.resolverForModule(library) // Required before module to initialize library properly - - val resolverForModule = resolverForProject.resolverForModule(module) - - return analysisContextCreator.create( - environment.project as MockProject, - moduleDescriptor, - resolverForModule, - environment, - this - ) - } - - private fun Platform.analyzerServices() = when (this) { - Platform.js, Platform.wasm -> JsPlatformAnalyzerServices - Platform.common -> CommonPlatformAnalyzerServices - Platform.native -> NativePlatformAnalyzerServices - Platform.jvm -> JvmPlatformAnalyzerServices - } - - private fun Collection<KotlinLibrary>.registerLibraries(): List<DokkaKlibLibraryInfo> { - if (analysisPlatform != Platform.native && analysisPlatform != Platform.js && analysisPlatform != Platform.wasm) return emptyList() - val dependencyResolver = DokkaKlibLibraryDependencyResolver() - val analyzerServices = analysisPlatform.analyzerServices() - - return map { kotlinLibrary -> - if (analysisPlatform == org.jetbrains.dokka.Platform.native) DokkaNativeKlibLibraryInfo( - kotlinLibrary, - analyzerServices, - dependencyResolver - ) - else DokkaJsKlibLibraryInfo(kotlinLibrary, analyzerServices, dependencyResolver) - } - } - - @OptIn(ExperimentalStdlibApi::class) - private fun resolveKotlinLibraries(): Map<AbsolutePathString, KotlinLibrary> { - return if (analysisPlatform == Platform.jvm) emptyMap() else buildMap { - classpath - .filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION } - .forEach { libraryFile -> - try { - val kotlinLibrary = resolveSingleFileKlib( - libraryFile = KFile(libraryFile.absolutePath), - strategy = ToolingSingleFileKlibResolveStrategy - ) - if (kLibService.isAnalysisCompatible(kotlinLibrary)) { - // exists, is KLIB, has compatible format - put( - libraryFile.absolutePath, - kotlinLibrary - ) - } - } catch (e: Throwable) { - configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - .report(CompilerMessageSeverity.WARNING, "Can not resolve KLIB. " + e.message) - } - } - } - } - - private fun createCommonResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>, - environment: KotlinCoreEnvironment, - dependencyContainer: CommonDependenciesContainer? - ): ResolverForProject<ModuleInfo> { - return object : AbstractResolverForProject<ModuleInfo>( - "Dokka", - projectContext, - modules = module.dependencies() - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = modulesContent(module) - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance - - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule = - CommonResolverForModuleFactory( - CommonAnalysisParameters( - metadataPartProviderFactory = { content -> - environment.createPackagePartProvider(content.moduleContentScope) - } - ), - CompilerEnvironment, - unspecifiedJvmPlatform, - true, - dependencyContainer - ).createResolverForModule( - moduleDescriptor = descriptor as ModuleDescriptorImpl, - moduleContext = projectContext.withModule(descriptor), - moduleContent = modulesContent(moduleInfo), - resolverForProject = this, - languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, - sealedInheritorsProvider = CliSealedClassInheritorsProvider, - resolveOptimizingOptions = null, - absentDescriptorHandlerClass = null - ) - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - private fun createJsResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo> - ): ResolverForProject<ModuleInfo> { - return object : AbstractResolverForProject<ModuleInfo>( - "Dokka", - projectContext, - modules = module.dependencies() - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = modulesContent(module) - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule = DokkaJsResolverForModuleFactory(CompilerEnvironment, kLibService).createResolverForModule( - moduleDescriptor = descriptor as ModuleDescriptorImpl, - moduleContext = projectContext.withModule(descriptor), - moduleContent = modulesContent(moduleInfo), - resolverForProject = this, - languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, - sealedInheritorsProvider = CliSealedClassInheritorsProvider, - resolveOptimizingOptions = null, - absentDescriptorHandlerClass = null - ) - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - private fun createNativeResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo> - ): ResolverForProject<ModuleInfo> { - return object : AbstractResolverForProject<ModuleInfo>( - "Dokka", - projectContext, - modules = module.dependencies() - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = modulesContent(module) - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule { - - return DokkaNativeResolverForModuleFactory(CompilerEnvironment, kLibService).createResolverForModule( - moduleDescriptor = descriptor as ModuleDescriptorImpl, - moduleContext = projectContext.withModule(descriptor), - moduleContent = modulesContent(moduleInfo), - resolverForProject = this, - languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, - sealedInheritorsProvider = CliSealedClassInheritorsProvider, - resolveOptimizingOptions = null, - absentDescriptorHandlerClass = null - ) - } - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - private fun createJvmResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - library: LibraryModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>, - sourcesScope: GlobalSearchScope, - builtIns: KotlinBuiltIns - ): ResolverForProject<ModuleInfo> { - val javaRoots = classpath - .mapNotNull { file -> - val rootFile = when (file.extension) { - "jar" -> StandardFileSystems.jar().findFileByPath("${file.absolutePath}$JAR_SEPARATOR") - else -> StandardFileSystems.local().findFileByPath(file.absolutePath) - } - rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) } - } - - return object : AbstractResolverForProject<ModuleInfo>( - "Dokka", - projectContext, - modules = listOf(module, library) - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = - when (module) { - library -> ModuleContent(module, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(module, emptyList(), sourcesScope) - else -> throw IllegalArgumentException("Unexpected module info") - } - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = builtIns - - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule = JvmResolverForModuleFactory( - JvmPlatformParameters(packagePartProviderFactory = { content -> - JvmPackagePartProvider( - configuration.languageVersionSettings, - content.moduleContentScope - ) - .apply { - addRoots(javaRoots, messageCollector) - } - }, moduleByJavaClass = { - val file = - (it as? BinaryJavaClass)?.virtualFile ?: (it as JavaClassImpl).psi.containingFile.virtualFile - if (file in sourcesScope) - module - else - library - }, resolverForReferencedModule = null, - useBuiltinsProviderForModule = { false }), - CompilerEnvironment, - unspecifiedJvmPlatform - ).createResolverForModule( - moduleDescriptor = descriptor as ModuleDescriptorImpl, - moduleContext = projectContext.withModule(descriptor), - moduleContent = modulesContent(moduleInfo), - resolverForProject = this, - languageVersionSettings = configuration.languageVersionSettings, - sealedInheritorsProvider = CliSealedClassInheritorsProvider, - resolveOptimizingOptions = null, - absentDescriptorHandlerClass = null - ) - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - internal fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) { - val languageVersion = LanguageVersion.fromVersionString(languageVersionString) ?: LanguageVersion.LATEST_STABLE - val apiVersion = - apiVersionString?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(languageVersion) - configuration.languageVersionSettings = LanguageVersionSettingsImpl( - languageVersion = languageVersion, - apiVersion = apiVersion, analysisFlags = hashMapOf( - // force to resolve light classes (lazily by default) - AnalysisFlags.eagerResolveOfLightClasses to true - ) - ) - } - - /** - * Classpath for this environment. - */ - private val classpath: List<File> - get() = configuration.jvmClasspathRoots + configuration.getList(JSConfigurationKeys.LIBRARIES) - .mapNotNull { File(it) } - - /** - * Adds list of paths to classpath. - * $paths: collection of files to add - */ - internal fun addClasspath(paths: List<File>) { - if (analysisPlatform == Platform.js || analysisPlatform == Platform.wasm) { - configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath }) - } else { - configuration.addJvmClasspathRoots(paths) - } - } - - // Set up JDK classpath roots explicitly because of https://github.com/JetBrains/kotlin/commit/f89765eb33dd95c8de33a919cca83651b326b246 - internal fun configureJdkClasspathRoots() { - val jdkHome = File(System.getProperty("java.home")) - if (!jdkHome.exists()) { - messageCollector.report(CompilerMessageSeverity.WARNING, "Set existed java.home to use JDK") - } - configuration.put(JVMConfigurationKeys.JDK_HOME, jdkHome) - configuration.configureJdkClasspathRoots() // only non-nodular JDK - } - /** - * Adds path to classpath. - * $path: path to add - */ - internal fun addClasspath(path: File) { - if (analysisPlatform == Platform.js || analysisPlatform == Platform.wasm) { - configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) - } else { - configuration.addJvmClasspathRoot(path) - } - } - - /** - * List of source roots for this environment. - */ - internal val sources: List<String> - get() = configuration.get(CLIConfigurationKeys.CONTENT_ROOTS) - ?.filterIsInstance<KotlinSourceRoot>() - ?.map { it.path } ?: emptyList() - - /** - * Adds list of paths to source roots. - * $list: collection of files to add - */ - internal fun addSources(sourceDirectories: Iterable<File>) { - sourceDirectories.forEach { directory -> - configuration.addKotlinSourceRoot(directory.path) - if (directory.isDirectory || directory.extension == "java") { - configuration.addJavaSourceRoot(directory) - } - } - } - - internal fun addRoots(list: List<ContentRoot>) { - configuration.addAll(CLIConfigurationKeys.CONTENT_ROOTS, list) - } - - /** - * Disposes the environment and frees all associated resources. - */ - override fun dispose() { - Disposer.dispose(this) - } - -} - - diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/CallableFactory.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/CallableFactory.kt deleted file mode 100644 index 068b4730..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/CallableFactory.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.psi.PsiField -import com.intellij.psi.PsiMethod -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.links.JavaClassReference -import org.jetbrains.dokka.links.TypeReference -import org.jetbrains.kotlin.descriptors.CallableDescriptor - -internal fun Callable.Companion.from(descriptor: CallableDescriptor, name: String? = null) = with(descriptor) { - Callable( - name ?: descriptor.name.asString(), - extensionReceiverParameter?.let { TypeReference.from(it) }, - valueParameters.mapNotNull { TypeReference.from(it) } - ) -} - -internal fun Callable.Companion.from(psi: PsiMethod) = with(psi) { - Callable( - name, - null, - parameterList.parameters.map { param -> JavaClassReference(param.type.canonicalText) }) -} - -internal fun Callable.Companion.from(psi: PsiField): Callable { - return Callable( - name = psi.name, - receiver = null, - params = emptyList() - ) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRIFactory.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRIFactory.kt deleted file mode 100644 index e2deaa8c..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRIFactory.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.psi.* -import org.jetbrains.dokka.links.* -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull - -internal fun DRI.Companion.from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run { - val parameter = firstIsInstanceOrNull<ValueParameterDescriptor>() - val callable = parameter?.containingDeclaration ?: firstIsInstanceOrNull<CallableDescriptor>() - - DRI( - packageName = firstIsInstanceOrNull<PackageFragmentDescriptor>()?.fqName?.asString() ?: "", - classNames = (filterIsInstance<ClassDescriptor>() + filterIsInstance<TypeAliasDescriptor>()).toList() - .takeIf { it.isNotEmpty() } - ?.asReversed() - ?.joinToString(separator = ".") { it.name.asString() }, - callable = callable?.let { Callable.from(it) }, - target = DriTarget.from(parameter ?: descriptor), - extra = if (descriptor is EnumEntrySyntheticClassDescriptor || (descriptor as? ClassDescriptor)?.kind == ClassKind.ENUM_ENTRY) - DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode() - else null - ) -} - -internal fun DRI.Companion.from(psi: PsiElement) = psi.parentsWithSelf.run { - val psiMethod = firstIsInstanceOrNull<PsiMethod>() - val psiField = firstIsInstanceOrNull<PsiField>() - val classes = filterIsInstance<PsiClass>().filterNot { it is PsiTypeParameter } - .toList() // We only want exact PsiClass types, not PsiTypeParameter subtype - val additionalClasses = if (psi is PsiEnumConstant) listOfNotNull(psiField?.name) else emptyList() - DRI( - packageName = classes.lastOrNull()?.qualifiedName?.substringBeforeLast('.', "") ?: "", - classNames = (additionalClasses + classes.mapNotNull { it.name }).takeIf { it.isNotEmpty() } - ?.asReversed()?.joinToString("."), - // The fallback strategy test whether psi is not `PsiEnumConstant`. The reason behind this is that - // we need unified DRI for both Java and Kotlin enums, so we can link them properly and treat them alike. - // To achieve that, we append enum name to classNames list and leave the callable part set to null. For Kotlin enums - // it is by default, while for Java enums we have to explicitly test for that in this `takeUnless` condition. - callable = psiMethod?.let { Callable.from(it) } ?: psiField?.takeUnless { psi is PsiEnumConstant }?.let { Callable.from(it) }, - target = DriTarget.from(psi), - extra = if (psi is PsiEnumConstant) - DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode() - else null - ) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRITargetFactory.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRITargetFactory.kt deleted file mode 100644 index f9d01ceb..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRITargetFactory.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiParameter -import com.intellij.psi.PsiTypeParameter -import org.jetbrains.dokka.links.DriTarget -import org.jetbrains.dokka.links.PointingToCallableParameters -import org.jetbrains.dokka.links.PointingToDeclaration -import org.jetbrains.dokka.links.PointingToGenericParameters -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull - -internal fun DriTarget.Companion.from(descriptor: DeclarationDescriptor): DriTarget = descriptor.parentsWithSelf.run { - return when (descriptor) { - is TypeParameterDescriptor -> PointingToGenericParameters(descriptor.index) - is ValueParameterDescriptor -> PointingToCallableParameters(descriptor.index) - else -> { - val callable = firstIsInstanceOrNull<CallableDescriptor>() - val params = - callable?.let { listOfNotNull(it.extensionReceiverParameter) + it.valueParameters }.orEmpty() - val parameterDescriptor = firstIsInstanceOrNull<ParameterDescriptor>() - - parameterDescriptor?.let { PointingToCallableParameters(params.indexOf(it)) } - ?: PointingToDeclaration - } - } -} - - -internal fun DriTarget.Companion.from(psi: PsiElement): DriTarget = psi.parentsWithSelf.run { - return when (psi) { - is PsiTypeParameter -> PointingToGenericParameters(psi.index) - else -> firstIsInstanceOrNull<PsiParameter>()?.let { - val callable = firstIsInstanceOrNull<PsiMethod>() - val params = (callable?.parameterList?.parameters).orEmpty() - PointingToCallableParameters(params.indexOf(it)) - } ?: PointingToDeclaration - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/Documentable.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/Documentable.kt deleted file mode 100644 index ad5eb048..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/Documentable.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.psi.PsiDocumentManager -import org.jetbrains.dokka.model.DocumentableSource -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.load.kotlin.toSourceElement -import org.jetbrains.kotlin.resolve.source.getPsi - -internal class DescriptorDocumentableSource(val descriptor: DeclarationDescriptor) : DocumentableSource { - override val path = descriptor.toSourceElement.containingFile.toString() - - override fun computeLineNumber(): Int? { - return (this.descriptor as DeclarationDescriptorWithSource) - .source.getPsi() - ?.let { - val range = it.node?.findChildByType(KtTokens.IDENTIFIER)?.textRange ?: it.textRange - val doc = PsiDocumentManager.getInstance(it.project).getDocument(it.containingFile) - // IJ uses 0-based line-numbers; external source browsers use 1-based - doc?.getLineNumber(range.startOffset)?.plus(1) - } - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/JvmDependenciesIndexImpl.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/JvmDependenciesIndexImpl.kt deleted file mode 100644 index da18a952..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/JvmDependenciesIndexImpl.kt +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -/** - * DO NOT MOVE IT - * This is a hack for https://github.com/Kotlin/dokka/issues/1599 - * - * Copy-pasted from 1.9.20-Beta-1 - * Can be removed for Kotlin compiler 1.9.20 and later - * - * It makes this class threadsafe for Dokka - */ -@file:Suppress("PackageDirectoryMismatch") -package org.jetbrains.kotlin.cli.jvm.index - -import com.intellij.ide.highlighter.JavaClassFileType -import com.intellij.ide.highlighter.JavaFileType -import com.intellij.openapi.vfs.VfsUtilCore -import com.intellij.openapi.vfs.VirtualFile -import gnu.trove.THashMap -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import java.util.* -import java.util.concurrent.locks.ReentrantLock -import kotlin.concurrent.withLock - -// speeds up finding files/classes in classpath/java source roots -// TODO: KT-58327 needs to be adapted/removed if we want compiler to be multithreaded -// the main idea of this class is for each package to store roots which contains it to avoid excessive file system traversal -public class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex { - private val lock = ReentrantLock() - - //these fields are computed based on _roots passed to constructor which are filled in later - private val roots: List<JavaRoot> by lazy { _roots.toList() } - - private val maxIndex: Int - get() = roots.size - - // each "Cache" object corresponds to a package - private class Cache { - private val innerPackageCaches = HashMap<String, Cache>() - - operator fun get(name: String) = innerPackageCaches.getOrPut(name, ::Cache) - - // indices of roots that are known to contain this package - // if this list contains [1, 3, 5] then roots with indices 1, 3 and 5 are known to contain this package, 2 and 4 are known not to (no information about roots 6 or higher) - // if this list contains maxIndex that means that all roots containing this package are known - @Suppress("DEPRECATION") // TODO: fix deprecation - val rootIndices = com.intellij.util.containers.IntArrayList(2) - } - - // root "Cache" object corresponds to DefaultPackage which exists in every root. Roots with non-default fqname are also listed here but - // they will be ignored on requests with invalid fqname prefix. - private val rootCache: Cache by lazy { - Cache().apply { - roots.indices.forEach(rootIndices::add) - rootIndices.add(maxIndex) - rootIndices.trimToSize() - } - } - - // holds the request and the result last time we searched for class - // helps improve several scenarios, LazyJavaResolverContext.findClassInJava being the most important - private var lastClassSearch: Pair<FindClassRequest, SearchResult>? = null - - override val indexedRoots: Sequence<JavaRoot> by lazy { roots.asSequence() } - - private val packageCache: Array<out MutableMap<String, VirtualFile?>> by lazy { - Array(roots.size) { THashMap<String, VirtualFile?>() } - } - - override fun traverseDirectoriesInPackage( - packageFqName: FqName, - acceptedRootTypes: Set<JavaRoot.RootType>, - continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean - ) { - lock.withLock { - search(TraverseRequest(packageFqName, acceptedRootTypes)) { dir, rootType -> - if (continueSearch(dir, rootType)) null else Unit - } - } - } - - // findClassGivenDirectory MUST check whether the class with this classId exists in given package - override fun <T : Any> findClass( - classId: ClassId, - acceptedRootTypes: Set<JavaRoot.RootType>, - findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? - ): T? { - lock.withLock { - // TODO: KT-58327 probably should be changed to thread local to fix fast-path - // make a decision based on information saved from last class search - if (lastClassSearch?.first?.classId != classId) { - return search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory) - } - - val (cachedRequest, cachedResult) = lastClassSearch!! - return when (cachedResult) { - is SearchResult.NotFound -> { - val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes - if (limitedRootTypes.isEmpty()) { - null - } else { - search(FindClassRequest(classId, limitedRootTypes), findClassGivenDirectory) - } - } - is SearchResult.Found -> { - if (cachedRequest.acceptedRootTypes == acceptedRootTypes) { - findClassGivenDirectory(cachedResult.packageDirectory, cachedResult.root.type) - } else { - search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory) - } - } - } - } - } - - private fun <T : Any> search(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> T?): T? { - // a list of package sub names, ["org", "jb", "kotlin"] - val packagesPath = request.packageFqName.pathSegments().map { it.identifierOrNullIfSpecial ?: return null } - // a list of caches corresponding to packages, [default, "org", "org.jb", "org.jb.kotlin"] - val caches = cachesPath(packagesPath) - - var processedRootsUpTo = -1 - // traverse caches starting from last, which contains most specific information - - // NOTE: indices manipulation instead of using caches.reversed() is here for performance reasons - for (cacheIndex in caches.lastIndex downTo 0) { - val cacheRootIndices = caches[cacheIndex].rootIndices - for (i in 0 until cacheRootIndices.size()) { - val rootIndex = cacheRootIndices[i] - if (rootIndex <= processedRootsUpTo) continue // roots with those indices have been processed by now - - val directoryInRoot = travelPath(rootIndex, request.packageFqName, packagesPath, cacheIndex, caches) ?: continue - val root = roots[rootIndex] - if (root.type in request.acceptedRootTypes) { - val result = handler(directoryInRoot, root.type) - if (result != null) { - if (request is FindClassRequest) { - lastClassSearch = Pair(request, SearchResult.Found(directoryInRoot, root)) - } - return result - } - } - } - processedRootsUpTo = if (cacheRootIndices.isEmpty) processedRootsUpTo else cacheRootIndices[cacheRootIndices.size() - 1] - } - - if (request is FindClassRequest) { - lastClassSearch = Pair(request, SearchResult.NotFound) - } - return null - } - - // try to find a target directory corresponding to package represented by packagesPath in a given root represented by index - // possibly filling "Cache" objects with new information - private fun travelPath( - rootIndex: Int, - packageFqName: FqName, - packagesPath: List<String>, - fillCachesAfter: Int, - cachesPath: List<Cache> - ): VirtualFile? { - if (rootIndex >= maxIndex) { - for (i in (fillCachesAfter + 1) until cachesPath.size) { - // we all know roots that contain this package by now - cachesPath[i].rootIndices.add(maxIndex) - cachesPath[i].rootIndices.trimToSize() - } - return null - } - - return packageCache[rootIndex].getOrPut(packageFqName.asString()) { - doTravelPath(rootIndex, packagesPath, fillCachesAfter, cachesPath) - } - } - - private fun doTravelPath(rootIndex: Int, packagesPath: List<String>, fillCachesAfter: Int, cachesPath: List<Cache>): VirtualFile? { - val pathRoot = roots[rootIndex] - val prefixPathSegments = pathRoot.prefixFqName?.pathSegments() - - var currentFile = pathRoot.file - - for (pathIndex in packagesPath.indices) { - val subPackageName = packagesPath[pathIndex] - if (prefixPathSegments != null && pathIndex < prefixPathSegments.size) { - // Traverse prefix first instead of traversing real directories - if (prefixPathSegments[pathIndex].identifier != subPackageName) { - return null - } - } else { - currentFile = currentFile.findChildPackage(subPackageName, pathRoot.type) ?: return null - } - - val correspondingCacheIndex = pathIndex + 1 - if (correspondingCacheIndex > fillCachesAfter) { - // subPackageName exists in this root - cachesPath[correspondingCacheIndex].rootIndices.add(rootIndex) - } - } - - return currentFile - } - - private fun VirtualFile.findChildPackage(subPackageName: String, rootType: JavaRoot.RootType): VirtualFile? { - val childDirectory = findChild(subPackageName) ?: return null - - val fileExtension = when (rootType) { - JavaRoot.RootType.BINARY -> JavaClassFileType.INSTANCE.defaultExtension - JavaRoot.RootType.BINARY_SIG -> "sig" - JavaRoot.RootType.SOURCE -> JavaFileType.INSTANCE.defaultExtension - } - - // If in addition to a directory "foo" there's a class file "foo.class" AND there are no classes anywhere in the directory "foo", - // then we ignore the directory and let the resolution choose the class "foo" instead. - if (findChild("$subPackageName.$fileExtension")?.isDirectory == false) { - if (VfsUtilCore.processFilesRecursively(childDirectory) { file -> file.extension != fileExtension }) { - return null - } - } - - return childDirectory - } - - private fun cachesPath(path: List<String>): List<Cache> { - val caches = ArrayList<Cache>(path.size + 1) - caches.add(rootCache) - var currentCache = rootCache - for (subPackageName in path) { - currentCache = currentCache[subPackageName] - caches.add(currentCache) - } - return caches - } - - private data class FindClassRequest(val classId: ClassId, override val acceptedRootTypes: Set<JavaRoot.RootType>) : SearchRequest { - override val packageFqName: FqName - get() = classId.packageFqName - } - - private data class TraverseRequest( - override val packageFqName: FqName, - override val acceptedRootTypes: Set<JavaRoot.RootType> - ) : SearchRequest - - private interface SearchRequest { - val packageFqName: FqName - val acceptedRootTypes: Set<JavaRoot.RootType> - } - - private sealed class SearchResult { - class Found(val packageDirectory: VirtualFile, val root: JavaRoot) : SearchResult() - - object NotFound : SearchResult() - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis.kt deleted file mode 100644 index 4e6f42c9..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.DokkaSourceSetID -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.model.SourceSetDependent -import org.jetbrains.dokka.plugability.ConfigurableBlock -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.DokkaPluginApiPreview -import java.io.Closeable - -@OptIn(DokkaPluginApiPreview::class) -@Suppress("FunctionName") -internal fun ProjectKotlinAnalysis( - sourceSets: List<DokkaSourceSet>, - context: DokkaContext, - analysisConfiguration: DokkaAnalysisConfiguration = DokkaAnalysisConfiguration() -): KotlinAnalysis { - val environments = sourceSets.associateWith { sourceSet -> - createAnalysisContext( - context = context, - sourceSets = sourceSets, - sourceSet = sourceSet, - analysisConfiguration = analysisConfiguration - ) - } - return EnvironmentKotlinAnalysis(environments) -} - -/** - * [projectKotlinAnalysis] needs to be closed separately - * Usually the analysis created for samples is short-lived and can be closed right after - * it's been used, there's no need to wait for [projectKotlinAnalysis] to be closed as it must be handled separately. - */ -@OptIn(DokkaPluginApiPreview::class) -@Suppress("FunctionName") -internal fun SamplesKotlinAnalysis( - sourceSets: List<DokkaSourceSet>, - context: DokkaContext, - projectKotlinAnalysis: KotlinAnalysis, - analysisConfiguration: DokkaAnalysisConfiguration = DokkaAnalysisConfiguration() -): KotlinAnalysis { - val environments = sourceSets - .filter { it.samples.isNotEmpty() } - .associateWith { sourceSet -> - createAnalysisContext( - context = context, - classpath = sourceSet.classpath, - sourceRoots = sourceSet.samples, - sourceSet = sourceSet, - analysisConfiguration = analysisConfiguration - ) - } - - return EnvironmentKotlinAnalysis(environments, projectKotlinAnalysis) -} -@DokkaPluginApiPreview -public data class DokkaAnalysisConfiguration( - /** - * Only for common platform ignore BuiltIns for StdLib since it can cause a conflict - * between BuiltIns from a compiler and ones from source code. - */ - val ignoreCommonBuiltIns: Boolean = DEFAULT_IGNORE_COMMON_BUILT_INS -): ConfigurableBlock { - public companion object { - public const val DEFAULT_IGNORE_COMMON_BUILT_INS: Boolean = false - } -} - -/** - * First child delegation. It does not close [parent]. - */ -@InternalDokkaApi -public abstract class KotlinAnalysis( - private val parent: KotlinAnalysis? = null -) : Closeable { - - public operator fun get(key: DokkaSourceSet): AnalysisContext { - return get(key.sourceSetID) - } - - internal operator fun get(key: DokkaSourceSetID): AnalysisContext { - return find(key) - ?: parent?.get(key) - ?: throw IllegalStateException("Missing EnvironmentAndFacade for sourceSet $key") - } - - internal abstract fun find(sourceSetID: DokkaSourceSetID): AnalysisContext? -} - -internal open class EnvironmentKotlinAnalysis( - private val environments: SourceSetDependent<AnalysisContext>, - parent: KotlinAnalysis? = null, -) : KotlinAnalysis(parent = parent) { - - override fun find(sourceSetID: DokkaSourceSetID): AnalysisContext? = - environments.entries.firstOrNull { (sourceSet, _) -> sourceSet.sourceSetID == sourceSetID }?.value - - override fun close() { - environments.values.forEach(AnalysisContext::close) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinCliJavaFileManagerImpl.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinCliJavaFileManagerImpl.kt deleted file mode 100644 index 3d340672..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinCliJavaFileManagerImpl.kt +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -/** - * DO NOT MOVE IT - * This is a hack for https://github.com/Kotlin/dokka/issues/1599 - * - * Copy-pasted from Kotlin compiler - * - * It makes this class threadsafe (`topLevelClassesCache` and `binaryCache`) for Dokka - * - */ -@file:Suppress("PackageDirectoryMismatch") -package org.jetbrains.kotlin.cli.jvm.compiler - -import com.intellij.core.CoreJavaFileManager -import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.util.text.StringUtil -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.* -import com.intellij.psi.impl.file.PsiPackageImpl -import com.intellij.psi.search.GlobalSearchScope -import gnu.trove.THashMap -import gnu.trove.THashSet -import org.jetbrains.kotlin.cli.jvm.index.JavaRoot -import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex -import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex -import org.jetbrains.kotlin.load.java.JavaClassFinder -import org.jetbrains.kotlin.load.java.structure.JavaClass -import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryClassSignatureParser -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.ClassifierResolutionContext -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.isNotTopLevelClass -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager -import org.jetbrains.kotlin.util.PerformanceCounter - -// TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices -// Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage, -// which is indirectly invoked from PsiPackage.getSubPackages -public class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJavaFileManager(myPsiManager), KotlinCliJavaFileManager { - private val perfCounter = PerformanceCounter.create("Find Java class") - private lateinit var index: JvmDependenciesIndex - private lateinit var singleJavaFileRootsIndex: SingleJavaFileRootsIndex - private lateinit var packagePartProviders: List<JvmPackagePartProvider> - private val topLevelClassesCache: MutableMap<FqName, VirtualFile?> = THashMap() - private val allScope = GlobalSearchScope.allScope(myPsiManager.project) - private var usePsiClassFilesReading = false - - public fun initialize( - index: JvmDependenciesIndex, - packagePartProviders: List<JvmPackagePartProvider>, - singleJavaFileRootsIndex: SingleJavaFileRootsIndex, - usePsiClassFilesReading: Boolean - ) { - this.index = index - this.packagePartProviders = packagePartProviders - this.singleJavaFileRootsIndex = singleJavaFileRootsIndex - this.usePsiClassFilesReading = usePsiClassFilesReading - } - - private fun findPsiClass(classId: ClassId, searchScope: GlobalSearchScope): PsiClass? = perfCounter.time { - findVirtualFileForTopLevelClass(classId, searchScope)?.findPsiClassInVirtualFile(classId.relativeClassName.asString()) - } - - private fun findVirtualFileForTopLevelClass(classId: ClassId, searchScope: GlobalSearchScope): VirtualFile? { - val relativeClassName = classId.relativeClassName.asString() - synchronized(topLevelClassesCache) { - return topLevelClassesCache.getOrPut(classId.packageFqName.child(classId.relativeClassName.pathSegments().first())) { - index.findClass(classId) { dir, type -> - findVirtualFileGivenPackage(dir, relativeClassName, type) - } ?: singleJavaFileRootsIndex.findJavaSourceClass(classId) - }?.takeIf { it in searchScope } - } - } - - private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap() - private val signatureParsingComponent = BinaryClassSignatureParser() - - public fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? = findClass(JavaClassFinder.Request(classId), searchScope) - - override fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? { - val (classId, classFileContentFromRequest, outerClassFromRequest) = request - val virtualFile = findVirtualFileForTopLevelClass(classId, searchScope) ?: return null - - if (!usePsiClassFilesReading && (virtualFile.extension == "class" || virtualFile.extension == "sig")) { - synchronized(binaryCache){ - // We return all class files' names in the directory in knownClassNamesInPackage method, so one may request an inner class - return binaryCache.getOrPut(classId) { - // Note that currently we implicitly suppose that searchScope for binary classes is constant and we do not use it - // as a key in cache - // This is a true assumption by now since there are two search scopes in compiler: one for sources and another one for binary - // When it become wrong because we introduce the modules into CLI, it's worth to consider - // having different KotlinCliJavaFileManagerImpl's for different modules - - classId.outerClassId?.let { outerClassId -> - val outerClass = outerClassFromRequest ?: findClass(outerClassId, searchScope) - - return if (outerClass is BinaryJavaClass) - outerClass.findInnerClass(classId.shortClassName, classFileContentFromRequest) - else - outerClass?.findInnerClass(classId.shortClassName) - } - - // Here, we assume the class is top-level - val classContent = classFileContentFromRequest ?: virtualFile.contentsToByteArray() - if (virtualFile.nameWithoutExtension.contains("$") && isNotTopLevelClass(classContent)) return@getOrPut null - - val resolver = ClassifierResolutionContext { findClass(it, allScope) } - - BinaryJavaClass( - virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent, - outerClass = null, classContent = classContent - ) - } - } - } - - return virtualFile.findPsiClassInVirtualFile(classId.relativeClassName.asString())?.let(::JavaClassImpl) - } - - // this method is called from IDEA to resolve dependencies in Java code - // which supposedly shouldn't have errors so the dependencies exist in general - override fun findClass(qName: String, scope: GlobalSearchScope): PsiClass? { - // String cannot be reliably converted to ClassId because we don't know where the package name ends and class names begin. - // For example, if qName is "a.b.c.d.e", we should either look for a top level class "e" in the package "a.b.c.d", - // or, for example, for a nested class with the relative qualified name "c.d.e" in the package "a.b". - // Below, we start by looking for the top level class "e" in the package "a.b.c.d" first, then for the class "d.e" in the package - // "a.b.c", and so on, until we find something. Most classes are top level, so most of the times the search ends quickly - - forEachClassId(qName) { classId -> - findPsiClass(classId, scope)?.let { return it } - } - - return null - } - - private inline fun forEachClassId(fqName: String, block: (ClassId) -> Unit) { - var classId = fqName.toSafeTopLevelClassId() ?: return - - while (true) { - block(classId) - - val packageFqName = classId.packageFqName - if (packageFqName.isRoot) break - - classId = ClassId( - packageFqName.parent(), - FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()), - false - ) - } - } - - override fun findClasses(qName: String, scope: GlobalSearchScope): Array<PsiClass> = perfCounter.time { - val result = ArrayList<PsiClass>(1) - forEachClassId(qName) { classId -> - val relativeClassName = classId.relativeClassName.asString() - index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType -> - val psiClass = - findVirtualFileGivenPackage(dir, relativeClassName, rootType) - ?.takeIf { it in scope } - ?.findPsiClassInVirtualFile(relativeClassName) - if (psiClass != null) { - result.add(psiClass) - } - // traverse all - true - } - - singleJavaFileRootsIndex.findJavaSourceClass(classId) - ?.takeIf { it in scope } - ?.findPsiClassInVirtualFile(relativeClassName) - ?.let { result.add(it) } - - if (result.isNotEmpty()) { - return@time result.toTypedArray() - } - } - - PsiClass.EMPTY_ARRAY - } - - override fun findPackage(packageName: String): PsiPackage? { - var found = false - val packageFqName = packageName.toSafeFqName() ?: return null - index.traverseDirectoriesInPackage(packageFqName) { _, _ -> - found = true - //abort on first found - false - } - if (!found) { - found = packagePartProviders.any { it.findPackageParts(packageName).isNotEmpty() } - } - if (!found) { - found = singleJavaFileRootsIndex.findJavaSourceClasses(packageFqName).isNotEmpty() - } - return if (found) PsiPackageImpl(myPsiManager, packageName) else null - } - - private fun findVirtualFileGivenPackage( - packageDir: VirtualFile, - classNameWithInnerClasses: String, - rootType: JavaRoot.RootType - ): VirtualFile? { - val topLevelClassName = classNameWithInnerClasses.substringBefore('.') - - val vFile = when (rootType) { - JavaRoot.RootType.BINARY -> packageDir.findChild("$topLevelClassName.class") - JavaRoot.RootType.BINARY_SIG -> packageDir.findChild("$topLevelClassName.sig") - JavaRoot.RootType.SOURCE -> packageDir.findChild("$topLevelClassName.java") - } ?: return null - - if (!vFile.isValid) { - LOG.error("Invalid child of valid parent: ${vFile.path}; ${packageDir.isValid} path=${packageDir.path}") - return null - } - - return vFile - } - - private fun VirtualFile.findPsiClassInVirtualFile(classNameWithInnerClasses: String): PsiClass? { - val file = myPsiManager.findFile(this) as? PsiClassOwner ?: return null - return findClassInPsiFile(classNameWithInnerClasses, file) - } - - override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> { - val result = THashSet<String>() - index.traverseDirectoriesInPackage(packageFqName, continueSearch = { dir, _ -> - for (child in dir.children) { - if (child.extension == "class" || child.extension == "java" || child.extension == "sig") { - result.add(child.nameWithoutExtension) - } - } - - true - }) - - for (classId in singleJavaFileRootsIndex.findJavaSourceClasses(packageFqName)) { - assert(!classId.isNestedClass) { "ClassId of a single .java source class should not be nested: $classId" } - result.add(classId.shortClassName.asString()) - } - - return result - } - - override fun findModules(moduleName: String, scope: GlobalSearchScope): Collection<PsiJavaModule> { - // TODO - return emptySet() - } - - override fun getNonTrivialPackagePrefixes(): Collection<String> = emptyList() - - public companion object { - private val LOG = Logger.getInstance(KotlinCliJavaFileManagerImpl::class.java) - - private fun findClassInPsiFile(classNameWithInnerClassesDotSeparated: String, file: PsiClassOwner): PsiClass? { - for (topLevelClass in file.classes) { - val candidate = findClassByTopLevelClass(classNameWithInnerClassesDotSeparated, topLevelClass) - if (candidate != null) { - return candidate - } - } - return null - } - - private fun findClassByTopLevelClass(className: String, topLevelClass: PsiClass): PsiClass? { - if (className.indexOf('.') < 0) { - return if (className == topLevelClass.name) topLevelClass else null - } - - val segments = StringUtil.split(className, ".").iterator() - if (!segments.hasNext() || segments.next() != topLevelClass.name) { - return null - } - var curClass = topLevelClass - while (segments.hasNext()) { - val innerClassName = segments.next() - val innerClass = curClass.findInnerClassByName(innerClassName, false) ?: return null - curClass = innerClass - } - return curClass - } - } -} - -// a sad workaround to avoid throwing exception when called from inside IDEA code -private fun <T : Any> safely(compute: () -> T): T? = - try { - compute() - } catch (e: IllegalArgumentException) { - null - } catch (e: AssertionError) { - null - } - -private fun String.toSafeFqName(): FqName? = safely { FqName(this) } -private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) } diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/TypeReferenceFactory.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/TypeReferenceFactory.kt deleted file mode 100644 index b6929cbb..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/TypeReferenceFactory.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration - -import com.intellij.psi.PsiClass -import org.jetbrains.dokka.links.* -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeProjection -import org.jetbrains.kotlin.types.error.ErrorType -import org.jetbrains.kotlin.types.error.ErrorTypeConstructor -import org.jetbrains.kotlin.types.error.ErrorTypeKind - -internal fun TypeReference.Companion.from(d: ReceiverParameterDescriptor): TypeReference? = - when (d.value) { - is ExtensionReceiver -> fromPossiblyNullable(d.type, emptyList()) - else -> run { - println("Unknown value type for $d") - null - } - } - -internal fun TypeReference.Companion.from(d: ValueParameterDescriptor): TypeReference = - fromPossiblyNullable(d.type, emptyList()) - -internal fun TypeReference.Companion.from(@Suppress("UNUSED_PARAMETER") p: PsiClass) = TypeReference - -private fun TypeReference.Companion.fromPossiblyNullable(t: KotlinType, paramTrace: List<KotlinType>): TypeReference = - fromPossiblyRecursive(t, paramTrace).let { if (t.isMarkedNullable) Nullable(it) else it } - -private fun TypeReference.Companion.fromPossiblyRecursive(t: KotlinType, paramTrace: List<KotlinType>): TypeReference = - paramTrace.indexOfFirst { it.constructor == t.constructor && it.arguments == t.arguments } - .takeIf { it >= 0 } - ?.let(::RecursiveType) - ?: from(t, paramTrace) - -private fun TypeReference.Companion.from(t: KotlinType, paramTrace: List<KotlinType>): TypeReference { - if (t is ErrorType) { - val errorConstructor = t.constructor as? ErrorTypeConstructor - val presentableName = - if (errorConstructor?.kind == ErrorTypeKind.UNRESOLVED_TYPE && errorConstructor.parameters.isNotEmpty()) - errorConstructor.getParam(0) - else - t.constructor.toString() - return TypeConstructor(presentableName, t.arguments.map { fromProjection(it, paramTrace) }) - } - return when (val d = t.constructor.declarationDescriptor) { - is TypeParameterDescriptor -> TypeParam( - d.upperBounds.map { fromPossiblyNullable(it, paramTrace + t) } - ) - else -> TypeConstructor( - t.constructorName.orEmpty(), - t.arguments.map { fromProjection(it, paramTrace) } - ) - } -} - -private fun TypeReference.Companion.fromProjection(t: TypeProjection, paramTrace: List<KotlinType>): TypeReference = - if (t.isStarProjection) { - StarProjection - } else { - fromPossiblyNullable(t.type, paramTrace) - } - -private val KotlinType.constructorName - get() = constructor.declarationDescriptor?.fqNameSafe?.asString() diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/CommonKlibModuleInfo.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/CommonKlibModuleInfo.kt deleted file mode 100644 index 9f5ecc40..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/CommonKlibModuleInfo.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.CommonPlatforms -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices - -internal class CommonKlibModuleInfo( - override val name: Name, - val kotlinLibrary: KotlinLibrary, - private val dependOnModules: List<ModuleInfo> -) : ModuleInfo { - override fun dependencies(): List<ModuleInfo> = dependOnModules - - override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns = ModuleInfo.DependencyOnBuiltIns.LAST - - override val platform: TargetPlatform - get() = CommonPlatforms.defaultCommonPlatform - - override val analyzerServices: PlatformDependentAnalyzerServices - get() = CommonPlatformAnalyzerServices -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsKlibLibraryInfo.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsKlibLibraryInfo.kt deleted file mode 100644 index 480bc7cb..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsKlibLibraryInfo.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.shortName -import org.jetbrains.kotlin.library.uniqueName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.platform.js.JsPlatforms -import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices - -/** TODO: replace by [org.jetbrains.kotlin.caches.resolve.JsKlibLibraryInfo] after fix of KT-40734 */ -internal class DokkaJsKlibLibraryInfo( - override val kotlinLibrary: KotlinLibrary, - override val analyzerServices: PlatformDependentAnalyzerServices, - private val dependencyResolver: DokkaKlibLibraryDependencyResolver -) : DokkaKlibLibraryInfo() { - init { - dependencyResolver.registerLibrary(this) - } - - override val name: Name by lazy { - val libraryName = kotlinLibrary.shortName ?: kotlinLibrary.uniqueName - Name.special("<$libraryName>") - } - - override val platform: TargetPlatform = JsPlatforms.defaultJsPlatform - override fun dependencies(): List<ModuleInfo> = listOf(this) + dependencyResolver.resolveDependencies(this) - override fun getLibraryRoots(): Collection<String> = listOf(libraryRoot) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsResolverForModuleFactory.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsResolverForModuleFactory.kt deleted file mode 100644 index 98f9c64a..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsResolverForModuleFactory.kt +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KLibService -import org.jetbrains.kotlin.analyzer.* -import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.container.StorageComponentContainer -import org.jetbrains.kotlin.container.get -import org.jetbrains.kotlin.context.ModuleContext -import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.frontend.di.createContainerForLazyResolve -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices -import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories -import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider -import org.jetbrains.kotlin.resolve.TargetEnvironment -import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService -import org.jetbrains.kotlin.serialization.js.DynamicTypeDeserializer -import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil -import org.jetbrains.kotlin.serialization.js.createKotlinJavascriptPackageFragmentProvider -import org.jetbrains.kotlin.library.metadata.impl.KlibMetadataModuleDescriptorFactoryImpl -import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler -import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions -import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils -import java.io.File - -/** TODO: replace by [org.jetbrains.kotlin.caches.resolve.JsResolverForModuleFactory] after fix of KT-40734 */ -internal class DokkaJsResolverForModuleFactory( - private val targetEnvironment: TargetEnvironment, - private val kLibService: KLibService -) : ResolverForModuleFactory() { - companion object { - private val metadataFactories = KlibMetadataFactories({ DefaultBuiltIns.Instance }, DynamicTypeDeserializer) - - private val metadataModuleDescriptorFactory = KlibMetadataModuleDescriptorFactoryImpl( - metadataFactories.DefaultDescriptorFactory, - metadataFactories.DefaultPackageFragmentsFactory, - metadataFactories.flexibleTypeDeserializer, - ) - } - - override fun <M : ModuleInfo> createResolverForModule( - moduleDescriptor: ModuleDescriptorImpl, - moduleContext: ModuleContext, - moduleContent: ModuleContent<M>, - resolverForProject: ResolverForProject<M>, - languageVersionSettings: LanguageVersionSettings, - sealedInheritorsProvider: SealedClassInheritorsProvider, - resolveOptimizingOptions: OptimizingOptions?, - absentDescriptorHandlerClass: Class<out AbsentDescriptorHandler>? - ): ResolverForModule { - val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory( - moduleContext.project, - moduleContext.storageManager, - moduleContent.syntheticFiles, - moduleContent.moduleContentScope, - moduleContent.moduleInfo - ) - - val container = createContainerForLazyResolve( - moduleContext = moduleContext, - declarationProviderFactory = declarationProviderFactory, - bindingTrace = CodeAnalyzerInitializer.getInstance(moduleContext.project).createTrace(), // BindingTraceContext(/* allowSliceRewrite = */ true), - platform = moduleDescriptor.platform!!, - analyzerServices = JsPlatformAnalyzerServices, - targetEnvironment = targetEnvironment, - languageVersionSettings = languageVersionSettings, - absentDescriptorHandlerClass = absentDescriptorHandlerClass - ) - - var packageFragmentProvider = container.get<ResolveSession>().packageFragmentProvider - - val libraryProviders = createPackageFragmentProvider(moduleContent.moduleInfo, container, moduleContext, moduleDescriptor, languageVersionSettings) - - if (libraryProviders.isNotEmpty()) { - packageFragmentProvider = - CompositePackageFragmentProvider(listOf(packageFragmentProvider) + libraryProviders, "DokkaCompositePackageFragmentProvider") - } - return ResolverForModule(packageFragmentProvider, container) - } - - internal fun <M : ModuleInfo> createPackageFragmentProvider( - moduleInfo: M, - container: StorageComponentContainer, - moduleContext: ModuleContext, - moduleDescriptor: ModuleDescriptorImpl, - languageVersionSettings: LanguageVersionSettings - ): List<PackageFragmentProvider> = when (moduleInfo) { - is DokkaJsKlibLibraryInfo -> { - with(kLibService) { - listOfNotNull( - moduleInfo.kotlinLibrary - .createPackageFragmentProvider( - storageManager = moduleContext.storageManager, - metadataModuleDescriptorFactory = metadataModuleDescriptorFactory, - languageVersionSettings = languageVersionSettings, - moduleDescriptor = moduleDescriptor, - lookupTracker = LookupTracker.DO_NOTHING - ) - ) - } - } - is LibraryModuleInfo -> { - moduleInfo.getLibraryRoots() - .flatMap { - if (File(it).exists()) { - KotlinJavascriptMetadataUtils.loadMetadata(it) - } else { - // TODO can/should we warn a user about a problem in a library root? If so how? - emptyList() - } - } - .filter { it.version.isCompatibleWithCurrentCompilerVersion() } - .map { metadata -> - val (header, packageFragmentProtos) = - KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body, metadata.version) - createKotlinJavascriptPackageFragmentProvider( - moduleContext.storageManager, moduleDescriptor, header, packageFragmentProtos, metadata.version, - container.get(), LookupTracker.DO_NOTHING - ) - } - } - else -> emptyList() - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryDependencyResolver.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryDependencyResolver.kt deleted file mode 100644 index 8d275ad8..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryDependencyResolver.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.kotlin.library.uniqueName -import org.jetbrains.kotlin.library.unresolvedDependencies - -/** TODO: replace by [NativeKlibLibraryInfo] after fix of KT-40734 */ -internal class DokkaKlibLibraryDependencyResolver { - private val cachedDependencies = mutableMapOf</* libraryName */String, DokkaKlibLibraryInfo>() - - fun registerLibrary(libraryInfo: DokkaKlibLibraryInfo) { - cachedDependencies[libraryInfo.kotlinLibrary.uniqueName] = libraryInfo - } - - fun resolveDependencies(libraryInfo: DokkaKlibLibraryInfo): List<DokkaKlibLibraryInfo> { - return libraryInfo.kotlinLibrary.unresolvedDependencies.mapNotNull { cachedDependencies[it.path] } - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryInfo.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryInfo.kt deleted file mode 100644 index 28a674af..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryInfo.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.kotlin.analyzer.LibraryModuleInfo -import org.jetbrains.kotlin.library.KotlinLibrary - -internal abstract class DokkaKlibLibraryInfo : LibraryModuleInfo { - abstract val kotlinLibrary: KotlinLibrary - internal val libraryRoot: String - get() = kotlinLibrary.libraryFile.path -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibMetadataCommonDependencyContainer.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibMetadataCommonDependencyContainer.kt deleted file mode 100644 index 09f4e48a..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibMetadataCommonDependencyContainer.kt +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer -import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.languageVersionSettings -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer -import org.jetbrains.kotlin.library.metadata.parseModuleHeader -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration -import org.jetbrains.kotlin.library.metadata.impl.KlibMetadataModuleDescriptorFactoryImpl -import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.jetbrains.kotlin.storage.StorageManager - -/** - * Adapted from org.jetbrains.kotlin.cli.metadata.KlibMetadataDependencyContainer - */ -internal class DokkaKlibMetadataCommonDependencyContainer( - kotlinLibraries: List<KotlinLibrary>, - private val configuration: CompilerConfiguration, - private val storageManager: StorageManager -) : CommonDependenciesContainer { - - private val builtIns - get() = DefaultBuiltIns.Instance - - private val mutableDependenciesForAllModuleDescriptors = mutableListOf<ModuleDescriptorImpl>().apply { - add(builtIns.builtInsModule) - } - - private val mutableDependenciesForAllModules = mutableListOf<ModuleInfo>() - - private val moduleDescriptorsForKotlinLibraries: Map<KotlinLibrary, ModuleDescriptorImpl> = - kotlinLibraries.associateBy({ it }) { library -> - val moduleHeader = parseModuleHeader(library.moduleHeaderData) - val moduleName = Name.special(moduleHeader.moduleName) - val moduleOrigin = DeserializedKlibModuleOrigin(library) - MetadataFactories.DefaultDescriptorFactory.createDescriptor( - moduleName, storageManager, builtIns, moduleOrigin - ) - }.also { result -> - val resultValues = result.values - resultValues.forEach { module -> - module.setDependencies(mutableDependenciesForAllModuleDescriptors) - } - mutableDependenciesForAllModuleDescriptors.addAll(resultValues) - } - - private val moduleInfosImpl: List<CommonKlibModuleInfo> = mutableListOf<CommonKlibModuleInfo>().apply { - addAll( - moduleDescriptorsForKotlinLibraries.map { (kotlinLibrary, moduleDescriptor) -> - CommonKlibModuleInfo(moduleDescriptor.name, kotlinLibrary, mutableDependenciesForAllModules) - } - ) - mutableDependenciesForAllModules.addAll(this@apply) - } - - override val moduleInfos: List<ModuleInfo> get() = moduleInfosImpl - - /* not used in Dokka */ - override val friendModuleInfos: List<ModuleInfo> = emptyList() - - /* not used in Dokka */ - override val refinesModuleInfos: List<ModuleInfo> = emptyList() - - override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo): ModuleDescriptor { - if (moduleInfo !in moduleInfos) - error("Unknown module info $moduleInfo") - - // Ensure that the package fragment provider has been created and the module descriptor has been - // initialized with the package fragment provider: - packageFragmentProviderForModuleInfo(moduleInfo) - - return moduleDescriptorsForKotlinLibraries.getValue((moduleInfo as CommonKlibModuleInfo).kotlinLibrary) - } - - override fun registerDependencyForAllModules( - moduleInfo: ModuleInfo, - descriptorForModule: ModuleDescriptorImpl - ) { - mutableDependenciesForAllModules.add(moduleInfo) - mutableDependenciesForAllModuleDescriptors.add(descriptorForModule) - } - - override fun packageFragmentProviderForModuleInfo( - moduleInfo: ModuleInfo - ): PackageFragmentProvider? { - if (moduleInfo !in moduleInfos) - return null - return packageFragmentProviderForKotlinLibrary((moduleInfo as CommonKlibModuleInfo).kotlinLibrary) - } - - private val klibMetadataModuleDescriptorFactory by lazy { - KlibMetadataModuleDescriptorFactoryImpl( - MetadataFactories.DefaultDescriptorFactory, - MetadataFactories.DefaultPackageFragmentsFactory, - MetadataFactories.flexibleTypeDeserializer - ) - } - - private fun packageFragmentProviderForKotlinLibrary( - library: KotlinLibrary - ): PackageFragmentProvider { - val languageVersionSettings = configuration.languageVersionSettings - - val libraryModuleDescriptor = moduleDescriptorsForKotlinLibraries.getValue(library) - val packageFragmentNames = parseModuleHeader(library.moduleHeaderData).packageFragmentNameList - - return klibMetadataModuleDescriptorFactory.createPackageFragmentProvider( - library, - packageAccessHandler = null, - packageFragmentNames = packageFragmentNames, - storageManager = LockBasedStorageManager("KlibMetadataPackageFragmentProvider"), - moduleDescriptor = libraryModuleDescriptor, - configuration = CompilerDeserializationConfiguration(languageVersionSettings), - compositePackageFragmentAddend = null, - lookupTracker = LookupTracker.DO_NOTHING - ).also { - libraryModuleDescriptor.initialize(it) - } - } -} - -private val MetadataFactories = - KlibMetadataFactories( - { DefaultBuiltIns.Instance }, - NullFlexibleTypeDeserializer - ) diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeKlibLibraryInfo.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeKlibLibraryInfo.kt deleted file mode 100644 index 25cfb406..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeKlibLibraryInfo.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.descriptors.ModuleCapability -import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin -import org.jetbrains.kotlin.library.metadata.KlibModuleOrigin -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.isInterop -import org.jetbrains.kotlin.library.shortName -import org.jetbrains.kotlin.library.uniqueName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.platform.konan.NativePlatforms -import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion -import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices -import java.io.IOException - -/** TODO: replace by [NativeKlibLibraryInfo] after fix of KT-40734 */ -internal class DokkaNativeKlibLibraryInfo( - override val kotlinLibrary: KotlinLibrary, - override val analyzerServices: PlatformDependentAnalyzerServices, - private val dependencyResolver: DokkaKlibLibraryDependencyResolver -) : DokkaKlibLibraryInfo() { - init { - dependencyResolver.registerLibrary(this) - } - - override val name: Name by lazy { - val libraryName = kotlinLibrary.shortName ?: kotlinLibrary.uniqueName - Name.special("<$libraryName>") - } - - override val platform: TargetPlatform = NativePlatforms.unspecifiedNativePlatform - override fun dependencies(): List<ModuleInfo> = listOf(this) + dependencyResolver.resolveDependencies(this) - override fun getLibraryRoots(): Collection<String> = listOf(libraryRoot) - - override val capabilities: Map<ModuleCapability<*>, Any?> - get() { - val capabilities = super.capabilities.toMutableMap() - capabilities[KlibModuleOrigin.CAPABILITY] = DeserializedKlibModuleOrigin(kotlinLibrary) - capabilities[ImplicitIntegerCoercion.MODULE_CAPABILITY] = kotlinLibrary.safeRead(false) { isInterop } - return capabilities - } - - private fun <T> KotlinLibrary.safeRead(defaultValue: T, action: KotlinLibrary.() -> T) = try { - action() - } catch (_: IOException) { - defaultValue - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeResolverForModuleFactory.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeResolverForModuleFactory.kt deleted file mode 100644 index 6063ae1b..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeResolverForModuleFactory.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve - -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KLibService -import org.jetbrains.kotlin.analyzer.* -import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.container.get -import org.jetbrains.kotlin.context.ModuleContext -import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.frontend.di.createContainerForLazyResolve -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories -import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer -import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider -import org.jetbrains.kotlin.resolve.TargetEnvironment -import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices -import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler -import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService -import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions - -/** TODO: replace by [NativeResolverForModuleFactory] after fix of KT-40734 */ -internal class DokkaNativeResolverForModuleFactory( - private val targetEnvironment: TargetEnvironment, - private val kLibService: KLibService, -) : ResolverForModuleFactory() { - companion object { - private val metadataFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer) - } - - override fun <M : ModuleInfo> createResolverForModule( - moduleDescriptor: ModuleDescriptorImpl, - moduleContext: ModuleContext, - moduleContent: ModuleContent<M>, - resolverForProject: ResolverForProject<M>, - languageVersionSettings: LanguageVersionSettings, - sealedInheritorsProvider: SealedClassInheritorsProvider, - resolveOptimizingOptions: OptimizingOptions?, - absentDescriptorHandlerClass: Class<out AbsentDescriptorHandler>? - ): ResolverForModule { - - val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory( - moduleContext.project, - moduleContext.storageManager, - moduleContent.syntheticFiles, - moduleContent.moduleContentScope, - moduleContent.moduleInfo - ) - - val container = createContainerForLazyResolve( - moduleContext = moduleContext, - declarationProviderFactory = declarationProviderFactory, - bindingTrace = CodeAnalyzerInitializer.getInstance(moduleContext.project).createTrace(), - platform = moduleDescriptor.platform!!, - analyzerServices = NativePlatformAnalyzerServices, - targetEnvironment = targetEnvironment, - languageVersionSettings = languageVersionSettings, - absentDescriptorHandlerClass = absentDescriptorHandlerClass - ) - - var packageFragmentProvider = container.get<ResolveSession>().packageFragmentProvider - - val klibPackageFragmentProvider = with(kLibService) { - (moduleContent.moduleInfo as? DokkaNativeKlibLibraryInfo) - ?.kotlinLibrary - ?.createPackageFragmentProvider( - storageManager = moduleContext.storageManager, - metadataModuleDescriptorFactory = metadataFactories.DefaultDeserializedDescriptorFactory, - languageVersionSettings = languageVersionSettings, - moduleDescriptor = moduleDescriptor, - lookupTracker = LookupTracker.DO_NOTHING - ) - } - - if (klibPackageFragmentProvider != null) { - packageFragmentProvider = - CompositePackageFragmentProvider(listOf(packageFragmentProvider, klibPackageFragmentProvider), "DokkaCompositePackageFragmentProvider") - } - - return ResolverForModule(packageFragmentProvider, container) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorFullClassHierarchyBuilder.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorFullClassHierarchyBuilder.kt deleted file mode 100644 index 95295cf1..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorFullClassHierarchyBuilder.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl - -import com.intellij.psi.PsiClass -import kotlinx.coroutines.coroutineScope -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.DescriptorDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.from -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.utilities.parallelForEach -import org.jetbrains.dokka.analysis.kotlin.internal.ClassHierarchy -import org.jetbrains.dokka.analysis.kotlin.internal.FullClassHierarchyBuilder -import org.jetbrains.dokka.analysis.kotlin.internal.Supertypes -import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes -import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny -import java.util.concurrent.ConcurrentHashMap - -internal class DescriptorFullClassHierarchyBuilder : FullClassHierarchyBuilder { - - override suspend fun build(module: DModule): ClassHierarchy = coroutineScope { - val map = module.sourceSets.associateWith { ConcurrentHashMap<DRI, List<DRI>>() } - module.packages.parallelForEach { visitDocumentable(it, map) } - map - } - - private suspend fun collectSupertypesFromKotlinType( - driWithKType: Pair<DRI, KotlinType>, - supersMap: MutableMap<DRI, Supertypes> - ): Unit = coroutineScope { - val (dri, kotlinType) = driWithKType - val supertypes = kotlinType.immediateSupertypes().filterNot { it.isAnyOrNullableAny() } - val supertypesDriWithKType = supertypes.mapNotNull { supertype -> - supertype.constructor.declarationDescriptor?.let { - DRI.from(it) to supertype - } - } - - if (supersMap[dri] == null) { - // another thread can rewrite the same value, but it isn't a problem - supersMap[dri] = supertypesDriWithKType.map { it.first } - supertypesDriWithKType.parallelForEach { collectSupertypesFromKotlinType(it, supersMap) } - } - } - - private suspend fun collectSupertypesFromPsiClass( - driWithPsiClass: Pair<DRI, PsiClass>, - supersMap: MutableMap<DRI, Supertypes> - ): Unit = coroutineScope { - val (dri, psiClass) = driWithPsiClass - val supertypes = psiClass.superTypes.mapNotNull { it.resolve() } - .filterNot { it.qualifiedName == "java.lang.Object" } - val supertypesDriWithPsiClass = supertypes.map { DRI.from(it) to it } - - if (supersMap[dri] == null) { - // another thread can rewrite the same value, but it isn't a problem - supersMap[dri] = supertypesDriWithPsiClass.map { it.first } - supertypesDriWithPsiClass.parallelForEach { collectSupertypesFromPsiClass(it, supersMap) } - } - } - - private suspend fun visitDocumentable( - documentable: Documentable, - hierarchy: SourceSetDependent<MutableMap<DRI, List<DRI>>> - ): Unit = coroutineScope { - if (documentable is WithScope) { - documentable.classlikes.parallelForEach { visitDocumentable(it, hierarchy) } - } - if (documentable is DClasslike) { - // to build a full class graph, using supertypes from Documentable - // is not enough since it keeps only one level of hierarchy - documentable.sources.forEach { (sourceSet, source) -> - if (source is DescriptorDocumentableSource) { - val descriptor = source.descriptor as? ClassifierDescriptorWithTypeParameters ?: return@forEach // it can be typealias as well - val type = descriptor.defaultType - hierarchy[sourceSet]?.let { collectSupertypesFromKotlinType(documentable.dri to type, it) } - } else if (source is PsiDocumentableSource) { - val psi = source.psi as PsiClass - hierarchy[sourceSet]?.let { collectSupertypesFromPsiClass(documentable.dri to psi, it) } - } - } - } - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorInheritanceBuilder.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorInheritanceBuilder.kt deleted file mode 100644 index 46974dce..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorInheritanceBuilder.kt +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl - -import com.intellij.psi.PsiClass -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.DescriptorDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.from -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.WithSources -import org.jetbrains.dokka.analysis.kotlin.internal.InheritanceBuilder -import org.jetbrains.dokka.analysis.kotlin.internal.InheritanceNode -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.resolve.DescriptorUtils.getClassDescriptorForType - -internal class DescriptorInheritanceBuilder : InheritanceBuilder { - - override fun build(documentables: Map<DRI, Documentable>): List<InheritanceNode> { - val descriptorMap = getDescriptorMap(documentables) - - val psiInheritanceTree = - documentables.flatMap { (_, v) -> (v as? WithSources)?.sources?.values.orEmpty() } - .filterIsInstance<PsiDocumentableSource>().mapNotNull { it.psi as? PsiClass } - .flatMap(::gatherPsiClasses) - .flatMap { entry -> entry.second.map { it to entry.first } } - .let { - it + it.map { it.second to null } - } - .groupBy({ it.first }) { it.second } - .map { it.key to it.value.filterNotNull().distinct() } - .map { (k, v) -> - InheritanceNode( - DRI.from(k), - v.map { InheritanceNode(DRI.from(it)) }, - k.supers.filter { it.isInterface }.map { DRI.from(it) }, - k.isInterface - ) - - } - - val descriptorInheritanceTree = descriptorMap.flatMap { (_, v) -> - v.typeConstructor.supertypes - .map { getClassDescriptorForType(it) to v } - } - .let { - it + it.map { it.second to null } - } - .groupBy({ it.first }) { it.second } - .map { it.key to it.value.filterNotNull().distinct() } - .map { (k, v) -> - InheritanceNode( - DRI.from(k), - v.map { InheritanceNode(DRI.from(it)) }, - k.typeConstructor.supertypes.map { getClassDescriptorForType(it) } - .mapNotNull { cd -> cd.takeIf { it.kind == ClassKind.INTERFACE }?.let { DRI.from(it) } }, - isInterface = k.kind == ClassKind.INTERFACE - ) - } - - return psiInheritanceTree + descriptorInheritanceTree - } - - private fun gatherPsiClasses(psi: PsiClass): List<Pair<PsiClass, List<PsiClass>>> = psi.supers.toList().let { l -> - listOf(psi to l) + l.flatMap { gatherPsiClasses(it) } - } - - private fun getDescriptorMap(documentables: Map<DRI, Documentable>): Map<DRI, ClassDescriptor> { - val map: MutableMap<DRI, ClassDescriptor> = mutableMapOf() - documentables - .mapNotNull { (k, v) -> - v.descriptorForPlatform()?.let { k to it }?.also { (k, v) -> map[k] = v } - }.map { it.second }.forEach { gatherSupertypes(it, map) } - - return map.toMap() - } - - private fun gatherSupertypes(descriptor: ClassDescriptor, map: MutableMap<DRI, ClassDescriptor>) { - map.putIfAbsent(DRI.from(descriptor), descriptor) - descriptor.typeConstructor.supertypes.map { getClassDescriptorForType(it) } - .forEach { gatherSupertypes(it, map) } - } - - - private fun Documentable?.descriptorForPlatform(platform: Platform = Platform.jvm) = - (this as? WithSources).descriptorForPlatform(platform) - - private fun WithSources?.descriptorForPlatform(platform: Platform = Platform.jvm) = this?.let { - it.sources.entries.find { it.key.analysisPlatform == platform }?.value?.let { it as? DescriptorDocumentableSource }?.descriptor as? ClassDescriptor - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorKotlinToJavaMapper.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorKotlinToJavaMapper.kt deleted file mode 100644 index b022e0c3..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorKotlinToJavaMapper.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl - -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.PointingToDeclaration -import org.jetbrains.dokka.analysis.kotlin.internal.KotlinToJavaService -import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName - -internal class DescriptorKotlinToJavaMapper : KotlinToJavaService { - - override fun findAsJava(kotlinDri: DRI): DRI? { - return kotlinDri.partialFqName().mapToJava()?.toDRI(kotlinDri) - } - - private fun DRI.partialFqName() = packageName?.let { "$it." } + classNames - - private fun String.mapToJava(): ClassId? = - JavaToKotlinClassMap.mapKotlinToJava(FqName(this).toUnsafe()) - - private fun ClassId.toDRI(dri: DRI?): DRI = DRI( - packageName = packageFqName.asString(), - classNames = classNames(), - callable = dri?.callable,//?.asJava(), TODO: check this - extra = null, - target = PointingToDeclaration - ) - - private fun ClassId.classNames(): String = - shortClassName.identifier + (outerClassId?.classNames()?.let { ".$it" } ?: "") -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorSyntheticDocumentableDetector.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorSyntheticDocumentableDetector.kt deleted file mode 100644 index d6768eca..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorSyntheticDocumentableDetector.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.DescriptorDocumentableSource -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.WithSources -import org.jetbrains.dokka.analysis.kotlin.internal.SyntheticDocumentableDetector -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor - -internal class DescriptorSyntheticDocumentableDetector : SyntheticDocumentableDetector { - override fun isSynthetic(documentable: Documentable, sourceSet: DokkaConfiguration.DokkaSourceSet): Boolean { - return isFakeOverride(documentable, sourceSet) || isSynthesized(documentable, sourceSet) - } - - private fun isFakeOverride(documentable: Documentable, sourceSet: DokkaConfiguration.DokkaSourceSet): Boolean { - return callableMemberDescriptorOrNull(documentable, sourceSet)?.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE - } - - private fun isSynthesized(documentable: Documentable, sourceSet: DokkaConfiguration.DokkaSourceSet): Boolean { - return callableMemberDescriptorOrNull(documentable, sourceSet)?.kind == CallableMemberDescriptor.Kind.SYNTHESIZED - } - - private fun callableMemberDescriptorOrNull( - documentable: Documentable, sourceSet: DokkaConfiguration.DokkaSourceSet - ): CallableMemberDescriptor? { - if (documentable is WithSources) { - return documentable.sources[sourceSet] - .let { it as? DescriptorDocumentableSource }?.descriptor as? CallableMemberDescriptor - } - - return null - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/KotlinSampleProvider.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/KotlinSampleProvider.kt deleted file mode 100644 index 5199abf5..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/KotlinSampleProvider.kt +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl - -import com.intellij.psi.PsiElement -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.SamplesKotlinAnalysis -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.analysis.kotlin.internal.SampleProvider -import org.jetbrains.dokka.analysis.kotlin.internal.SampleProviderFactory -import org.jetbrains.dokka.plugability.DokkaPluginApiPreview -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtBlockExpression -import org.jetbrains.kotlin.psi.KtDeclarationWithBody -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.lazy.ResolveSession - -public class KotlinSampleProviderFactory( - public val context: DokkaContext -): SampleProviderFactory { - override fun build(): SampleProvider { - return KotlinSampleProvider(context) - } - -} -/** - * It's declared as open since StdLib has its own sample transformer - * with [processBody] and [processImports] - */ -@InternalDokkaApi -public open class KotlinSampleProvider( - public val context: DokkaContext -): SampleProvider { - private val kDocFinder: KDocFinder = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kdocFinder } - private val analysis = lazy { - /** - * Run from the thread of [Dispatchers.Default]. It can help to avoid a memory leaks in `ThreadLocal`s (that keep `URLCLassLoader`) - * since we shut down Dispatchers.Default at the end of each task (see [org.jetbrains.dokka.DokkaConfiguration.finalizeCoroutines]). - * Currently, all `ThreadLocal`s are in a compiler/IDE codebase. - */ - runBlocking(Dispatchers.Default) { - @OptIn(DokkaPluginApiPreview::class) - SamplesKotlinAnalysis( - sourceSets = context.configuration.sourceSets, - context = context, - projectKotlinAnalysis = context.plugin<CompilerDescriptorAnalysisPlugin>() - .querySingle { kotlinAnalysis } - ) - } - } - protected open fun processBody(psiElement: PsiElement): String { - val text = processSampleBody(psiElement).trim { it == '\n' || it == '\r' }.trimEnd() - val lines = text.split("\n") - val indent = lines.filter(String::isNotBlank).map { it.takeWhile(Char::isWhitespace).count() }.minOrNull() ?: 0 - return lines.joinToString("\n") { it.drop(indent) } - } - - private fun processSampleBody(psiElement: PsiElement): String = when (psiElement) { - is KtDeclarationWithBody -> { - when (val bodyExpression = psiElement.bodyExpression) { - is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") - else -> bodyExpression!!.text - } - } - else -> psiElement.text - } - - protected open fun processImports(psiElement: PsiElement): String { - val psiFile = psiElement.containingFile - return when(val text = (psiFile as? KtFile)?.importList?.text) { - is String -> text - else -> "" - } - } - - /** - * @return [SampleProvider.SampleSnippet] or null if it has not found by [fqLink] - */ - override fun getSample(sourceSet: DokkaConfiguration.DokkaSourceSet, fqLink: String): SampleProvider.SampleSnippet? { - return runBlocking(Dispatchers.Default) { - val resolveSession = analysis.value[sourceSet].resolveSession - val psiElement = fqNameToPsiElement(resolveSession, fqLink, sourceSet) - ?: return@runBlocking null.also { context.logger.warn("Cannot find PsiElement corresponding to $fqLink") } - val imports = - processImports(psiElement) - val body = processBody(psiElement) - return@runBlocking SampleProvider.SampleSnippet(imports, body) - } - } - override fun close() { - if(analysis.isInitialized()) - analysis.value.close() - } - - private fun fqNameToPsiElement(resolveSession: ResolveSession, functionName: String, dokkaSourceSet: DokkaConfiguration.DokkaSourceSet): PsiElement? { - val packageName = functionName.takeWhile { it != '.' } - val descriptor = resolveSession.getPackageFragment(FqName(packageName)) - ?: return null.also { context.logger.warn("Cannot find descriptor for package $packageName") } - - with (kDocFinder) { - val symbol = resolveKDocLink( - descriptor, - functionName, - dokkaSourceSet, - emptyBindingContext = true - ).firstOrNull() ?: return null.also { context.logger.warn("Unresolved function $functionName in @sample") } - return org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration(symbol) - } - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/IllegalModuleAndPackageDocumentation.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/IllegalModuleAndPackageDocumentation.kt deleted file mode 100644 index 98eabf19..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/IllegalModuleAndPackageDocumentation.kt +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -import org.jetbrains.dokka.DokkaException - -internal class IllegalModuleAndPackageDocumentation( - source: ModuleAndPackageDocumentationSource, message: String -) : DokkaException("[$source] $message") diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentation.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentation.kt deleted file mode 100644 index 9b352c1a..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentation.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -import org.jetbrains.dokka.model.doc.DocumentationNode - -internal data class ModuleAndPackageDocumentation( - val name: String, - val classifier: Classifier, - val documentation: DocumentationNode -) { - enum class Classifier { Module, Package } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationFragment.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationFragment.kt deleted file mode 100644 index d1e729b2..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationFragment.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - - -internal data class ModuleAndPackageDocumentationFragment( - val name: String, - val classifier: ModuleAndPackageDocumentation.Classifier, - val documentation: String, - val source: ModuleAndPackageDocumentationSource -) diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationParsingContext.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationParsingContext.kt deleted file mode 100644 index 95701964..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationParsingContext.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.from -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier.Module -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier.Package -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name - -internal fun interface ModuleAndPackageDocumentationParsingContext { - fun markdownParserFor(fragment: ModuleAndPackageDocumentationFragment, location: String): MarkdownParser -} - -internal fun ModuleAndPackageDocumentationParsingContext.parse( - fragment: ModuleAndPackageDocumentationFragment -): DocumentationNode { - return markdownParserFor(fragment, fragment.source.sourceDescription).parse(fragment.documentation) -} - -internal fun ModuleAndPackageDocumentationParsingContext( - logger: DokkaLogger, - moduleDescriptor: ModuleDescriptor? = null, - kDocFinder: KDocFinder? = null, - sourceSet: DokkaConfiguration.DokkaSourceSet? = null -) = ModuleAndPackageDocumentationParsingContext { fragment, sourceLocation -> - val descriptor = when (fragment.classifier) { - Module -> moduleDescriptor?.getPackage(FqName.topLevel(Name.identifier(""))) - Package -> moduleDescriptor?.getPackage(FqName(fragment.name)) - } - - val externalDri = { link: String -> - try { - if (kDocFinder != null && descriptor != null && sourceSet != null) { - with(kDocFinder) { - resolveKDocLink( - descriptor, - link, - sourceSet - ).sorted().firstOrNull()?.let { - DRI.from( - it - ) - } - } - } else null - } catch (e1: IllegalArgumentException) { - logger.warn("Couldn't resolve link for $link") - null - } - } - - MarkdownParser(externalDri = externalDri, sourceLocation) -} - -private fun Collection<DeclarationDescriptor>.sorted() = sortedWith( - compareBy( - { it is ClassDescriptor }, - { (it as? FunctionDescriptor)?.name }, - { (it as? FunctionDescriptor)?.valueParameters?.size }, - { (it as? FunctionDescriptor)?.valueParameters?.joinToString { it.type.toString() } } - ) -) diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationReader.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationReader.kt deleted file mode 100644 index e3697159..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationReader.kt +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.KotlinAnalysis -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier -import org.jetbrains.dokka.model.DModule -import org.jetbrains.dokka.model.DPackage -import org.jetbrains.dokka.model.SourceSetDependent -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.model.doc.Deprecated -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.utilities.associateWithNotNull -import org.jetbrains.dokka.analysis.kotlin.internal.ModuleAndPackageDocumentationReader - -internal fun ModuleAndPackageDocumentationReader(context: DokkaContext): ModuleAndPackageDocumentationReader = - ContextModuleAndPackageDocumentationReader(context) - -private class ContextModuleAndPackageDocumentationReader( - private val context: DokkaContext -) : ModuleAndPackageDocumentationReader { - - private val kotlinAnalysis: KotlinAnalysis = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kotlinAnalysis } - private val kdocFinder: KDocFinder = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kdocFinder } - - private val documentationFragments: SourceSetDependent<List<ModuleAndPackageDocumentationFragment>> = - context.configuration.sourceSets.associateWith { sourceSet -> - sourceSet.includes.flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } - } - - private fun findDocumentationNodes( - sourceSets: Set<DokkaConfiguration.DokkaSourceSet>, - predicate: (ModuleAndPackageDocumentationFragment) -> Boolean - ): SourceSetDependent<DocumentationNode> { - return sourceSets.associateWithNotNull { sourceSet -> - val fragments = documentationFragments[sourceSet].orEmpty().filter(predicate) - val moduleDescriptor = kotlinAnalysis[sourceSet].moduleDescriptor - val documentations = fragments.map { fragment -> - parseModuleAndPackageDocumentation( - context = ModuleAndPackageDocumentationParsingContext(context.logger, moduleDescriptor, kdocFinder, sourceSet), - fragment = fragment - ) - } - when (documentations.size) { - 0 -> null - 1 -> documentations.single().documentation - else -> DocumentationNode(documentations.flatMap { it.documentation.children } - .mergeDocumentationNodes()) - } - } - } - - private val ModuleAndPackageDocumentationFragment.canonicalPackageName: String - get() { - check(classifier == Classifier.Package) - if (name == "[root]") return "" - return name - } - - override fun read(module: DModule): SourceSetDependent<DocumentationNode> { - return findDocumentationNodes(module.sourceSets) { fragment -> - fragment.classifier == Classifier.Module && (fragment.name == module.name) - } - } - - override fun read(pkg: DPackage): SourceSetDependent<DocumentationNode> { - return findDocumentationNodes(pkg.sourceSets) { fragment -> - fragment.classifier == Classifier.Package && fragment.canonicalPackageName == pkg.dri.packageName - } - } - - override fun read(module: DokkaConfiguration.DokkaModuleDescription): DocumentationNode? { - val parsingContext = ModuleAndPackageDocumentationParsingContext(context.logger) - - val documentationFragment = module.includes - .flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } - .firstOrNull { fragment -> fragment.classifier == Classifier.Module && fragment.name == module.name } - ?: return null - - val moduleDocumentation = parseModuleAndPackageDocumentation(parsingContext, documentationFragment) - return moduleDocumentation.documentation - } - - private fun List<TagWrapper>.mergeDocumentationNodes(): List<TagWrapper> = - groupBy { it::class }.values.map { - it.reduce { acc, tagWrapper -> - val newRoot = CustomDocTag( - acc.children + tagWrapper.children, - name = (tagWrapper as? NamedTagWrapper)?.name.orEmpty() - ) - when (acc) { - is See -> acc.copy(newRoot) - is Param -> acc.copy(newRoot) - is Throws -> acc.copy(newRoot) - is Sample -> acc.copy(newRoot) - is Property -> acc.copy(newRoot) - is CustomTagWrapper -> acc.copy(newRoot) - is Description -> acc.copy(newRoot) - is Author -> acc.copy(newRoot) - is Version -> acc.copy(newRoot) - is Since -> acc.copy(newRoot) - is Return -> acc.copy(newRoot) - is Receiver -> acc.copy(newRoot) - is Constructor -> acc.copy(newRoot) - is Deprecated -> acc.copy(newRoot) - is org.jetbrains.dokka.model.doc.Suppress -> acc.copy(newRoot) - } - } - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationSource.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationSource.kt deleted file mode 100644 index 7d717de6..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationSource.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -import java.io.File - -internal abstract class ModuleAndPackageDocumentationSource { - abstract val sourceDescription: String - abstract val documentation: String - override fun toString(): String = sourceDescription -} - -internal data class ModuleAndPackageDocumentationFile(private val file: File) : ModuleAndPackageDocumentationSource() { - override val sourceDescription: String = file.path - override val documentation: String by lazy(LazyThreadSafetyMode.PUBLICATION) { file.readText() } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentation.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentation.kt deleted file mode 100644 index 286d650a..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentation.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -internal fun parseModuleAndPackageDocumentation( - context: ModuleAndPackageDocumentationParsingContext, - fragment: ModuleAndPackageDocumentationFragment -): ModuleAndPackageDocumentation { - return ModuleAndPackageDocumentation( - name = fragment.name, - classifier = fragment.classifier, - documentation = context.parse(fragment) - ) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentationFragments.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentationFragments.kt deleted file mode 100644 index 2b36225b..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentationFragments.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs - -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier.Module -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier.Package -import java.io.File - -internal fun parseModuleAndPackageDocumentationFragments(source: File): List<ModuleAndPackageDocumentationFragment> { - return parseModuleAndPackageDocumentationFragments(ModuleAndPackageDocumentationFile(source)) -} - -internal fun parseModuleAndPackageDocumentationFragments( - source: ModuleAndPackageDocumentationSource -): List<ModuleAndPackageDocumentationFragment> { - val fragmentStrings = source.documentation.split(Regex("(|^)#\\s*(?=(Module|Package))")) - return fragmentStrings - .filter(String::isNotBlank) - .map { fragmentString -> parseModuleAndPackageDocFragment(source, fragmentString) } -} - -private fun parseModuleAndPackageDocFragment( - source: ModuleAndPackageDocumentationSource, - fragment: String -): ModuleAndPackageDocumentationFragment { - val firstLineAndDocumentation = fragment.split("\r\n", "\n", "\r", limit = 2) - val firstLine = firstLineAndDocumentation[0] - - val classifierAndName = firstLine.split(Regex("\\s+"), limit = 2) - - val classifier = when (classifierAndName[0].trim()) { - "Module" -> Module - "Package" -> Package - else -> throw IllegalStateException( - """Unexpected classifier: "${classifierAndName[0]}", expected either "Module" or "Package". - |For more information consult the specification: https://kotlinlang.org/docs/dokka-module-and-package-docs.html""".trimMargin() - ) - } - - if (classifierAndName.size != 2 && classifier == Module) { - throw IllegalModuleAndPackageDocumentation(source, "Missing Module name") - } - - val name = classifierAndName.getOrNull(1)?.trim().orEmpty() - if (classifier == Package && name.contains(Regex("\\s"))) { - throw IllegalModuleAndPackageDocumentation( - source, "Package name cannot contain whitespace in '$firstLine'" - ) - } - - return ModuleAndPackageDocumentationFragment( - name = name, - classifier = classifier, - documentation = firstLineAndDocumentation.getOrNull(1)?.trim().orEmpty(), - source = source - ) -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorDocumentationContent.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorDocumentationContent.kt deleted file mode 100644 index e8dcf63c..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorDocumentationContent.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import org.jetbrains.dokka.analysis.java.doccomment.DocumentationContent -import org.jetbrains.dokka.analysis.java.JavadocTag -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag - -internal data class DescriptorDocumentationContent( - val descriptor: DeclarationDescriptor, - val element: KDocTag, - override val tag: JavadocTag, -) : DocumentationContent { - override fun resolveSiblings(): List<DocumentationContent> { - return listOf(this) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocComment.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocComment.kt deleted file mode 100644 index b6150ca5..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocComment.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import org.jetbrains.dokka.analysis.java.* -import org.jetbrains.dokka.analysis.java.doccomment.DocComment -import org.jetbrains.dokka.analysis.java.doccomment.DocumentationContent -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag - -internal class DescriptorKotlinDocComment( - val comment: KDocTag, - val descriptor: DeclarationDescriptor -) : DocComment { - - private val tagsWithContent: List<KDocTag> = comment.children.mapNotNull { (it as? KDocTag) } - - override fun hasTag(tag: JavadocTag): Boolean { - return when (tag) { - is DescriptionJavadocTag -> comment.getContent().isNotEmpty() - is ThrowingExceptionJavadocTag -> tagsWithContent.any { it.hasException(tag) } - else -> tagsWithContent.any { it.text.startsWith("@${tag.name}") } - } - } - - private fun KDocTag.hasException(tag: ThrowingExceptionJavadocTag) = - text.startsWith("@${tag.name}") && getSubjectName() == tag.exceptionQualifiedName - - override fun resolveTag(tag: JavadocTag): List<DocumentationContent> { - return when (tag) { - is DescriptionJavadocTag -> listOf(DescriptorDocumentationContent(descriptor, comment, tag)) - is ParamJavadocTag -> { - val resolvedContent = resolveGeneric(tag) - listOf(resolvedContent[tag.paramIndex]) - } - - is ThrowsJavadocTag -> resolveThrowingException(tag) - is ExceptionJavadocTag -> resolveThrowingException(tag) - else -> resolveGeneric(tag) - } - } - - private fun resolveThrowingException(tag: ThrowingExceptionJavadocTag): List<DescriptorDocumentationContent> { - val exceptionName = tag.exceptionQualifiedName ?: return resolveGeneric(tag) - - return comment.children - .filterIsInstance<KDocTag>() - .filter { it.name == tag.name && it.getSubjectName() == exceptionName } - .map { DescriptorDocumentationContent(descriptor, it, tag) } - } - - private fun resolveGeneric(tag: JavadocTag): List<DescriptorDocumentationContent> { - return comment.children.mapNotNull { element -> - if (element is KDocTag && element.name == tag.name) { - DescriptorDocumentationContent(descriptor, element, tag) - } else { - null - } - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as DescriptorKotlinDocComment - - if (comment != other.comment) return false - if (descriptor.name != other.descriptor.name) return false - if (tagsWithContent != other.tagsWithContent) return false - - return true - } - - override fun hashCode(): Int { - var result = comment.hashCode() - result = 31 * result + descriptor.name.hashCode() - result = 31 * result + tagsWithContent.hashCode() - return result - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentCreator.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentCreator.kt deleted file mode 100644 index 6beaac3f..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentCreator.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import com.intellij.psi.PsiNamedElement -import org.jetbrains.dokka.analysis.java.doccomment.DocComment -import org.jetbrains.dokka.analysis.java.doccomment.DocCommentCreator -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.DescriptorFinder -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtElement - -internal class DescriptorKotlinDocCommentCreator( - private val kdocFinder: KDocFinder, - private val descriptorFinder: DescriptorFinder -) : DocCommentCreator { - override fun create(element: PsiNamedElement): DocComment? { - val ktElement = element.navigationElement as? KtElement ?: return null - val kdoc = with (kdocFinder) { - ktElement.findKDoc() - } ?: return null - val descriptor = with (descriptorFinder) { - (element.navigationElement as? KtDeclaration)?.findDescriptor() - } ?: return null - - return DescriptorKotlinDocComment(kdoc, descriptor) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentParser.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentParser.kt deleted file mode 100644 index 694ee5ac..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentParser.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import com.intellij.psi.PsiNamedElement -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.analysis.java.doccomment.DocComment -import org.jetbrains.dokka.analysis.java.parsers.DocCommentParser -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.from -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator.parseFromKDocTag -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.utilities.DokkaLogger - -internal class DescriptorKotlinDocCommentParser( - private val context: DokkaContext, - private val logger: DokkaLogger -) : DocCommentParser { - - override fun canParse(docComment: DocComment): Boolean { - return docComment is DescriptorKotlinDocComment - } - - override fun parse(docComment: DocComment, context: PsiNamedElement): DocumentationNode { - val kotlinDocComment = docComment as DescriptorKotlinDocComment - return parseDocumentation(kotlinDocComment) - } - - fun parseDocumentation(element: DescriptorKotlinDocComment, parseWithChildren: Boolean = true): DocumentationNode { - val sourceSet = context.configuration.sourceSets.let { sourceSets -> - sourceSets.firstOrNull { it.sourceSetID.sourceSetName == "jvmMain" } - ?: sourceSets.first { it.analysisPlatform == Platform.jvm } - } - val kdocFinder = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kdocFinder } - return parseFromKDocTag( - kDocTag = element.comment, - externalDri = { link: String -> - try { - kdocFinder.resolveKDocLink(element.descriptor, link, sourceSet) - .firstOrNull() - ?.let { DRI.from(it) } - } catch (e1: IllegalArgumentException) { - logger.warn("Couldn't resolve link for $link") - null - } - }, - kdocLocation = null, - parseWithChildren = parseWithChildren - ) - } -} - diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisProjectProvider.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisProjectProvider.kt deleted file mode 100644 index 33ad025f..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisProjectProvider.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import com.intellij.openapi.project.Project -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.ProjectProvider -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle - -internal class KotlinAnalysisProjectProvider : ProjectProvider { - override fun getProject(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): Project { - val kotlinAnalysis = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kotlinAnalysis } - return kotlinAnalysis[sourceSet].project - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisSourceRootsExtractor.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisSourceRootsExtractor.kt deleted file mode 100644 index 78b08f18..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisSourceRootsExtractor.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.SourceRootsExtractor -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot -import java.io.File - -internal class KotlinAnalysisSourceRootsExtractor : SourceRootsExtractor { - - override fun extract(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): List<File> { - val kotlinAnalysis = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kotlinAnalysis } - val environment = kotlinAnalysis[sourceSet].environment - return environment.configuration.get(CLIConfigurationKeys.CONTENT_ROOTS) - ?.filterIsInstance<JavaSourceRoot>() - ?.mapNotNull { it.file.takeIf { isFileInSourceRoots(it, sourceSet) } } - ?: listOf() - } - - private fun isFileInSourceRoots(file: File, sourceSet: DokkaConfiguration.DokkaSourceSet): Boolean = - sourceSet.sourceRoots.any { root -> file.startsWith(root) } - -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinInheritDocTagContentProvider.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinInheritDocTagContentProvider.kt deleted file mode 100644 index 40a12fe8..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinInheritDocTagContentProvider.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.java - -import org.jetbrains.dokka.analysis.java.doccomment.DocumentationContent -import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin -import org.jetbrains.dokka.analysis.java.parsers.doctag.DocTagParserContext -import org.jetbrains.dokka.analysis.java.parsers.doctag.InheritDocTagContentProvider -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query - -internal class KotlinInheritDocTagContentProvider( - context: DokkaContext -) : InheritDocTagContentProvider { - - val parser: DescriptorKotlinDocCommentParser by lazy { - context.plugin<JavaAnalysisPlugin>().query { docCommentParsers } - .single { it is DescriptorKotlinDocCommentParser } as DescriptorKotlinDocCommentParser - } - - override fun canConvert(content: DocumentationContent): Boolean = content is DescriptorDocumentationContent - - override fun convertToHtml(content: DocumentationContent, docTagParserContext: DocTagParserContext): String { - val descriptorContent = content as DescriptorDocumentationContent - val inheritedDocNode = parser.parseDocumentation( - DescriptorKotlinDocComment(descriptorContent.element, descriptorContent.descriptor), - parseWithChildren = false - ) - val id = docTagParserContext.store(inheritedDocNode) - return """<inheritdoc id="$id"/>""" - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/CollectionExtensions.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/CollectionExtensions.kt deleted file mode 100644 index b08eecfc..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/CollectionExtensions.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -// TODO [beresnev] remove this copy-paste and use the same method from stdlib instead after updating to 1.5 -internal inline fun <T, R : Any> Iterable<T>.firstNotNullOfOrNull(transform: (T) -> R?): R? { - for (element in this) { - val result = transform(element) - if (result != null) { - return result - } - } - return null -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultDescriptorToDocumentableTranslator.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultDescriptorToDocumentableTranslator.kt deleted file mode 100644 index 4d561189..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultDescriptorToDocumentableTranslator.kt +++ /dev/null @@ -1,1284 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiNamedElement -import com.intellij.psi.util.PsiLiteralUtil.* -import kotlinx.coroutines.* -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin -import org.jetbrains.dokka.analysis.java.parsers.JavadocParser -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisContext -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.DescriptorDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.KotlinAnalysis -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.from -import org.jetbrains.dokka.links.* -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.AnnotationTarget -import org.jetbrains.dokka.model.Nullable -import org.jetbrains.dokka.model.Visibility -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.model.properties.PropertyContainer -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.DokkaLogger -import org.jetbrains.dokka.utilities.parallelMap -import org.jetbrains.dokka.utilities.parallelMapNotNull -import org.jetbrains.kotlin.KtNodeTypes -import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor -import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType -import org.jetbrains.kotlin.builtins.isExtensionFunctionType -import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype -import org.jetbrains.kotlin.codegen.isJvmStaticInObjectOrClassOrInterface -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.annotations.Annotated -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.descriptors.java.JavaVisibilities -import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi -import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor -import org.jetbrains.kotlin.load.kotlin.toSourceElement -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.calls.components.isVararg -import org.jetbrains.kotlin.resolve.calls.util.getValueArgumentsInParentheses -import org.jetbrains.kotlin.resolve.constants.ConstantValue -import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.LocalClass -import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.NormalClass -import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull -import org.jetbrains.kotlin.resolve.descriptorUtil.parents -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum -import org.jetbrains.kotlin.resolve.source.KotlinSourceElement -import org.jetbrains.kotlin.resolve.source.PsiSourceElement -import org.jetbrains.kotlin.resolve.source.PsiSourceFile -import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes -import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull -import java.nio.file.Paths -import org.jetbrains.kotlin.resolve.constants.AnnotationValue as ConstantsAnnotationValue -import org.jetbrains.kotlin.resolve.constants.ArrayValue as ConstantsArrayValue -import org.jetbrains.kotlin.resolve.constants.BooleanValue as ConstantsBooleanValue -import org.jetbrains.kotlin.resolve.constants.DoubleValue as ConstantsDoubleValue -import org.jetbrains.kotlin.resolve.constants.EnumValue as ConstantsEnumValue -import org.jetbrains.kotlin.resolve.constants.FloatValue as ConstantsFloatValue -import org.jetbrains.kotlin.resolve.constants.IntValue as ConstantsIntValue -import org.jetbrains.kotlin.resolve.constants.KClassValue as ConstantsKtClassValue -import org.jetbrains.kotlin.resolve.constants.LongValue as ConstantsLongValue -import org.jetbrains.kotlin.resolve.constants.NullValue as ConstantsNullValue -import org.jetbrains.kotlin.resolve.constants.UIntValue as ConstantsUIntValue -import org.jetbrains.kotlin.resolve.constants.ULongValue as ConstantsULongValue - -internal class DefaultDescriptorToDocumentableTranslator( - private val context: DokkaContext -) : AsyncSourceToDocumentableTranslator, ExternalClasslikesTranslator { - - private val kotlinAnalysis: KotlinAnalysis = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kotlinAnalysis } - private val kdocFinder: KDocFinder = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kdocFinder } - - override suspend fun invokeSuspending(sourceSet: DokkaSourceSet, context: DokkaContext): DModule { - val analysisContext = kotlinAnalysis[sourceSet] - val environment = analysisContext.environment - val packageFragments = environment.getSourceFiles().asSequence() - .map { it.packageFqName } - .distinct() - .mapNotNull { analysisContext.resolveSession.getPackageFragment(it) } - .toList() - - val javadocParser = JavadocParser( - docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers }, - docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder - ) - - - return DokkaDescriptorVisitor(sourceSet, kdocFinder, kotlinAnalysis[sourceSet], context.logger, javadocParser).run { - packageFragments.parallelMap { - visitPackageFragmentDescriptor( - it - ) - } - }.let { - DModule( - name = context.configuration.moduleName, - packages = it, - documentation = emptyMap(), - expectPresentInSet = null, - sourceSets = setOf(sourceSet) - ) - } - } - - /** - * Implementation note: it runs in a separated single thread due to existing support of coroutines (see #2936) - */ - @OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class) - override fun translateClassDescriptor(descriptor: ClassDescriptor, sourceSet: DokkaSourceSet): DClasslike { - val driInfo = DRI.from(descriptor.parents.first()).withEmptyInfo() - - val javadocParser = JavadocParser( - docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers }, - docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder - ) - - return newSingleThreadContext("Generating documentable model of classlike").use { coroutineContext -> // see https://github.com/Kotlin/dokka/issues/3151 - runBlocking(coroutineContext) { - DokkaDescriptorVisitor(sourceSet, kdocFinder, kotlinAnalysis[sourceSet], context.logger, javadocParser) - .visitClassDescriptor(descriptor, driInfo) - } - } - } -} - -internal data class DRIWithPlatformInfo( - val dri: DRI, - val actual: SourceSetDependent<DocumentableSource> -) - -internal fun DRI.withEmptyInfo() = DRIWithPlatformInfo(this, emptyMap()) - -private class DokkaDescriptorVisitor( - private val sourceSet: DokkaSourceSet, - private val kDocFinder: KDocFinder, - private val analysisContext: AnalysisContext, - private val logger: DokkaLogger, - private val javadocParser: JavadocParser -) { - private val syntheticDocProvider = SyntheticDescriptorDocumentationProvider(kDocFinder, sourceSet) - - private fun Collection<DeclarationDescriptor>.filterDescriptorsInSourceSet() = filter { - it.toSourceElement.containingFile.toString().let { path -> - path.isNotBlank() && sourceSet.sourceRoots.any { root -> - Paths.get(path).startsWith(root.toPath()) - } - } - } - - private fun <T> T.toSourceSetDependent() = if (this != null) mapOf(sourceSet to this) else emptyMap() - - suspend fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor): DPackage { - val name = descriptor.fqName.asString().takeUnless { it.isBlank() } ?: "" - val driWithPlatform = DRI(packageName = name).withEmptyInfo() - val scope = descriptor.getMemberScope() - return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind(true) - - val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - val typealiases = async { descriptorsWithKind.typealiases.visitTypealiases() } - - DPackage( - dri = driWithPlatform.dri, - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - typealiases = typealiases.await(), - documentation = descriptor.resolveDescriptorData(), - sourceSets = setOf(sourceSet) - ) - } - } - - suspend fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClasslike = - when (descriptor.kind) { - ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent) - ClassKind.OBJECT -> objectDescriptor(descriptor, parent) - ClassKind.INTERFACE -> interfaceDescriptor(descriptor, parent) - ClassKind.ANNOTATION_CLASS -> annotationDescriptor(descriptor, parent) - else -> classDescriptor(descriptor, parent) - } - - private suspend fun interfaceDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DInterface { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - val info = descriptor.resolveClassDescriptionData() - - return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind() - - val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } - - DInterface( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - sources = descriptor.createSources(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - documentation = info.docs, - generics = generics.await(), - companion = descriptor.companion(driWithPlatform), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()), - info.ancestry.exceptionInSupertypesOrNull() - ) - ) - } - } - - private suspend fun objectDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DObject { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - val info = descriptor.resolveClassDescriptionData() - - - return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind() - - val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - - DObject( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - sources = descriptor.createSources(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - documentation = info.docs, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()), - info.ancestry.exceptionInSupertypesOrNull() - ) - ) - } - - - } - - private suspend fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnum { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - val info = descriptor.resolveClassDescriptionData() - - return coroutineScope { - val descriptorsWithKind = descriptor.getEnumDescriptorsWithKind() - - val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - val constructors = - async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } } - val entries = async { descriptorsWithKind.enumEntries.visitEnumEntries(driWithPlatform) } - - DEnum( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - entries = entries.await(), - constructors = constructors.await(), - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - sources = descriptor.createSources(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - documentation = info.docs, - companion = descriptor.companion(driWithPlatform), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()) - ) - ) - } - } - - private fun ClassDescriptor.getEnumDescriptorsWithKind(): DescriptorsWithKind { - val descriptorsWithKind = this.unsubstitutedMemberScope.getDescriptorsWithKind() - val staticScopeForKotlinEnum = (this.staticScope as? StaticScopeForKotlinEnum) ?: return descriptorsWithKind - - // synthetic declarations, such as `entries`, `values()` and `valueOf()`, - // are not present among real in-code declarationg - val contributedDescriptors = staticScopeForKotlinEnum.getContributedDescriptors { true } - return descriptorsWithKind.copy( - properties = descriptorsWithKind.properties + contributedDescriptors.filterIsInstance<PropertyDescriptor>(), - functions = descriptorsWithKind.functions + contributedDescriptors.filterIsInstance<FunctionDescriptor>() - ) - } - - private suspend fun visitEnumEntryDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnumEntry { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val isExpect = descriptor.isExpect - - return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind() - - val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - - DEnumEntry( - dri = driWithPlatform.dri.withEnumEntryExtra(), - name = descriptor.name.asString(), - documentation = descriptor.resolveDescriptorData(), - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - sourceSets = setOf(sourceSet), - expectPresentInSet = sourceSet.takeIf { isExpect }, - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations() - ) - ) - } - } - - private suspend fun annotationDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DAnnotation { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - - return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind() - - val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } - val constructors = - async { descriptor.constructors.parallelMap { visitConstructorDescriptor(it, driWithPlatform) } } - - DAnnotation( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - documentation = descriptor.resolveDescriptorData(), - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations() - ), - companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = generics.await(), - constructors = constructors.await(), - sources = descriptor.createSources() - ) - } - - - } - - private suspend fun classDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DClass { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - val info = descriptor.resolveClassDescriptionData() - val actual = descriptor.createSources() - - return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind() - - val (regularFunctions, accessors) = splitFunctionsAndInheritedAccessors( - properties = descriptorsWithKind.properties, - functions = descriptorsWithKind.functions - ) - - val functions = async { regularFunctions.visitFunctions(driWithPlatform) } - val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform, accessors) } - val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } - val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } - val constructors = async { - descriptor.constructors.parallelMap { - visitConstructorDescriptor( - it, - if (it.isPrimary) DRIWithPlatformInfo(driWithPlatform.dri, actual) - else DRIWithPlatformInfo(driWithPlatform.dri, emptyMap()) - ) - } - } - - DClass( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - constructors = constructors.await(), - functions = functions.await(), - properties = properties.await(), - classlikes = classlikes.await(), - sources = actual, - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - supertypes = info.supertypes.toSourceSetDependent(), - generics = generics.await(), - documentation = info.docs, - modifier = descriptor.modifier().toSourceSetDependent(), - companion = descriptor.companion(driWithPlatform), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.ancestry.allImplementedInterfaces().toSourceSetDependent()), - info.ancestry.exceptionInSupertypesOrNull() - ) - ) - } - } - - /** - * @param implicitAccessors getters/setters that are not part of the property descriptor, for instance - * average methods inherited from java sources that access the property - */ - private suspend fun visitPropertyDescriptor( - originalDescriptor: PropertyDescriptor, - implicitAccessors: DescriptorAccessorHolder?, - parent: DRIWithPlatformInfo - ): DProperty { - val (dri, _) = originalDescriptor.createDRI() - val inheritedFrom = dri.getInheritedFromDRI(parent) - val descriptor = originalDescriptor.getConcreteDescriptor() - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - - val actual = originalDescriptor.createSources() - - // example - generated getter that comes with data classes - suspend fun getDescriptorGetter() = - descriptor.accessors - .firstIsInstanceOrNull<PropertyGetterDescriptor>() - ?.let { - visitPropertyAccessorDescriptor(it, descriptor, dri, inheritedFrom) - } - - suspend fun getImplicitAccessorGetter() = - implicitAccessors?.getter?.let { visitFunctionDescriptor(it, parent) } - - // example - generated setter that comes with data classes - suspend fun getDescriptorSetter() = - descriptor.accessors - .firstIsInstanceOrNull<PropertySetterDescriptor>() - ?.let { - visitPropertyAccessorDescriptor(it, descriptor, dri, inheritedFrom) - } - - suspend fun getImplicitAccessorSetter() = - implicitAccessors?.setter?.let { visitFunctionDescriptor(it, parent) } - - return coroutineScope { - val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } - val getter = getDescriptorGetter() ?: getImplicitAccessorGetter() - val setter = getDescriptorSetter() ?: getImplicitAccessorSetter() - - DProperty( - dri = dri, - name = descriptor.name.asString(), - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) - }, - sources = actual, - getter = getter, - setter = setter, - visibility = descriptor.getVisibility(implicitAccessors).toSourceSetDependent(), - documentation = descriptor.getDocumentation(), - modifier = descriptor.modifier().toSourceSetDependent(), - type = descriptor.returnType!!.toBound(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - generics = generics.await(), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - listOfNotNull( - (descriptor.additionalExtras() + descriptor.getAnnotationsWithBackingField() - .toAdditionalExtras()).toSet().toSourceSetDependent().toAdditionalModifiers(), - (descriptor.getAnnotationsWithBackingField() + descriptor.fileLevelAnnotations()).toSourceSetDependent() - .toAnnotations(), - descriptor.getDefaultValue()?.let { DefaultValue(it.toSourceSetDependent()) }, - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) }, - takeIf { descriptor.isVar(getter, setter) }?.let { IsVar }, - takeIf { descriptor.findPsi() is KtParameter }?.let { IsAlsoParameter(listOf(sourceSet)) } - ) - ) - ) - } - } - - private fun PropertyDescriptor.isVar(getter: DFunction?, setter: DFunction?): Boolean { - return if (this is JavaPropertyDescriptor) { - // in Java, concepts of extensibility and mutability are mixed into a single `final` modifier - // in Kotlin, it's different - val/var controls mutability and open modifier controls extensibility - // so when inheriting Java properties, you can end up with a final var - non extensible mutable prop - val isMutable = this.isVar - // non-final java property should be var if it has no accessors at all or has a setter - (isMutable && getter == null && setter == null) || (getter != null && setter != null) - } else { - this.isVar - } - } - - private fun PropertyDescriptor.getVisibility(implicitAccessors: DescriptorAccessorHolder?): Visibility { - val isNonPublicJavaProperty = this is JavaPropertyDescriptor && !this.visibility.isPublicAPI - val visibility = - if (isNonPublicJavaProperty) { - // only try to take implicit getter's visibility if it's a java property - // because it's not guaranteed that implicit accessor will be used - // for the kotlin property, as it may have an explicit accessor of its own, - // i.e in data classes or with get() and set() are overridden - (implicitAccessors?.getter?.visibility ?: this.visibility) - } else { - this.visibility - } - - return visibility.toDokkaVisibility() - } - - private fun CallableMemberDescriptor.createDRI(wasOverridenBy: DRI? = null): Pair<DRI, DRI?> = - if (kind == CallableMemberDescriptor.Kind.DECLARATION || overriddenDescriptors.isEmpty()) - Pair(DRI.from(this), wasOverridenBy) - else - overriddenDescriptors.first().createDRI(DRI.from(this)) - - private suspend fun visitFunctionDescriptor( - originalDescriptor: FunctionDescriptor, - parent: DRIWithPlatformInfo - ): DFunction { - val (dri, _) = originalDescriptor.createDRI() - val inheritedFrom = dri.getInheritedFromDRI(parent) - val descriptor = originalDescriptor.getConcreteDescriptor() - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - - val actual = originalDescriptor.createSources() - return coroutineScope { - val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } - - DFunction( - dri = dri, - name = descriptor.name.asString(), - isConstructor = false, - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) - }, - parameters = descriptor.valueParameters.mapIndexed { index, desc -> - parameter(index, desc, DRIWithPlatformInfo(dri, actual)) - }, - expectPresentInSet = sourceSet.takeIf { isExpect }, - sources = actual, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = generics.await(), - documentation = descriptor.getDocumentation(), - modifier = descriptor.modifier().toSourceSetDependent(), - type = descriptor.returnType!!.toBound(), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) }, - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - (descriptor.getAnnotations() + descriptor.fileLevelAnnotations()).toSourceSetDependent() - .toAnnotations(), - ObviousMember.takeIf { descriptor.isObvious() }, - ) - ) - } - } - - private fun DeclarationDescriptor.getDocumentation(): SourceSetDependent<DocumentationNode> { - val isSynthesized = this is CallableMemberDescriptor && this.kind == CallableMemberDescriptor.Kind.SYNTHESIZED - return if (isSynthesized) { - syntheticDocProvider.getDocumentation(this)?.toSourceSetDependent() ?: emptyMap() - } else { - this.resolveDescriptorData() - } - } - - /** - * `createDRI` returns the DRI of the exact element and potential DRI of an element that is overriding it - * (It can be also FAKE_OVERRIDE which is in fact just inheritance of the symbol) - * - * Looking at what PSIs do, they give the DRI of the element within the classnames where it is actually - * declared and inheritedFrom as the same DRI but truncated callable part. - * Therefore, we set callable to null and take the DRI only if it is indeed coming from different class. - */ - private fun DRI.getInheritedFromDRI(parent: DRIWithPlatformInfo): DRI? { - return this.copy(callable = null) - .takeIf { parent.dri.classNames != this.classNames || parent.dri.packageName != this.packageName } - } - - private fun FunctionDescriptor.isObvious(): Boolean { - return kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE - || (kind == CallableMemberDescriptor.Kind.SYNTHESIZED && !syntheticDocProvider.isDocumented(this)) - || containingDeclaration.fqNameOrNull()?.isObvious() == true - } - - private fun FqName.isObvious(): Boolean = with(this.asString()) { - return this == "kotlin.Any" || this == "kotlin.Enum" - || this == "java.lang.Object" || this == "java.lang.Enum" - } - - suspend fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, parent: DRIWithPlatformInfo): DFunction { - val name = descriptor.constructedClass.name.toString() - val dri = parent.dri.copy(callable = Callable.from(descriptor, name)) - val actual = descriptor.createSources() - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - - return coroutineScope { - val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } - - DFunction( - dri = dri, - name = name, - isConstructor = true, - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor(it, DRIWithPlatformInfo(dri, actual)) - }, - parameters = descriptor.valueParameters.mapIndexed { index, desc -> - parameter(index, desc, DRIWithPlatformInfo(dri, actual)) - }, - sources = actual, - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - documentation = descriptor.resolveDescriptorData().let { sourceSetDependent -> - if (descriptor.isPrimary) { - sourceSetDependent.map { entry -> - Pair( - entry.key, - entry.value.copy(children = (entry.value.children.find { it is Constructor }?.root?.let { constructor -> - listOf(Description(constructor)) - } ?: emptyList<TagWrapper>()) + entry.value.children.filterIsInstance<Param>())) - }.toMap() - } else { - sourceSetDependent - } - }, - type = descriptor.returnType.toBound(), - modifier = descriptor.modifier().toSourceSetDependent(), - generics = generics.await(), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll<DFunction>( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations() - ).let { - if (descriptor.isPrimary) { - it + PrimaryConstructorExtra - } else it - } - ) - } - } - - private suspend fun visitReceiverParameterDescriptor( - descriptor: ReceiverParameterDescriptor, - parent: DRIWithPlatformInfo - ) = DParameter( - dri = parent.dri.copy(target = PointingToDeclaration), - name = null, - type = descriptor.type.toBound(), - expectPresentInSet = null, - documentation = descriptor.resolveDescriptorData(), - sourceSets = setOf(sourceSet), - extra = PropertyContainer.withAll(descriptor.getAnnotations().toSourceSetDependent().toAnnotations()) - ) - - private suspend fun visitPropertyAccessorDescriptor( - descriptor: PropertyAccessorDescriptor, - propertyDescriptor: PropertyDescriptor, - parent: DRI, - inheritedFrom: DRI? = null - ): DFunction { - val dri = parent.copy(callable = Callable.from(descriptor)) - val isGetter = descriptor is PropertyGetterDescriptor - val isExpect = descriptor.isExpect - val isActual = descriptor.isActual - - suspend fun PropertyDescriptor.asParameter(parent: DRI) = - DParameter( - parent.copy(target = PointingToCallableParameters(parameterIndex = 1)), - this.name.asString(), - type = this.type.toBound(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - documentation = descriptor.resolveDescriptorData(), - sourceSets = setOf(sourceSet), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - getAnnotationsWithBackingField().toSourceSetDependent().toAnnotations() - ) - ) - - val name = run { - val rawName = propertyDescriptor.name.asString() - /* - * Kotlin has special rules for conversion around properties that - * start with "is" For more info see: - * https://kotlinlang.org/docs/java-interop.html#getters-and-setters - * https://kotlinlang.org/docs/java-to-kotlin-interop.html#properties - * - * Based on our testing, this rule only applies when the letter after - * the "is" is *not* lowercase. This means that words like "issue" won't - * have the rule applied but "is_foobar" and "is1of" will have the rule applied. - */ - val specialCaseIs = rawName.startsWith("is") - && rawName.getOrNull(2)?.isLowerCase() == false - - if (specialCaseIs) { - if (isGetter) rawName else rawName.replaceFirst("is", "set") - } else { - if (isGetter) "get${rawName.capitalize()}" else "set${rawName.capitalize()}" - } - } - - val parameters = - if (isGetter) { - emptyList() - } else { - listOf(propertyDescriptor.asParameter(dri)) - } - - return coroutineScope { - val generics = async { descriptor.typeParameters.parallelMap { it.toVariantTypeParameter() } } - DFunction( - dri, - name, - isConstructor = false, - parameters = parameters, - visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(), - documentation = descriptor.resolveDescriptorData().mapInheritedTagWrappers(), - type = descriptor.returnType!!.toBound(), - generics = generics.await(), - modifier = descriptor.modifier().toSourceSetDependent(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor( - it, - DRIWithPlatformInfo(dri, descriptor.createSources()) - ) - }, - sources = descriptor.createSources(), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) } - ) - ) - } - } - - /** - * Workaround for a problem with inheriting parent TagWrappers of the wrong type. - * - * For instance, if you annotate a class with `@property`, kotlin compiler will propagate - * this tag to the property and its getters and setters. In case of getters and setters, - * it's more correct to display propagated docs as description instead of property - */ - private fun SourceSetDependent<DocumentationNode>.mapInheritedTagWrappers(): SourceSetDependent<DocumentationNode> { - return this.mapValues { (_, value) -> - val mappedChildren = value.children.map { - when (it) { - is Property -> Description(it.root) - else -> it - } - } - value.copy(children = mappedChildren) - } - } - - private suspend fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor) = - with(descriptor) { - coroutineScope { - val generics = async { descriptor.declaredTypeParameters.parallelMap { it.toVariantTypeParameter() } } - val info = buildAncestryInformation(defaultType).copy( - superclass = buildAncestryInformation(underlyingType), - interfaces = emptyList() - ) - DTypeAlias( - dri = DRI.from(this@with), - name = name.asString(), - type = defaultType.toBound(), - expectPresentInSet = null, - underlyingType = underlyingType.toBound().toSourceSetDependent(), - visibility = visibility.toDokkaVisibility().toSourceSetDependent(), - documentation = resolveDescriptorData(), - sourceSets = setOf(sourceSet), - generics = generics.await(), - sources = descriptor.createSources(), - extra = PropertyContainer.withAll( - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - info.exceptionInSupertypesOrNull(), - ) - ) - } - } - - private suspend fun parameter(index: Int, descriptor: ValueParameterDescriptor, parent: DRIWithPlatformInfo) = - DParameter( - dri = parent.dri.copy(target = PointingToCallableParameters(index)), - name = descriptor.name.asString(), - type = descriptor.varargElementType?.toBound() ?: descriptor.type.toBound(), - expectPresentInSet = null, - documentation = descriptor.resolveDescriptorData(), - sourceSets = setOf(sourceSet), - extra = PropertyContainer.withAll(listOfNotNull( - descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - descriptor.getDefaultValue()?.let { DefaultValue(it.toSourceSetDependent()) } - )) - ) - - private data class DescriptorsWithKind( - val functions: List<FunctionDescriptor>, - val properties: List<PropertyDescriptor>, - val classlikes: List<ClassDescriptor>, - val typealiases: List<TypeAliasDescriptor>, - val enumEntries: List<ClassDescriptor> - ) - - private fun MemberScope.getDescriptorsWithKind(shouldFilter: Boolean = false): DescriptorsWithKind { - val descriptors = getContributedDescriptors { true }.let { - if (shouldFilter) it.filterDescriptorsInSourceSet() else it - } - - class EnumEntryDescriptor - - val groupedDescriptors = descriptors.groupBy { - when { - it is FunctionDescriptor -> FunctionDescriptor::class - it is PropertyDescriptor -> PropertyDescriptor::class - it is ClassDescriptor && it.kind != ClassKind.ENUM_ENTRY -> ClassDescriptor::class - it is TypeAliasDescriptor -> TypeAliasDescriptor::class - it is ClassDescriptor && it.kind == ClassKind.ENUM_ENTRY -> EnumEntryDescriptor::class - else -> IllegalStateException::class - } - } - - @Suppress("UNCHECKED_CAST") - return DescriptorsWithKind( - (groupedDescriptors[FunctionDescriptor::class] ?: emptyList()) as List<FunctionDescriptor>, - (groupedDescriptors[PropertyDescriptor::class] ?: emptyList()) as List<PropertyDescriptor>, - (groupedDescriptors[ClassDescriptor::class] ?: emptyList()) as List<ClassDescriptor>, - (groupedDescriptors[TypeAliasDescriptor::class] ?: emptyList()) as List<TypeAliasDescriptor>, - (groupedDescriptors[EnumEntryDescriptor::class] ?: emptyList()) as List<ClassDescriptor> - ) - } - - private suspend fun List<FunctionDescriptor>.visitFunctions(parent: DRIWithPlatformInfo): List<DFunction> = - coroutineScope { parallelMap { visitFunctionDescriptor(it, parent) } } - - private suspend fun List<PropertyDescriptor>.visitProperties( - parent: DRIWithPlatformInfo, - implicitAccessors: Map<PropertyDescriptor, DescriptorAccessorHolder> = emptyMap(), - ): List<DProperty> { - return coroutineScope { - parallelMap { - visitPropertyDescriptor(it, implicitAccessors[it], parent) - } - } - } - - private suspend fun List<ClassDescriptor>.visitClasslikes(parent: DRIWithPlatformInfo): List<DClasslike> = - coroutineScope { parallelMap { visitClassDescriptor(it, parent) } } - - private suspend fun List<TypeAliasDescriptor>.visitTypealiases(): List<DTypeAlias> = - coroutineScope { parallelMap { visitTypeAliasDescriptor(it) } } - - private suspend fun List<ClassDescriptor>.visitEnumEntries(parent: DRIWithPlatformInfo): List<DEnumEntry> = - coroutineScope { parallelMap { visitEnumEntryDescriptor(it, parent) } } - - private fun DeclarationDescriptor.resolveDescriptorData(): SourceSetDependent<DocumentationNode> = - resolveDocumentation()?.toSourceSetDependent() ?: emptyMap() - - - private suspend fun toTypeConstructor(kt: KotlinType) = - GenericTypeConstructor( - DRI.from(kt.constructor.declarationDescriptor as DeclarationDescriptor), - kt.arguments.map { it.toProjection() }, - extra = PropertyContainer.withAll(kt.getAnnotations().toSourceSetDependent().toAnnotations()) - ) - - private suspend fun buildAncestryInformation( - kotlinType: KotlinType - ): AncestryNode { - val (interfaces, superclass) = kotlinType.immediateSupertypes().filterNot { it.isAnyOrNullableAny() } - .partition { - val declaration = it.constructor.declarationDescriptor - val descriptor = declaration as? ClassDescriptor - ?: (declaration as? TypeAliasDescriptor)?.underlyingType?.constructor?.declarationDescriptor as? ClassDescriptor - descriptor?.kind == ClassKind.INTERFACE - } - - return coroutineScope { - AncestryNode( - typeConstructor = toTypeConstructor(kotlinType), - superclass = superclass.parallelMap(::buildAncestryInformation).singleOrNull(), - interfaces = interfaces.parallelMap(::buildAncestryInformation) - ) - } - } - - - private suspend fun ClassDescriptor.resolveClassDescriptionData(): ClassInfo { - return coroutineScope { - ClassInfo( - buildAncestryInformation(this@resolveClassDescriptionData.defaultType), - resolveDescriptorData() - ) - } - } - - private suspend fun TypeParameterDescriptor.toVariantTypeParameter() = - DTypeParameter( - variantTypeParameter( - TypeParameter(DRI.from(this), name.identifier, annotations.getPresentableName()) - ), - resolveDescriptorData(), - null, - upperBounds.map { it.toBound() }, - setOf(sourceSet), - extra = PropertyContainer.withAll( - additionalExtras().toSourceSetDependent().toAdditionalModifiers(), - getAnnotations().toSourceSetDependent().toAnnotations() - ) - ) - - private fun org.jetbrains.kotlin.descriptors.annotations.Annotations.getPresentableName(): String? = - mapNotNull { it.toAnnotation() }.singleOrNull { it.dri.classNames == "ParameterName" }?.params?.get("name") - .let { it as? StringValue }?.value?.let { unquotedValue(it) } - - private suspend fun KotlinType.toBound(): Bound { - suspend fun <T : AnnotationTarget> annotations(): PropertyContainer<T> = - getAnnotations().takeIf { it.isNotEmpty() }?.let { annotations -> - PropertyContainer.withAll(annotations.toSourceSetDependent().toAnnotations()) - } ?: PropertyContainer.empty() - - return when (this) { - is DynamicType -> Dynamic - is AbbreviatedType -> TypeAliased( - abbreviation.toBound(), - expandedType.toBound(), - annotations() - ) - is DefinitelyNotNullType -> DefinitelyNonNullable( - original.toBound() - ) - else -> when (val ctor = constructor.declarationDescriptor) { - is TypeParameterDescriptor -> TypeParameter( - dri = DRI.from(ctor), - name = ctor.name.asString(), - presentableName = annotations.getPresentableName(), - extra = annotations() - ) - is FunctionClassDescriptor -> FunctionalTypeConstructor( - DRI.from(ctor), - arguments.map { it.toProjection() }, - isExtensionFunction = isExtensionFunctionType || isBuiltinExtensionFunctionalType, - isSuspendable = isSuspendFunctionTypeOrSubtype, - presentableName = annotations.getPresentableName(), - extra = annotations() - ) - else -> GenericTypeConstructor( - DRI.from(ctor!!), // TODO: remove '!!' - arguments.map { it.toProjection() }, - annotations.getPresentableName(), - extra = annotations() - ) - }.let { - if (isMarkedNullable) Nullable(it) else it - } - } - } - - private suspend fun TypeProjection.toProjection(): Projection = - if (isStarProjection) Star else formPossiblyVariant() - - private suspend fun TypeProjection.formPossiblyVariant(): Projection = - type.toBound().wrapWithVariance(projectionKind) - - private fun TypeParameterDescriptor.variantTypeParameter(type: TypeParameter) = - type.wrapWithVariance(variance) - - private fun <T : Bound> T.wrapWithVariance(variance: org.jetbrains.kotlin.types.Variance) = - when (variance) { - org.jetbrains.kotlin.types.Variance.INVARIANT -> Invariance(this) - org.jetbrains.kotlin.types.Variance.IN_VARIANCE -> Contravariance(this) - org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Covariance(this) - } - - private fun descriptorToAnyDeclaration(descriptor: DeclarationDescriptor): PsiElement? { - val effectiveReferencedDescriptors = DescriptorToSourceUtils.getEffectiveReferencedDescriptors(descriptor) - //take any - return effectiveReferencedDescriptors.firstOrNull()?.let { DescriptorToSourceUtils.getSourceFromDescriptor(it) } - } - - private fun DeclarationDescriptor.resolveDocumentation(): DocumentationNode? { - val find = with(kDocFinder) { - find(::descriptorToAnyDeclaration) - } - - return (find?.let { - parseFromKDocTag( - kDocTag = it, - externalDri = { link: String -> - try { - val kdocLink = with(kDocFinder) { - resolveKDocLink( - fromDescriptor = this@resolveDocumentation, - qualifiedName = link, - sourceSet = sourceSet - ) - } - kdocLink.firstOrNull()?.let { - DRI.from( - it - ) - } - } catch (e1: IllegalArgumentException) { - logger.warn("Couldn't resolve link for $link") - null - } - }, - kdocLocation = toSourceElement.containingFile.name?.let { - val fqName = fqNameOrNull()?.asString() - if (fqName != null) "$it/$fqName" - else it - } - ) - } ?: getJavaDocs())?.takeIf { it.children.isNotEmpty() } - } - - private fun DeclarationDescriptor.getJavaDocs(): DocumentationNode? { - val overriddenDescriptors = (this as? CallableDescriptor)?.overriddenDescriptors ?: emptyList() - val allDescriptors = overriddenDescriptors + listOf(this) - return allDescriptors - .mapNotNull { it.findPsi() as? PsiNamedElement } - .firstOrNull() - ?.let { javadocParser.parseDocumentation(it) } - } - - private suspend fun ClassDescriptor.companion(dri: DRIWithPlatformInfo): DObject? = companionObjectDescriptor?.let { - objectDescriptor(it, dri) - } - - private fun MemberDescriptor.modifier() = when (modality) { - Modality.FINAL -> KotlinModifier.Final - Modality.SEALED -> KotlinModifier.Sealed - Modality.OPEN -> KotlinModifier.Open - Modality.ABSTRACT -> KotlinModifier.Abstract - else -> KotlinModifier.Empty - } - - private fun MemberDescriptor.createSources(): SourceSetDependent<DocumentableSource> = - DescriptorDocumentableSource(this).toSourceSetDependent() - - private fun FunctionDescriptor.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Infix.takeIf { isInfix }, - ExtraModifiers.KotlinOnlyModifiers.Inline.takeIf { isInline }, - ExtraModifiers.KotlinOnlyModifiers.Suspend.takeIf { isSuspend }, - ExtraModifiers.KotlinOnlyModifiers.Operator.takeIf { isOperator }, - ExtraModifiers.JavaOnlyModifiers.Static.takeIf { isJvmStaticInObjectOrClassOrInterface() }, - ExtraModifiers.KotlinOnlyModifiers.TailRec.takeIf { isTailrec }, - ExtraModifiers.KotlinOnlyModifiers.External.takeIf { isExternal }, - ExtraModifiers.KotlinOnlyModifiers.Override.takeIf { DescriptorUtils.isOverride(this) } - ).toSet() - - private fun ClassDescriptor.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Inline.takeIf { isInline }, - ExtraModifiers.KotlinOnlyModifiers.Value.takeIf { isValue }, - ExtraModifiers.KotlinOnlyModifiers.External.takeIf { isExternal }, - ExtraModifiers.KotlinOnlyModifiers.Inner.takeIf { isInner }, - ExtraModifiers.KotlinOnlyModifiers.Data.takeIf { isData }, - ExtraModifiers.KotlinOnlyModifiers.Fun.takeIf { isFun }, - ).toSet() - - private fun ValueParameterDescriptor.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.NoInline.takeIf { isNoinline }, - ExtraModifiers.KotlinOnlyModifiers.CrossInline.takeIf { isCrossinline }, - ExtraModifiers.KotlinOnlyModifiers.Const.takeIf { isConst }, - ExtraModifiers.KotlinOnlyModifiers.LateInit.takeIf { isLateInit }, - ExtraModifiers.KotlinOnlyModifiers.VarArg.takeIf { isVararg } - ).toSet() - - private fun TypeParameterDescriptor.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Reified.takeIf { isReified } - ).toSet() - - private fun PropertyDescriptor.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Const.takeIf { isConst }, - ExtraModifiers.KotlinOnlyModifiers.LateInit.takeIf { isLateInit }, - ExtraModifiers.JavaOnlyModifiers.Static.takeIf { isJvmStaticInObjectOrClassOrInterface() }, - ExtraModifiers.KotlinOnlyModifiers.External.takeIf { isExternal }, - ExtraModifiers.KotlinOnlyModifiers.Override.takeIf { DescriptorUtils.isOverride(this) } - ) - - private suspend fun Annotated.getAnnotations() = annotations.parallelMapNotNull { it.toAnnotation() } - - private fun ConstantValue<*>.toValue(): AnnotationParameterValue = when (this) { - is ConstantsAnnotationValue -> AnnotationValue(value.toAnnotation()) - is ConstantsArrayValue -> ArrayValue(value.map { it.toValue() }) - is ConstantsEnumValue -> EnumValue( - fullEnumEntryName(), - DRI(enumClassId.packageFqName.asString(), fullEnumEntryName()) - ) - is ConstantsKtClassValue -> when (val value = value) { - is NormalClass -> value.classId.let { - ClassValue( - it.relativeClassName.asString(), - DRI(it.packageFqName.asString(), it.relativeClassName.asString()) - ) - } - is LocalClass -> value.type.let { - ClassValue( - it.toString(), - DRI.from(it.constructor.declarationDescriptor as DeclarationDescriptor) - ) - } - } - is ConstantsFloatValue -> FloatValue(value) - is ConstantsDoubleValue -> DoubleValue(value) - is ConstantsUIntValue -> IntValue(value) - is ConstantsULongValue -> LongValue(value) - is ConstantsIntValue -> IntValue(value) - is ConstantsLongValue -> LongValue(value) - is ConstantsBooleanValue -> BooleanValue(value) - is ConstantsNullValue -> NullValue - else -> StringValue(unquotedValue(toString())) - } - - private fun AnnotationDescriptor.toAnnotation(scope: Annotations.AnnotationScope = Annotations.AnnotationScope.DIRECT): Annotations.Annotation = - Annotations.Annotation( - DRI.from(annotationClass as DeclarationDescriptor), - allValueArguments.map { it.key.asString() to it.value.toValue() }.toMap(), - mustBeDocumented(), - scope - ) - - private fun AnnotationDescriptor.mustBeDocumented(): Boolean = - if (source.toString() == "NO_SOURCE") false - else annotationClass?.annotations?.hasAnnotation(FqName("kotlin.annotation.MustBeDocumented")) ?: false - - private suspend fun PropertyDescriptor.getAnnotationsWithBackingField(): List<Annotations.Annotation> = - getAnnotations() + (backingField?.getAnnotations() ?: emptyList()) - - private fun List<Annotations.Annotation>.toAdditionalExtras() = mapNotNull { - try { - ExtraModifiers.valueOf(it.dri.classNames?.toLowerCase() ?: "") - } catch (e: IllegalArgumentException) { - null - } - } - - private fun <T : CallableMemberDescriptor> T.getConcreteDescriptor(): T { - return if (kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { - this - } else { - @Suppress("UNCHECKED_CAST") - overriddenDescriptors.first().getConcreteDescriptor() as T - } - } - - private fun ValueParameterDescriptor.getDefaultValue(): Expression? = - ((source as? KotlinSourceElement)?.psi as? KtParameter)?.defaultValue?.toDefaultValueExpression() - - private fun PropertyDescriptor.getDefaultValue(): Expression? = - (source as? KotlinSourceElement)?.psi?.children?.firstIsInstanceOrNull<KtConstantExpression>() - ?.toDefaultValueExpression() - - private fun ClassDescriptor.getAppliedConstructorParameters() = - (source as PsiSourceElement).psi?.children?.flatMap { - (it as? KtInitializerList)?.initializersAsExpression().orEmpty() - }.orEmpty() - - private fun KtInitializerList.initializersAsExpression() = - initializers.firstIsInstanceOrNull<KtCallElement>() - ?.getValueArgumentsInParentheses() - ?.map { it.getArgumentExpression()?.toDefaultValueExpression() ?: ComplexExpression("") } - .orEmpty() - - private fun KtExpression.toDefaultValueExpression(): Expression? = when (node?.elementType) { - KtNodeTypes.INTEGER_CONSTANT -> parseLong(node?.text)?.let { IntegerConstant(it) } - KtNodeTypes.FLOAT_CONSTANT -> if (node?.text?.toLowerCase()?.endsWith('f') == true) - parseFloat(node?.text)?.let { FloatConstant(it) } - else parseDouble(node?.text)?.let { DoubleConstant(it) } - KtNodeTypes.BOOLEAN_CONSTANT -> BooleanConstant(node?.text == "true") - KtNodeTypes.STRING_TEMPLATE -> StringConstant(node.findChildByType(KtNodeTypes.LITERAL_STRING_TEMPLATE_ENTRY)?.text.orEmpty()) - else -> node?.text?.let { ComplexExpression(it) } - } - - private data class ClassInfo(val ancestry: AncestryNode, val docs: SourceSetDependent<DocumentationNode>) { - val supertypes: List<TypeConstructorWithKind> - get() = listOfNotNull(ancestry.superclass?.let { - it.typeConstructor.let { - TypeConstructorWithKind( - it, - KotlinClassKindTypes.CLASS - ) - } - }) + ancestry.interfaces.map { TypeConstructorWithKind(it.typeConstructor, KotlinClassKindTypes.INTERFACE) } - } - - private fun DescriptorVisibility.toDokkaVisibility(): Visibility = when (this.delegate) { - Visibilities.Public -> KotlinVisibility.Public - Visibilities.Protected -> KotlinVisibility.Protected - Visibilities.Internal -> KotlinVisibility.Internal - Visibilities.Private, Visibilities.PrivateToThis -> KotlinVisibility.Private - JavaVisibilities.ProtectedAndPackage -> KotlinVisibility.Protected - JavaVisibilities.ProtectedStaticVisibility -> KotlinVisibility.Protected - JavaVisibilities.PackageVisibility -> JavaVisibility.Default - else -> KotlinVisibility.Public - } - - private fun ConstantsEnumValue.fullEnumEntryName() = - "${this.enumClassId.relativeClassName.asString()}.${this.enumEntryName.identifier}" - - private fun DeclarationDescriptorWithSource.ktFile(): KtFile? = - (source.containingFile as? PsiSourceFile)?.psiFile as? KtFile - - private suspend fun DeclarationDescriptorWithSource.fileLevelAnnotations() = ktFile() - ?.let { file -> - analysisContext.resolveSession.getFileAnnotations(file) - } - ?.toList() - ?.parallelMap { it.toAnnotation(scope = Annotations.AnnotationScope.FILE) } - .orEmpty() - - private fun AncestryNode.exceptionInSupertypesOrNull(): ExceptionInSupertypes? = - typeConstructorsBeingExceptions().takeIf { it.isNotEmpty() }?.let { ExceptionInSupertypes(it.toSourceSetDependent()) } -} - diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultExternalDocumentablesProvider.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultExternalDocumentablesProvider.kt deleted file mode 100644 index 006a990b..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultExternalDocumentablesProvider.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.DClasslike -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.analysis.kotlin.internal.ExternalDocumentablesProvider -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.PackageViewDescriptor -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered - -internal class DefaultExternalDocumentablesProvider(context: DokkaContext) : ExternalDocumentablesProvider { - private val analysis = context.plugin<CompilerDescriptorAnalysisPlugin>().querySingle { kotlinAnalysis } - - private val translator: ExternalClasslikesTranslator = DefaultDescriptorToDocumentableTranslator(context) - - override fun findClasslike(dri: DRI, sourceSet: DokkaSourceSet): DClasslike? { - val pkg = dri.packageName?.let { FqName(it) } ?: FqName.ROOT - val names = dri.classNames?.split('.') ?: return null - - val packageDsc = analysis[sourceSet].moduleDescriptor.getPackage(pkg) - val classDsc = names.fold<String, DeclarationDescriptor?>(packageDsc) { dsc, name -> - dsc?.scope?.getDescriptorsFiltered { it.identifier == name } - ?.filterIsInstance<ClassDescriptor>() - ?.firstOrNull() - } - - return (classDsc as? ClassDescriptor)?.let { translator.translateClassDescriptor(it, sourceSet) } - } - - private val DeclarationDescriptor.scope: MemberScope - get() = when (this) { - is PackageViewDescriptor -> memberScope - is ClassDescriptor -> unsubstitutedMemberScope - else -> throw IllegalArgumentException("Unexpected type of descriptor: ${this::class}") - } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DescriptorAccessorConventionUtil.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DescriptorAccessorConventionUtil.kt deleted file mode 100644 index b350e035..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DescriptorAccessorConventionUtil.kt +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor -import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName -import org.jetbrains.kotlin.load.java.propertyNamesBySetMethodName - -internal data class DescriptorFunctionsHolder( - val regularFunctions: List<FunctionDescriptor>, - val accessors: Map<PropertyDescriptor, DescriptorAccessorHolder> -) - -internal data class DescriptorAccessorHolder( - val getter: FunctionDescriptor? = null, - val setter: FunctionDescriptor? = null -) - -/** - * Separate regular Kotlin/Java functions and inherited Java accessors - * to properly display properties inherited from Java. - * - * Take this example: - * ``` - * // java - * public class JavaClass { - * private int a = 1; - * public int getA() { return a; } - * public void setA(int a) { this.a = a; } - * } - * - * // kotlin - * class Bar : JavaClass() { - * fun foo() {} - * } - * ``` - * - * It should result in: - * - 1 regular function `foo` - * - Map a=[`getA`, `setA`] - */ -internal fun splitFunctionsAndInheritedAccessors( - properties: List<PropertyDescriptor>, - functions: List<FunctionDescriptor> -): DescriptorFunctionsHolder { - val (javaMethods, kotlinFunctions) = functions.partition { it is JavaMethodDescriptor } - if (javaMethods.isEmpty()) { - return DescriptorFunctionsHolder(regularFunctions = kotlinFunctions, emptyMap()) - } - - val propertiesByName = properties.associateBy { it.name.asString() } - val regularFunctions = ArrayList<FunctionDescriptor>(kotlinFunctions) - - val accessors = mutableMapOf<PropertyDescriptor, DescriptorAccessorHolder>() - javaMethods.forEach { function -> - val possiblePropertyNamesForFunction = function.toPossiblePropertyNames() - val property = possiblePropertyNamesForFunction.firstNotNullOfOrNull { propertiesByName[it] } - if (property != null && function.isAccessorFor(property)) { - accessors.compute(property) { prop, accessorHolder -> - if (function.isGetterFor(prop)) - accessorHolder?.copy(getter = function) ?: DescriptorAccessorHolder(getter = function) - else - accessorHolder?.copy(setter = function) ?: DescriptorAccessorHolder(setter = function) - } - } else { - regularFunctions.add(function) - } - } - - val accessorLookalikes = removeNonAccessorsReturning(accessors) - regularFunctions.addAll(accessorLookalikes) - - return DescriptorFunctionsHolder(regularFunctions, accessors) -} - -/** - * If a field has no getter, it's not accessible as a property from Kotlin's perspective, - * but it still might have a setter lookalike. In this case, this "setter" should be just a regular function - * - * @return removed elements - */ -private fun removeNonAccessorsReturning( - propertyAccessors: MutableMap<PropertyDescriptor, DescriptorAccessorHolder> -): List<FunctionDescriptor> { - val nonAccessors = mutableListOf<FunctionDescriptor>() - propertyAccessors.entries.removeIf { (_, accessors) -> - if (accessors.getter == null && accessors.setter != null) { - nonAccessors.add(accessors.setter) - true - } else { - false - } - } - return nonAccessors -} - -private fun FunctionDescriptor.toPossiblePropertyNames(): List<String> { - val stringName = this.name.asString() - return when { - JvmAbi.isSetterName(stringName) -> propertyNamesBySetMethodName(this.name).map { it.asString() } - JvmAbi.isGetterName(stringName) -> propertyNamesByGetMethod(this) - else -> listOf() - } -} - -private fun propertyNamesByGetMethod(functionDescriptor: FunctionDescriptor): List<String> { - val stringName = functionDescriptor.name.asString() - // In java, the convention for boolean property accessors is as follows: - // - `private boolean active;` - // - `private boolean isActive();` - // - // Whereas in Kotlin, because there are no explicit accessors, the convention is - // - `val isActive: Boolean` - // - // This makes it difficult to guess the name of the accessor property in case of Java - val javaPropName = if (functionDescriptor is JavaMethodDescriptor && JvmAbi.startsWithIsPrefix(stringName)) { - val javaPropName = stringName.removePrefix("is").let { newName -> - newName.replaceFirst(newName[0], newName[0].toLowerCase()) - } - javaPropName - } else { - null - } - val kotlinPropName = propertyNameByGetMethodName(functionDescriptor.name)?.asString() - return listOfNotNull(javaPropName, kotlinPropName) -} - -private fun FunctionDescriptor.isAccessorFor(property: PropertyDescriptor): Boolean { - return (this.isGetterFor(property) || this.isSetterFor(property)) - && !property.visibility.isPublicAPI - && this.visibility.isPublicAPI -} - -private fun FunctionDescriptor.isGetterFor(property: PropertyDescriptor): Boolean { - return this.returnType == property.returnType - && this.valueParameters.isEmpty() -} - -private fun FunctionDescriptor.isSetterFor(property: PropertyDescriptor): Boolean { - return this.valueParameters.size == 1 - && this.valueParameters[0].type == property.returnType -} - diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/ExternalClasslikesTranslator.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/ExternalClasslikesTranslator.kt deleted file mode 100644 index 7a305bc1..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/ExternalClasslikesTranslator.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.model.DClasslike -import org.jetbrains.kotlin.descriptors.ClassDescriptor - -/** - * Service translating [ClassDescriptor]s of symbols defined outside of documented project to [DClasslike]s. - */ -internal fun interface ExternalClasslikesTranslator { - fun translateClassDescriptor(descriptor: ClassDescriptor, sourceSet: DokkaSourceSet): DClasslike -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/KdocMarkdownParser.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/KdocMarkdownParser.kt deleted file mode 100644 index 7c304e39..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/KdocMarkdownParser.kt +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser.Companion.fqDeclarationName -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.model.doc.Suppress -import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag -import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag - -internal fun parseFromKDocTag( - kDocTag: KDocTag?, - externalDri: (String) -> DRI?, - kdocLocation: String?, - parseWithChildren: Boolean = true -): DocumentationNode { - return if (kDocTag == null) { - DocumentationNode(emptyList()) - } else { - fun parseStringToDocNode(text: String) = - MarkdownParser(externalDri, kdocLocation).parseStringToDocNode(text) - - fun pointedLink(tag: KDocTag): DRI? = (parseStringToDocNode("[${tag.getSubjectName()}]")).let { - val link = it.children[0].children[0] - if (link is DocumentationLink) link.dri else null - } - - val allTags = - listOf(kDocTag) + if (kDocTag.canHaveParent() && parseWithChildren) getAllKDocTags(findParent(kDocTag)) else emptyList() - DocumentationNode( - allTags.map { - when (it.knownTag) { - null -> if (it.name == null) Description(parseStringToDocNode(it.getContent())) else CustomTagWrapper( - parseStringToDocNode(it.getContent()), - it.name!! - ) - KDocKnownTag.AUTHOR -> Author(parseStringToDocNode(it.getContent())) - KDocKnownTag.THROWS -> { - val dri = pointedLink(it) - Throws( - parseStringToDocNode(it.getContent()), - dri?.fqDeclarationName() ?: it.getSubjectName().orEmpty(), - dri, - ) - } - KDocKnownTag.EXCEPTION -> { - val dri = pointedLink(it) - Throws( - parseStringToDocNode(it.getContent()), - dri?.fqDeclarationName() ?: it.getSubjectName().orEmpty(), - dri - ) - } - KDocKnownTag.PARAM -> Param( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.RECEIVER -> Receiver(parseStringToDocNode(it.getContent())) - KDocKnownTag.RETURN -> Return(parseStringToDocNode(it.getContent())) - KDocKnownTag.SEE -> { - val dri = pointedLink(it) - See( - parseStringToDocNode(it.getContent()), - dri?.fqDeclarationName() ?: it.getSubjectName().orEmpty(), - dri, - ) - } - KDocKnownTag.SINCE -> Since(parseStringToDocNode(it.getContent())) - KDocKnownTag.CONSTRUCTOR -> Constructor(parseStringToDocNode(it.getContent())) - KDocKnownTag.PROPERTY -> Property( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.SAMPLE -> Sample( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.SUPPRESS -> Suppress(parseStringToDocNode(it.getContent())) - } - } - ) - } -} - -//Horrible hack but since link resolution is passed as a function i am not able to resolve them otherwise -@kotlin.Suppress("DeprecatedCallableAddReplaceWith") -@Deprecated("This function makes wrong assumptions and is missing a lot of corner cases related to generics, " + - "parameters and static members. This is not supposed to be public API and will not be supported in the future") -internal fun DRI.fqName(): String? = "$packageName.$classNames".takeIf { packageName != null && classNames != null } - -private fun findParent(kDoc: PsiElement): PsiElement = - if (kDoc.canHaveParent()) findParent(kDoc.parent) else kDoc - -private fun PsiElement.canHaveParent(): Boolean = this is KDocSection && knownTag != KDocKnownTag.PROPERTY - -private fun getAllKDocTags(kDocImpl: PsiElement): List<KDocTag> = - kDocImpl.children.filterIsInstance<KDocTag>().filterNot { it is KDocSection } + kDocImpl.children.flatMap { - getAllKDocTags(it) - } diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/SyntheticDescriptorDocumentationProvider.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/SyntheticDescriptorDocumentationProvider.kt deleted file mode 100644 index cff24590..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/SyntheticDescriptorDocumentationProvider.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.from -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.resolve.DescriptorFactory -import org.jetbrains.kotlin.resolve.DescriptorUtils - -private const val ENUM_ENTRIES_TEMPLATE_PATH = "/dokka/docs/kdoc/EnumEntries.kt.template" -private const val ENUM_VALUEOF_TEMPLATE_PATH = "/dokka/docs/kdoc/EnumValueOf.kt.template" -private const val ENUM_VALUES_TEMPLATE_PATH = "/dokka/docs/kdoc/EnumValues.kt.template" - -internal class SyntheticDescriptorDocumentationProvider( - private val kDocFinder: KDocFinder, - private val sourceSet: DokkaConfiguration.DokkaSourceSet -) { - fun isDocumented(descriptor: DeclarationDescriptor): Boolean { - return when(descriptor) { - is PropertyDescriptor -> descriptor.isEnumEntries() - is FunctionDescriptor -> { - DescriptorFactory.isEnumValuesMethod(descriptor) || DescriptorFactory.isEnumValueOfMethod(descriptor) - } - else -> false - } - } - - private fun PropertyDescriptor.isEnumEntries(): Boolean { - return this.name == StandardNames.ENUM_ENTRIES - && this.kind == CallableMemberDescriptor.Kind.SYNTHESIZED - && DescriptorUtils.isEnumClass(this.containingDeclaration) - } - - fun getDocumentation(descriptor: DeclarationDescriptor): DocumentationNode? { - return when(descriptor) { - is PropertyDescriptor -> descriptor.getDocumentation() - is FunctionDescriptor -> descriptor.getDocumentation() - else -> null - } - } - - private fun PropertyDescriptor.getDocumentation(): DocumentationNode? { - return when { - this.isEnumEntries() -> loadTemplate(this, ENUM_ENTRIES_TEMPLATE_PATH) - else -> null - } - } - - private fun FunctionDescriptor.getDocumentation(): DocumentationNode? { - return when { - DescriptorFactory.isEnumValuesMethod(this) -> loadTemplate(this, ENUM_VALUES_TEMPLATE_PATH) - DescriptorFactory.isEnumValueOfMethod(this) -> loadTemplate(this, ENUM_VALUEOF_TEMPLATE_PATH) - else -> null - } - } - - private fun loadTemplate(descriptor: DeclarationDescriptor, filePath: String): DocumentationNode? { - val kdoc = loadContent(filePath) ?: return null - val parser = MarkdownParser({ link -> resolveLink(descriptor, link)}, filePath) - return parser.parse(kdoc) - } - - private fun loadContent(filePath: String): String? = javaClass.getResource(filePath)?.readText() - - private fun resolveLink(descriptor: DeclarationDescriptor, link: String): DRI? = - kDocFinder.resolveKDocLink( - fromDescriptor = descriptor, - qualifiedName = link, - sourceSet = sourceSet - ).firstOrNull()?.let { DRI.from(it) } -} diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/annotationsValue.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/annotationsValue.kt deleted file mode 100644 index 6944ac1d..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/annotationsValue.kt +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -internal fun unquotedValue(value: String): String = value.removeSurrounding("\"") diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/isException.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/isException.kt deleted file mode 100644 index e484f37a..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/isException.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator - -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.AncestryNode -import org.jetbrains.dokka.model.TypeConstructor - -internal fun AncestryNode.typeConstructorsBeingExceptions(): List<TypeConstructor> { - fun traverseSupertypes(ancestry: AncestryNode): List<TypeConstructor> = - listOf(ancestry.typeConstructor) + (ancestry.superclass?.let(::traverseSupertypes) ?: emptyList()) - - return superclass?.let(::traverseSupertypes)?.filter { type -> type.dri.isDirectlyAnException() } ?: emptyList() -} - -internal fun DRI.isDirectlyAnException(): Boolean = - toString().let { stringed -> - stringed == "kotlin/Exception///PointingToDeclaration/" || - stringed == "java.lang/Exception///PointingToDeclaration/" - } diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin b/subprojects/analysis-kotlin-descriptors/compiler/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin deleted file mode 100644 index 0d7ee9f6..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin +++ /dev/null @@ -1,5 +0,0 @@ -# -# Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. -# - -org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin diff --git a/subprojects/analysis-kotlin-descriptors/compiler/src/test/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ParseModuleAndPackageDocumentationFragmentsTest.kt b/subprojects/analysis-kotlin-descriptors/compiler/src/test/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ParseModuleAndPackageDocumentationFragmentsTest.kt deleted file mode 100644 index 76be1384..00000000 --- a/subprojects/analysis-kotlin-descriptors/compiler/src/test/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ParseModuleAndPackageDocumentationFragmentsTest.kt +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors - - -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.* -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier.Module -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.moduledocs.ModuleAndPackageDocumentation.Classifier.Package -import org.jetbrains.dokka.analysis.markdown.jb.MARKDOWN_ELEMENT_FILE_NAME -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.utilities.DokkaLogger -import org.junit.jupiter.api.io.TempDir -import java.nio.file.Path -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertTrue - -class ParseModuleAndPackageDocumentationFragmentsTest { - - private fun testBasicExample(lineSeperator: String = "\n") { - val source = source( - """ - # Module kotlin-demo - Module description - - # Package org.jetbrains.kotlin.demo - Package demo description - ## Level 2 heading - Heading 2\r\n - - # Package org.jetbrains.kotlin.demo2 - Package demo2 description - """.trimIndent().replace("\n", lineSeperator) - ) - val fragments = parseModuleAndPackageDocumentationFragments(source) - - assertEquals( - listOf( - ModuleAndPackageDocumentationFragment( - classifier = Module, - name = "kotlin-demo", - documentation = "Module description", - source = source - ), - ModuleAndPackageDocumentationFragment( - classifier = Package, - name = "org.jetbrains.kotlin.demo", - documentation = "Package demo description${lineSeperator}## Level 2 heading${lineSeperator}Heading 2\\r\\n", - source = source - ), - ModuleAndPackageDocumentationFragment( - classifier = Package, - name = "org.jetbrains.kotlin.demo2", - documentation = "Package demo2 description", - source = source - ) - ), - fragments - ) - } - - @Test - fun `basic example`() { - testBasicExample() - } - - @Test - fun `CRLF line seperators`() { - testBasicExample("\r\n") - } - - @Test - fun `no module name specified fails`() { - val exception = assertFailsWith<IllegalModuleAndPackageDocumentation> { - parseModuleAndPackageDocumentationFragments( - source( - """ - # Module - No module name given - """.trimIndent() - ) - ) - } - - assertTrue( - "Missing Module name" in exception.message.orEmpty(), - "Expected 'Missing Module name' in error message" - ) - } - - @Test - fun `no package name specified does not fail`() { - val source = source( - """ - # Package - This is a root package - """.trimIndent() - ) - val fragments = parseModuleAndPackageDocumentationFragments(source) - assertEquals(1, fragments.size, "Expected a single package fragment") - - assertEquals( - ModuleAndPackageDocumentationFragment( - name = "", - classifier = Package, - documentation = "This is a root package", - source = source - ), - fragments.single() - ) - } - - @Test - fun `white space in module name is supported`() { - val fragment = parseModuleAndPackageDocumentationFragments( - source( - """ - # Module My Module - Documentation for my module - """.trimIndent() - ) - ) - - assertEquals( - Module, fragment.single().classifier, - "Expected module being parsec" - ) - - assertEquals( - "My Module", fragment.single().name, - "Expected module name with white spaces being parsed" - ) - - assertEquals( - "Documentation for my module", fragment.single().documentation, - "Expected documentation being available" - ) - } - - @Test - fun `white space in package name fails`() { - val exception = assertFailsWith<IllegalModuleAndPackageDocumentation> { - parseModuleAndPackageDocumentationFragments( - source( - """ - # Package my package - """.trimIndent() - ) - ) - } - - assertTrue( - "Package my package" in exception.message.orEmpty(), - "Expected problematic statement in error message" - ) - } - - @Test - fun `multiple whitespaces are supported in first line`() { - val source = source( - """ - # Module my-module - My Module - # Package com.my.package - My Package - """.trimIndent() - ) - val fragments = parseModuleAndPackageDocumentationFragments(source) - - assertEquals( - listOf( - ModuleAndPackageDocumentationFragment( - classifier = Module, - name = "my-module", - documentation = "My Module", - source = source - ), - ModuleAndPackageDocumentationFragment( - classifier = Package, - name = "com.my.package", - documentation = "My Package", - source = source - ) - ), - fragments - ) - } - - @Test - fun `parse from file`(@TempDir temporaryFolder: Path) { - val file = temporaryFolder.resolve("other.md").toFile() - file.writeText( - """ - # Module MyModule - D1 - # Package com.sample - D2 - """.trimIndent() - ) - - assertEquals( - listOf( - ModuleAndPackageDocumentationFragment( - classifier = Module, - name = "MyModule", - documentation = "D1", - source = ModuleAndPackageDocumentationFile(file) - ), - ModuleAndPackageDocumentationFragment( - classifier = Package, - name = "com.sample", - documentation = "D2", - source = ModuleAndPackageDocumentationFile(file) - ) - ), - parseModuleAndPackageDocumentationFragments(file) - ) - } - - @Test - fun `at in code block is supported`() { - val fragment = parseModuleAndPackageDocumentationFragments( - source( - """ - # Module My Module - ``` - @Smth - ``` - @author Smb - """.trimIndent() - ) - ) - - assertEquals( - "```\n" + - "@Smth\n" + - "```\n" + - "@author Smb", fragment.single().documentation, - "Expected documentation being available" - ) - - val parsingContext = ModuleAndPackageDocumentationParsingContext(object : DokkaLogger { - override var warningsCount: Int = 0 - override var errorsCount: Int = 0 - override fun debug(message: String) {} - override fun info(message: String) {} - override fun progress(message: String) {} - override fun warn(message: String) {} - override fun error(message: String) {} - }) - val parsedFragment = parseModuleAndPackageDocumentation(parsingContext, fragment.single()) - val expectedDocumentationNode = DocumentationNode( - listOf( - Description( - CustomDocTag( - listOf( - CodeBlock( - listOf( - Text("@Smth") - ) - ) - ), name = MARKDOWN_ELEMENT_FILE_NAME - ) - ), - Author( - CustomDocTag( - listOf( - P(listOf(Text("Smb"))) - ), name = MARKDOWN_ELEMENT_FILE_NAME - ) - ) - ) - ) - assertEquals( - expectedDocumentationNode, parsedFragment.documentation - ) - } - - private fun source(documentation: String): ModuleAndPackageDocumentationSource = - object : ModuleAndPackageDocumentationSource() { - override val sourceDescription: String = "inline test" - override val documentation: String = documentation - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/README.md b/subprojects/analysis-kotlin-descriptors/ide/README.md deleted file mode 100644 index 14ed5baa..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Descriptors: IDE - -An internal module that encapsulates external IDE (`org.jetbrains.kotlin:idea`) dependencies. - -IDE artifacts are reused for things that are not possible to do with the Kotlin compiler API, such -as KDoc or KLib parsing/processing, because Dokka is very similar to an IDE when it comes to analyzing -source code and docs. - -Exists primarily to make sure that unreliable and coupled external dependencies are somewhat abstracted away, -otherwise everything gets tangled together and breaking changes in such dependencies become very -difficult to resolve. diff --git a/subprojects/analysis-kotlin-descriptors/ide/api/ide.api b/subprojects/analysis-kotlin-descriptors/ide/api/ide.api deleted file mode 100644 index a59658a3..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/api/ide.api +++ /dev/null @@ -1,4 +0,0 @@ -public final class org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorAnalysisPlugin : org/jetbrains/dokka/plugability/DokkaPlugin { - public fun <init> ()V -} - diff --git a/subprojects/analysis-kotlin-descriptors/ide/build.gradle.kts b/subprojects/analysis-kotlin-descriptors/ide/build.gradle.kts deleted file mode 100644 index 9783a71c..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -plugins { - id("org.jetbrains.conventions.kotlin-jvm") -} - -dependencies { - compileOnly(projects.core) - compileOnly(projects.subprojects.analysisKotlinApi) - - implementation(projects.subprojects.analysisKotlinDescriptors.compiler) - - // TODO [beresnev] get rid of it - compileOnly(libs.kotlinx.coroutines.core) -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/CoreKotlinCacheService.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/CoreKotlinCacheService.kt deleted file mode 100644 index 2a299009..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/CoreKotlinCacheService.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.caches.resolve.PlatformAnalysisSettings -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache - - -internal class CoreKotlinCacheService(private val resolutionFacade: DokkaResolutionFacade) : KotlinCacheService { - override fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacade(element: KtElement): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeByFile( - file: PsiFile, - platform: TargetPlatform - ): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeByModuleInfo( - moduleInfo: ModuleInfo, - settings: PlatformAnalysisSettings - ): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeByModuleInfo( - moduleInfo: ModuleInfo, - platform: TargetPlatform - ): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeWithForcedPlatform( - elements: List<KtElement>, - platform: TargetPlatform - ): ResolutionFacade { - return resolutionFacade - } - - override fun getSuppressionCache(): KotlinSuppressCache { - throw UnsupportedOperationException() - } - -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/DokkaResolutionFacade.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/DokkaResolutionFacade.kt deleted file mode 100644 index 1ded0495..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/DokkaResolutionFacade.kt +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -@file:OptIn(FrontendInternals::class) - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import com.google.common.collect.ImmutableMap -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.analyzer.AnalysisResult -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.analyzer.ResolverForModule -import org.jetbrains.kotlin.analyzer.ResolverForProject -import org.jetbrains.kotlin.container.getService -import org.jetbrains.kotlin.container.tryGetService -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.diagnostics.DiagnosticSink -import org.jetbrains.kotlin.idea.FrontendInternals -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice -import org.jetbrains.kotlin.util.slicedMap.WritableSlice - -internal class DokkaResolutionFacade( - override val project: Project, - override val moduleDescriptor: ModuleDescriptor, - val resolverForModule: ResolverForModule -) : ResolutionFacade { - override fun analyzeWithAllCompilerChecks( - elements: Collection<KtElement>, - callback: DiagnosticSink.DiagnosticsCallback? - ): AnalysisResult { - throw UnsupportedOperationException() - } - - @OptIn(FrontendInternals::class) - override fun <T : Any> tryGetFrontendService(element: PsiElement, serviceClass: Class<T>): T? { - return resolverForModule.componentProvider.tryGetService(serviceClass) - } - - override fun resolveToDescriptor( - declaration: KtDeclaration, - bodyResolveMode: BodyResolveMode - ): DeclarationDescriptor { - return resolveSession.resolveToDescriptor(declaration) - } - - override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext { - throw UnsupportedOperationException() - } - - val resolveSession: ResolveSession get() = getFrontendService(ResolveSession::class.java) - - override fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode): BindingContext { - if (element is KtDeclaration) { - val descriptor = resolveToDescriptor(element) - return object : BindingContext { - override fun <K : Any?, V : Any?> getKeys(p0: WritableSlice<K, V>?): Collection<K> { - throw UnsupportedOperationException() - } - - override fun getType(p0: KtExpression): KotlinType? { - throw UnsupportedOperationException() - } - - override fun <K : Any?, V : Any?> get(slice: ReadOnlySlice<K, V>?, key: K): V? { - if (key != element) { - throw UnsupportedOperationException() - } - @Suppress("UNCHECKED_CAST") - return when { - slice == BindingContext.DECLARATION_TO_DESCRIPTOR -> descriptor as V - slice == BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER && (element as KtParameter).hasValOrVar() -> descriptor as V - else -> null - } - } - - override fun getDiagnostics(): Diagnostics { - throw UnsupportedOperationException() - } - - override fun addOwnDataTo(p0: BindingTrace, p1: Boolean) { - throw UnsupportedOperationException() - } - - override fun <K : Any?, V : Any?> getSliceContents(p0: ReadOnlySlice<K, V>): ImmutableMap<K, V> { - throw UnsupportedOperationException() - } - - } - } - throw UnsupportedOperationException() - } - - override fun <T : Any> getFrontendService(element: PsiElement, serviceClass: Class<T>): T { - throw UnsupportedOperationException() - } - - override fun <T : Any> getFrontendService(serviceClass: Class<T>): T { - return resolverForModule.componentProvider.getService(serviceClass) - } - - @Deprecated("DO NOT USE IT AS IT IS A ROOT CAUSE OF KTIJ-17649") - override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T { - return resolverForModule.componentProvider.getService(serviceClass) - } - - override fun <T : Any> getIdeService(serviceClass: Class<T>): T { - throw UnsupportedOperationException() - } - - override fun getResolverForProject(): ResolverForProject<out ModuleInfo> { - throw UnsupportedOperationException() - } - -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeAnalysisContextCreator.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeAnalysisContextCreator.kt deleted file mode 100644 index 252fbd55..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeAnalysisContextCreator.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import com.intellij.mock.MockComponentManager -import com.intellij.mock.MockProject -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.AnalysisContextCreator -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisContext -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisEnvironment -import org.jetbrains.kotlin.analyzer.ResolverForModule -import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.descriptors.ModuleDescriptor - -internal class IdeAnalysisContextCreator : AnalysisContextCreator { - override fun create( - project: MockProject, - moduleDescriptor: ModuleDescriptor, - moduleResolver: ResolverForModule, - kotlinEnvironment: KotlinCoreEnvironment, - analysisEnvironment: AnalysisEnvironment, - ): AnalysisContext { - val facade = DokkaResolutionFacade(project, moduleDescriptor, moduleResolver) - val projectComponentManager = project as MockComponentManager - projectComponentManager.registerService( - KotlinCacheService::class.java, - CoreKotlinCacheService(facade) - ) - return ResolutionFacadeAnalysisContext(facade, kotlinEnvironment, analysisEnvironment) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorAnalysisPlugin.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorAnalysisPlugin.kt deleted file mode 100644 index e170b740..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorAnalysisPlugin.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.plugability.DokkaPluginApiPreview -import org.jetbrains.dokka.plugability.PluginApiPreviewAcknowledgement - -@InternalDokkaApi -public class IdeDescriptorAnalysisPlugin : DokkaPlugin() { - - internal val ideKdocFinder by extending { - plugin<CompilerDescriptorAnalysisPlugin>().kdocFinder providing ::IdePluginKDocFinder - } - - internal val ideDescriptorFinder by extending { - plugin<CompilerDescriptorAnalysisPlugin>().descriptorFinder providing { IdeDescriptorFinder() } - } - - internal val ideKlibService by extending { - plugin<CompilerDescriptorAnalysisPlugin>().klibService providing { IdeKLibService() } - } - - internal val ideApplicationHack by extending { - plugin<CompilerDescriptorAnalysisPlugin>().mockApplicationHack providing { IdeMockApplicationHack() } - } - - internal val ideAnalysisContextCreator by extending { - plugin<CompilerDescriptorAnalysisPlugin>().analysisContextCreator providing { IdeAnalysisContextCreator() } - } - - @OptIn(DokkaPluginApiPreview::class) - override fun pluginApiPreviewAcknowledgement(): PluginApiPreviewAcknowledgement = PluginApiPreviewAcknowledgement -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorFinder.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorFinder.kt deleted file mode 100644 index 7a1e04e4..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeDescriptorFinder.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.DescriptorFinder -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode - -internal class IdeDescriptorFinder : DescriptorFinder { - override fun KtDeclaration.findDescriptor(): DeclarationDescriptor? { - return if (this is KtParameter) this.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) else this.resolveToDescriptorIfAny( - BodyResolveMode.FULL - ) - } - -} - - diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeKLibService.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeKLibService.kt deleted file mode 100644 index e1c0eb31..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeKLibService.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KLibService -import org.jetbrains.kotlin.library.metadata.KlibMetadataModuleDescriptorFactory -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.idea.klib.CachingIdeKlibMetadataLoader -import org.jetbrains.kotlin.idea.klib.compatibilityInfo -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration -import org.jetbrains.kotlin.storage.StorageManager - -internal class IdeKLibService : KLibService { - override fun KotlinLibrary.createPackageFragmentProvider( - storageManager: StorageManager, - metadataModuleDescriptorFactory: KlibMetadataModuleDescriptorFactory, - languageVersionSettings: LanguageVersionSettings, - moduleDescriptor: ModuleDescriptor, - lookupTracker: LookupTracker, - ): PackageFragmentProvider? { - return this.createKlibPackageFragmentProvider( - storageManager, metadataModuleDescriptorFactory, languageVersionSettings, moduleDescriptor, lookupTracker - ) - } - - override fun isAnalysisCompatible(kotlinLibrary: KotlinLibrary): Boolean { - return kotlinLibrary.compatibilityInfo.isCompatible - } -} - -internal fun KotlinLibrary.createKlibPackageFragmentProvider( - storageManager: StorageManager, - metadataModuleDescriptorFactory: KlibMetadataModuleDescriptorFactory, - languageVersionSettings: LanguageVersionSettings, - moduleDescriptor: ModuleDescriptor, - lookupTracker: LookupTracker -): PackageFragmentProvider? { - if (!compatibilityInfo.isCompatible) return null - - val packageFragmentNames = CachingIdeKlibMetadataLoader.loadModuleHeader(this).packageFragmentNameList - - return metadataModuleDescriptorFactory.createPackageFragmentProvider( - library = this, - packageAccessHandler = CachingIdeKlibMetadataLoader, - packageFragmentNames = packageFragmentNames, - storageManager = storageManager, - moduleDescriptor = moduleDescriptor, - configuration = CompilerDeserializationConfiguration(languageVersionSettings), - compositePackageFragmentAddend = null, - lookupTracker = lookupTracker - ) -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeMockApplicationHack.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeMockApplicationHack.kt deleted file mode 100644 index 2bc83504..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdeMockApplicationHack.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import com.intellij.mock.MockApplication -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.MockApplicationHack -import org.jetbrains.kotlin.idea.klib.KlibLoadingMetadataCache - -internal class IdeMockApplicationHack : MockApplicationHack { - override fun hack(mockApplication: MockApplication) { - if (mockApplication.getService(KlibLoadingMetadataCache::class.java) == null) - mockApplication.registerService(KlibLoadingMetadataCache::class.java, KlibLoadingMetadataCache()) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdePluginKDocFinder.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdePluginKDocFinder.kt deleted file mode 100644 index 13119602..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/IdePluginKDocFinder.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.CompilerDescriptorAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KDocFinder -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.idea.kdoc.findKDoc -import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils - -internal class IdePluginKDocFinder( - private val context: DokkaContext -) : KDocFinder { - - override fun KtElement.findKDoc(): KDocTag? { - return this.findKDoc { DescriptorToSourceUtils.descriptorToDeclaration(it) }?.contentTag - } - - override fun DeclarationDescriptor.find(descriptorToPsi: (DeclarationDescriptorWithSource) -> PsiElement?): KDocTag? { - return this.findKDoc(descriptorToPsi)?.contentTag - } - - override fun resolveKDocLink( - fromDescriptor: DeclarationDescriptor, - qualifiedName: String, - sourceSet: DokkaConfiguration.DokkaSourceSet, - emptyBindingContext: Boolean - ): Collection<DeclarationDescriptor> { - val facadeAnalysisContext = context - .plugin<CompilerDescriptorAnalysisPlugin>() - .querySingle { kotlinAnalysis }[sourceSet] as ResolutionFacadeAnalysisContext - - return org.jetbrains.kotlin.idea.kdoc.resolveKDocLink( - context = if (emptyBindingContext) BindingContext.EMPTY else facadeAnalysisContext.resolveSession.bindingContext, - resolutionFacade = facadeAnalysisContext.facade, - fromDescriptor = fromDescriptor, - fromSubjectOfTag = null, - qualifiedName = qualifiedName.split('.'), - contextElement = fromDescriptor.findPsi() - ) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/ResolutionFacadeAnalysisContext.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/ResolutionFacadeAnalysisContext.kt deleted file mode 100644 index d70aeb99..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/ide/ResolutionFacadeAnalysisContext.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.descriptors.ide - -import com.intellij.openapi.project.Project -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisContext -import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.AnalysisEnvironment -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.resolve.lazy.ResolveSession - -internal class ResolutionFacadeAnalysisContext( - val facade: DokkaResolutionFacade, - - private val kotlinEnvironment: KotlinCoreEnvironment, - private val analysisEnvironment: AnalysisEnvironment -) : AnalysisContext { - private var isClosed: Boolean = false - - override val environment: KotlinCoreEnvironment - get() = kotlinEnvironment.takeUnless { isClosed } - ?: throw IllegalStateException("AnalysisEnvironment is already closed") - - override val resolveSession: ResolveSession = facade.resolveSession - override val moduleDescriptor: ModuleDescriptor = facade.moduleDescriptor - override val project: Project = facade.project - - override fun close() { - isClosed = true - analysisEnvironment.dispose() - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt deleted file mode 100644 index 0f1b3ccf..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.jetbrains.kotlin.caches.resolve - -import com.intellij.openapi.components.ComponentManager -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache - -internal interface KotlinCacheService { - companion object { - inline fun <reified T : Any> ComponentManager.service(): T { - val serviceClass = T::class.java - return getService(serviceClass) - ?: error("Cannot find service ${serviceClass.name} in $this (classloader=${serviceClass.classLoader}") - } - - fun getInstance(project: Project): KotlinCacheService = project.service() - } - - /** - * Provides resolution facade for [elements], guaranteeing that the resolution will be seen from the [platform]-perspective. - * - * This allows to get resolution for common sources in MPP from the perspective of given platform (with expects substituted to actuals, - * declarations resolved from platform-specific artifacts, ModuleDescriptors will contain only platform dependencies, etc.) - * - * It is equivalent to usual [getResolutionFacade]-overloads if platform(s) of module(s) containing [elements] are equal to [platform] - * - * Doesn't support scripts or any other 'special' files. - */ - fun getResolutionFacadeWithForcedPlatform(elements: List<KtElement>, platform: TargetPlatform): ResolutionFacade - - fun getResolutionFacade(element: KtElement): ResolutionFacade - fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade - fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade? - - fun getSuppressionCache(): KotlinSuppressCache - fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? - - fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, settings: PlatformAnalysisSettings): ResolutionFacade? -}
\ No newline at end of file diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/caches/resolve/PlatformAnalysisSettings.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/caches/resolve/PlatformAnalysisSettings.kt deleted file mode 100644 index f828580c..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/caches/resolve/PlatformAnalysisSettings.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.caches.resolve - -/** - * Regulates which sources should be analyzed together. - * - * There are exactly two descendants, which are in strong one-to-one correspondence with [ResolutionModeComponent.Mode] (meaning - * that after checking value of ResolutionMode, it's safe to downcast settings instance to the respective type): - * - [PlatformAnalysisSettingsImpl] should be used iff we're working under [Mode.SEPARATE], and will create separate - * facade for each platforms, sdk, builtIns settings and other stuff. - * This is the old and stable mode, which should be used by default. - * - * - [CompositeAnalysisSettings] should be used iff we're working under [Mode.COMPOSITE], and will analyze all sources - * together, in one facade. - * This mode is new and experimental, and works only together with TypeRefinement facilities in the compiler's frontend. - * This mode is currently enabled only for HMPP projects - */ -internal interface PlatformAnalysisSettings
\ No newline at end of file diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/caches/resolve/ExtendedResolutionApi.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/caches/resolve/ExtendedResolutionApi.kt deleted file mode 100644 index 3d93093f..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/caches/resolve/ExtendedResolutionApi.kt +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - -package org.jetbrains.kotlin.idea.caches.resolve - -import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException - - -internal fun KtElement.getResolutionFacade(): ResolutionFacade = KotlinCacheService.getInstance(project).getResolutionFacade(this) - -/** - * This function first uses declaration resolvers to resolve this declaration and/or additional declarations (e.g. its parent), - * and then takes the relevant descriptor from binding context. - * The exact set of declarations to resolve depends on bodyResolveMode - */ -internal fun KtDeclaration.resolveToDescriptorIfAny( - resolutionFacade: ResolutionFacade, - bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL -): DeclarationDescriptor? { - //TODO: BodyResolveMode.PARTIAL is not quite safe! - val context = safeAnalyze(resolutionFacade, bodyResolveMode) - return if (this is KtParameter && hasValOrVar()) { - context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, this) - // It is incorrect to have `val/var` parameters outside the primary constructor (e.g., `fun foo(val x: Int)`) - // but we still want to try to resolve in such cases. - ?: context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, this) - } else { - context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, this) - } -} - -internal fun KtParameter.resolveToParameterDescriptorIfAny(bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL) = - resolveToParameterDescriptorIfAny(getResolutionFacade(), bodyResolveMode) - -internal fun KtParameter.resolveToParameterDescriptorIfAny( - resolutionFacade: ResolutionFacade, - bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL -): ValueParameterDescriptor? { - val context = safeAnalyze(resolutionFacade, bodyResolveMode) - return context.get(BindingContext.VALUE_PARAMETER, this) as? ValueParameterDescriptor -} - -internal fun KtDeclaration.resolveToDescriptorIfAny( - bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL -): DeclarationDescriptor? = - resolveToDescriptorIfAny(getResolutionFacade(), bodyResolveMode) - -internal fun KtElement.analyze( - resolutionFacade: ResolutionFacade, - bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL -): BindingContext = resolutionFacade.analyze(this, bodyResolveMode) - -internal fun KtElement.safeAnalyze( - resolutionFacade: ResolutionFacade, - bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL -): BindingContext = try { - analyze(resolutionFacade, bodyResolveMode) -} catch (e: Exception) { - e.returnIfNoDescriptorForDeclarationException { BindingContext.EMPTY } -} - -internal inline fun <T> Exception.returnIfNoDescriptorForDeclarationException( - crossinline condition: (Boolean) -> Boolean = { v -> v }, - crossinline computable: () -> T -): T = - if (condition(this.isItNoDescriptorForDeclarationException)) { - computable() - } else { - throw this - } - -internal val Exception.isItNoDescriptorForDeclarationException: Boolean - get() = this is NoDescriptorForDeclarationException || (cause as? Exception)?.isItNoDescriptorForDeclarationException == true diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/kdoc/findKDoc.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/kdoc/findKDoc.kt deleted file mode 100644 index 1accf430..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/kdoc/findKDoc.kt +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - -package org.jetbrains.kotlin.idea.kdoc - -import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag -import org.jetbrains.kotlin.kdoc.psi.api.KDoc -import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.getChildOfType -import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType -import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly - -internal data class KDocContent( - val contentTag: KDocTag, - val sections: List<KDocSection> -) - -internal fun DeclarationDescriptor.findKDoc( - descriptorToPsi: (DeclarationDescriptorWithSource) -> PsiElement? = { DescriptorToSourceUtils.descriptorToDeclaration(it) } -): KDocContent? { - if (this is DeclarationDescriptorWithSource) { - val psiDeclaration = descriptorToPsi(this)?.navigationElement - return (psiDeclaration as? KtElement)?.findKDoc(descriptorToPsi) - } - return null -} - -private typealias DescriptorToPsi = (DeclarationDescriptorWithSource) -> PsiElement? - -internal fun KtElement.findKDoc(descriptorToPsi: DescriptorToPsi): KDocContent? { - return findKDoc() - ?: this.lookupInheritedKDoc(descriptorToPsi) -} - -internal fun KtElement.findKDoc(): KDocContent? { - return this.lookupOwnedKDoc() - ?: this.lookupKDocInContainer() -} - -private fun KtElement.lookupOwnedKDoc(): KDocContent? { - // KDoc for primary constructor is located inside of its class KDoc - val psiDeclaration = when (this) { - is KtPrimaryConstructor -> getContainingClassOrObject() - else -> this - } - - if (psiDeclaration is KtDeclaration) { - val kdoc = psiDeclaration.docComment - if (kdoc != null) { - if (this is KtConstructor<*>) { - // ConstructorDescriptor resolves to the same JetDeclaration - val constructorSection = kdoc.findSectionByTag(KDocKnownTag.CONSTRUCTOR) - if (constructorSection != null) { - // if annotated with @constructor tag and the caret is on constructor definition, - // then show @constructor description as the main content, and additional sections - // that contain @param tags (if any), as the most relatable ones - // practical example: val foo = Fo<caret>o("argument") -- show @constructor and @param content - val paramSections = kdoc.findSectionsContainingTag(KDocKnownTag.PARAM) - return KDocContent(constructorSection, paramSections) - } - } - return KDocContent(kdoc.getDefaultSection(), kdoc.getAllSections()) - } - } - return null -} - -/** - * Looks for sections that have a deeply nested [tag], - * as opposed to [KDoc.findSectionByTag], which only looks among the top level - */ -private fun KDoc.findSectionsContainingTag(tag: KDocKnownTag): List<KDocSection> { - return getChildrenOfType<KDocSection>() - .filter { it.findTagByName(tag.name.toLowerCaseAsciiOnly()) != null } -} - -private fun KtElement.lookupKDocInContainer(): KDocContent? { - val subjectName = name - val containingDeclaration = - PsiTreeUtil.findFirstParent(this, true) { - it is KtDeclarationWithBody && it !is KtPrimaryConstructor - || it is KtClassOrObject - } - - val containerKDoc = containingDeclaration?.getChildOfType<KDoc>() - if (containerKDoc == null || subjectName == null) return null - val propertySection = containerKDoc.findSectionByTag(KDocKnownTag.PROPERTY, subjectName) - val paramTag = containerKDoc.findDescendantOfType<KDocTag> { it.knownTag == KDocKnownTag.PARAM && it.getSubjectName() == subjectName } - - val primaryContent = when { - // class Foo(val <caret>s: String) - this is KtParameter && this.isPropertyParameter() -> propertySection ?: paramTag - // fun some(<caret>f: String) || class Some<<caret>T: Base> || Foo(<caret>s = "argument") - this is KtParameter || this is KtTypeParameter -> paramTag - // if this property is declared separately (outside primary constructor), but it's for some reason - // annotated as @property in class's description, instead of having its own KDoc - this is KtProperty && containingDeclaration is KtClassOrObject -> propertySection - else -> null - } - return primaryContent?.let { - // makes little sense to include any other sections, since we found - // documentation for a very specific element, like a property/param - KDocContent(it, sections = emptyList()) - } -} - -private fun KtElement.lookupInheritedKDoc(descriptorToPsi: DescriptorToPsi): KDocContent? { - if (this is KtCallableDeclaration) { - val descriptor = this.resolveToDescriptorIfAny() as? CallableDescriptor ?: return null - - for (baseDescriptor in descriptor.overriddenDescriptors) { - val baseKDoc = baseDescriptor.original.findKDoc(descriptorToPsi) - if (baseKDoc != null) { - return baseKDoc - } - } - } - return null -}
\ No newline at end of file diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt deleted file mode 100644 index 7e4e0bb5..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - -package org.jetbrains.kotlin.idea.kdoc - -import com.intellij.openapi.components.ComponentManager -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.FrontendInternals -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.idea.resolve.frontendService -import org.jetbrains.kotlin.idea.util.CallType -import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable -import org.jetbrains.kotlin.incremental.components.LookupLocation -import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.KtQualifiedExpression -import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil -import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver -import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension -import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider -import org.jetbrains.kotlin.resolve.scopes.* -import org.jetbrains.kotlin.resolve.scopes.utils.* -import org.jetbrains.kotlin.resolve.source.PsiSourceElement -import org.jetbrains.kotlin.utils.Printer -import org.jetbrains.kotlin.utils.SmartList -import org.jetbrains.kotlin.utils.addIfNotNull - -/** - * Returns `null` if the service cannot be found in [this] component manager, - * otherwise initializes a service if not yet initialized, and returns the service instance. - * @see ComponentManager.getService - */ -internal inline fun <reified T : Any> ComponentManager.serviceOrNull(): T? { - return getService(T::class.java) -} - -@OptIn(FrontendInternals::class) -internal fun ResolutionFacade.getFileResolutionScope(file: KtFile): LexicalScope { - return frontendService<FileScopeProvider>().getFileResolutionScope(file) -} - -internal fun resolveKDocLink( - context: BindingContext, - resolutionFacade: ResolutionFacade, - fromDescriptor: DeclarationDescriptor, - contextElement: PsiElement?, - fromSubjectOfTag: KDocTag?, - qualifiedName: List<String> -): Collection<DeclarationDescriptor> { - val tag = fromSubjectOfTag?.knownTag - if (tag == KDocKnownTag.PARAM) { - return resolveParamLink(fromDescriptor, qualifiedName) - } - val contextScope = getKDocLinkResolutionScope(resolutionFacade, fromDescriptor) - if (qualifiedName.size == 1) { - val localDescriptors = resolveLocal(qualifiedName.single(), contextScope, fromDescriptor) - if (localDescriptors.isNotEmpty()) { - return localDescriptors - } - } - - // [IdeKDocLinkResolutionService] is omitted - - return resolveDefaultKDocLink(context, resolutionFacade, contextElement, qualifiedName, contextScope) -} - -internal fun getParamDescriptors(fromDescriptor: DeclarationDescriptor): List<DeclarationDescriptor> { - // TODO resolve parameters of functions passed as parameters - when (fromDescriptor) { - is CallableDescriptor -> { - return fromDescriptor.valueParameters + fromDescriptor.typeParameters - } - - is ClassifierDescriptor -> { - val typeParams = fromDescriptor.typeConstructor.parameters - if (fromDescriptor is ClassDescriptor) { - val constructorDescriptor = fromDescriptor.unsubstitutedPrimaryConstructor - if (constructorDescriptor != null) { - return typeParams + constructorDescriptor.valueParameters - } - } - return typeParams - } - - else -> { - return emptyList() - } - } -} - -private fun resolveParamLink(fromDescriptor: DeclarationDescriptor, qualifiedName: List<String>): List<DeclarationDescriptor> { - val name = qualifiedName.singleOrNull() ?: return emptyList() - return getParamDescriptors(fromDescriptor).filter { it.name.asString() == name } -} - -private fun resolveLocal( - nameToResolve: String, - contextScope: LexicalScope, - fromDescriptor: DeclarationDescriptor -): List<DeclarationDescriptor> { - val shortName = Name.identifier(nameToResolve) - - val descriptorsByName = SmartList<DeclarationDescriptor>() - descriptorsByName.addIfNotNull(contextScope.findClassifier(shortName, NoLookupLocation.FROM_IDE)) - descriptorsByName.addIfNotNull(contextScope.findPackage(shortName)) - descriptorsByName.addAll(contextScope.collectFunctions(shortName, NoLookupLocation.FROM_IDE)) - descriptorsByName.addAll(contextScope.collectVariables(shortName, NoLookupLocation.FROM_IDE)) - - if (fromDescriptor is FunctionDescriptor && fromDescriptor.isExtension && shortName.asString() == "this") { - return listOfNotNull(fromDescriptor.extensionReceiverParameter) - } - - // Try to find a matching local descriptor (parameter or type parameter) first - val localDescriptors = descriptorsByName.filter { it.containingDeclaration == fromDescriptor } - if (localDescriptors.isNotEmpty()) return localDescriptors - - return descriptorsByName -} - -private fun resolveDefaultKDocLink( - context: BindingContext, - resolutionFacade: ResolutionFacade, - contextElement: PsiElement?, - qualifiedName: List<String>, - contextScope: LexicalScope -): Collection<DeclarationDescriptor> { - @OptIn(FrontendInternals::class) - val qualifiedExpressionResolver = resolutionFacade.getFrontendService(QualifiedExpressionResolver::class.java) - - val factory = KtPsiFactory(resolutionFacade.project) - // TODO escape identifiers - val codeFragment = factory.createExpressionCodeFragment(qualifiedName.joinToString("."), contextElement) - val qualifiedExpression = - codeFragment.findElementAt(codeFragment.textLength - 1)?.getStrictParentOfType<KtQualifiedExpression>() ?: return emptyList() - val (descriptor, memberName) = qualifiedExpressionResolver.resolveClassOrPackageInQualifiedExpression( - qualifiedExpression, - contextScope, - context - ) - if (descriptor == null) return emptyList() - if (memberName != null) { - val memberScope = getKDocLinkMemberScope(descriptor, contextScope) - return memberScope.getContributedFunctions(memberName, NoLookupLocation.FROM_IDE) + - memberScope.getContributedVariables(memberName, NoLookupLocation.FROM_IDE) + - listOfNotNull(memberScope.getContributedClassifier(memberName, NoLookupLocation.FROM_IDE)) - } - return listOf(descriptor) -} - -private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberScope { - return descriptor.containingDeclaration.getPackage(descriptor.fqName).memberScope -} - -private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope { - - val headerScope = LexicalScopeImpl( - outerScope, descriptor, false, descriptor.thisAsReceiverParameter, - descriptor.contextReceivers, LexicalScopeKind.SYNTHETIC - ) { - descriptor.declaredTypeParameters.forEach { addClassifierDescriptor(it) } - descriptor.constructors.forEach { addFunctionDescriptor(it) } - } - - return LexicalChainedScope.create( - headerScope, descriptor, false, null, emptyList(), LexicalScopeKind.SYNTHETIC, - descriptor.defaultType.memberScope, - descriptor.staticScope, - descriptor.companionObjectDescriptor?.defaultType?.memberScope - ) -} - -internal fun getKDocLinkResolutionScope(resolutionFacade: ResolutionFacade, contextDescriptor: DeclarationDescriptor): LexicalScope { - return when (contextDescriptor) { - is PackageFragmentDescriptor -> - LexicalScope.Base(getPackageInnerScope(contextDescriptor).memberScopeAsImportingScope(), contextDescriptor) - - is PackageViewDescriptor -> - LexicalScope.Base(contextDescriptor.memberScope.memberScopeAsImportingScope(), contextDescriptor) - - is ClassDescriptor -> - getClassInnerScope(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor) - - is FunctionDescriptor -> FunctionDescriptorUtil.getFunctionInnerScope( - getOuterScope(contextDescriptor, resolutionFacade), - contextDescriptor, LocalRedeclarationChecker.DO_NOTHING - ) - - is PropertyDescriptor -> - ScopeUtils.makeScopeForPropertyHeader(getOuterScope(contextDescriptor, resolutionFacade), contextDescriptor) - - is DeclarationDescriptorNonRoot -> - getOuterScope(contextDescriptor, resolutionFacade) - - else -> throw IllegalArgumentException("Cannot find resolution scope for root $contextDescriptor") - } -} - -private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope { - val parent = descriptor.containingDeclaration!! - if (parent is PackageFragmentDescriptor) { - val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile ?: return LexicalScope.Base( - ImportingScope.Empty, - parent - ) - val kotlinCacheService = containingFile.project.serviceOrNull<KotlinCacheService>() - val facadeToUse = kotlinCacheService?.getResolutionFacade(containingFile) ?: resolutionFacade - return facadeToUse.getFileResolutionScope(containingFile) - } else { - return getKDocLinkResolutionScope(resolutionFacade, parent) - } -} - -internal fun getKDocLinkMemberScope(descriptor: DeclarationDescriptor, contextScope: LexicalScope): MemberScope { - return when (descriptor) { - is PackageFragmentDescriptor -> getPackageInnerScope(descriptor) - - is PackageViewDescriptor -> descriptor.memberScope - - is ClassDescriptor -> { - ChainedMemberScope.create( - "Member scope for KDoc resolve", listOfNotNull( - descriptor.unsubstitutedMemberScope, - descriptor.staticScope, - descriptor.companionObjectDescriptor?.unsubstitutedMemberScope, - ExtensionsScope(descriptor, contextScope) - ) - ) - } - - else -> MemberScope.Empty - } -} - -private class ExtensionsScope( - private val receiverClass: ClassDescriptor, - private val contextScope: LexicalScope -) : MemberScope { - private val receiverTypes = listOf(receiverClass.defaultType) - - override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> { - return contextScope.collectFunctions(name, location).flatMap { - if (it is SimpleFunctionDescriptor && it.isExtension) { - it.substituteExtensionIfCallable( - receiverTypes = receiverTypes, - callType = CallType.DOT, - ignoreTypeParameters = true, - ) - } else { - emptyList() - } - } - } - - override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> { - return contextScope.collectVariables(name, location).flatMap { - if (it is PropertyDescriptor && it.isExtension) { - it.substituteExtensionIfCallable( - receiverTypes = receiverTypes, - callType = CallType.DOT, - ignoreTypeParameters = true, - ) - } else { - emptyList() - } - } - } - - override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null - - override fun getContributedDescriptors( - kindFilter: DescriptorKindFilter, - nameFilter: (Name) -> Boolean - ): Collection<DeclarationDescriptor> { - if (DescriptorKindExclude.Extensions in kindFilter.excludes) return emptyList() - return contextScope.collectDescriptorsFiltered( - kindFilter exclude DescriptorKindExclude.NonExtensions, - nameFilter, - changeNamesForAliased = true - ).flatMap { - if (it is CallableDescriptor && it.isExtension) { - it.substituteExtensionIfCallable( - receiverTypes = receiverTypes, - callType = CallType.DOT, - ignoreTypeParameters = true, - ) - } else { - emptyList() - } - } - } - - override fun getFunctionNames(): Set<Name> = - getContributedDescriptors(kindFilter = DescriptorKindFilter.FUNCTIONS).map { it.name }.toSet() - - override fun getVariableNames(): Set<Name> = - getContributedDescriptors(kindFilter = DescriptorKindFilter.VARIABLES).map { it.name }.toSet() - - override fun getClassifierNames() = null - - override fun printScopeStructure(p: Printer) { - p.println("Extensions for ${receiverClass.name} in:") - contextScope.printStructure(p) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/CachingIdeKlibMetadataLoader.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/CachingIdeKlibMetadataLoader.kt deleted file mode 100644 index 5c7ea8fb..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/CachingIdeKlibMetadataLoader.kt +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.klib - -import com.intellij.openapi.util.io.FileUtilRt -import com.intellij.openapi.vfs.StandardFileSystems -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.annotations.Contract -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.impl.KotlinLibraryImpl -import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf -import org.jetbrains.kotlin.library.metadata.PackageAccessHandler -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.konan.file.File as KFile - - -@Contract("null -> null; !null -> !null") -internal fun toSystemIndependentName(path: String?): String? { - return if (path == null) null else FileUtilRt.toSystemIndependentName(path) -} - -internal object CachingIdeKlibMetadataLoader : PackageAccessHandler { - override fun loadModuleHeader(library: KotlinLibrary): KlibMetadataProtoBuf.Header { - val virtualFile = getVirtualFile(library, library.moduleHeaderFile) - return virtualFile?.let { cache.getCachedModuleHeader(virtualFile) } ?: KlibMetadataProtoBuf.Header.getDefaultInstance() - } - - override fun loadPackageFragment(library: KotlinLibrary, packageFqName: String, partName: String): ProtoBuf.PackageFragment { - val virtualFile = getVirtualFile(library, library.packageFragmentFile(packageFqName, partName)) - return virtualFile?.let { cache.getCachedPackageFragment(virtualFile) } ?: ProtoBuf.PackageFragment.getDefaultInstance() - } - - private fun getVirtualFile(library: KotlinLibrary, file: KFile): VirtualFile? = - if (library.isZipped) asJarFileSystemFile(library.libraryFile, file) else asLocalFile(file) - - private fun asJarFileSystemFile(jarFile: KFile, localFile: KFile): VirtualFile? { - val fullPath = jarFile.absolutePath + "!" + toSystemIndependentName(localFile.path) - return StandardFileSystems.jar().findFileByPath(fullPath) - } - - private fun asLocalFile(localFile: KFile): VirtualFile? { - val fullPath = localFile.absolutePath - return StandardFileSystems.local().findFileByPath(fullPath) - } - - private val cache - get() = KlibLoadingMetadataCache.getInstance() - - private val KotlinLibrary.moduleHeaderFile - get() = (this as KotlinLibraryImpl).metadata.access.layout.moduleHeaderFile - - private fun KotlinLibrary.packageFragmentFile(packageFqName: String, partName: String) = - (this as KotlinLibraryImpl).metadata.access.layout.packageFragmentFile(packageFqName, partName) - - private val KotlinLibrary.isZipped - get() = (this as KotlinLibraryImpl).base.access.layout.isZipped -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/KlibCompatibilityInfo.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/KlibCompatibilityInfo.kt deleted file mode 100644 index 4923534d..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/KlibCompatibilityInfo.kt +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -@file:JvmName("KlibCompatibilityInfoUtils") - -package org.jetbrains.kotlin.idea.klib - - -import org.jetbrains.kotlin.library.* -import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion -import org.jetbrains.kotlin.library.metadata.metadataVersion -import java.io.IOException - -/** - * Whether a certain KLIB is compatible for the purposes of IDE: indexation, resolve, etc. - */ -internal sealed class KlibCompatibilityInfo(val isCompatible: Boolean) { - object Compatible : KlibCompatibilityInfo(true) - object Pre14Layout : KlibCompatibilityInfo(false) - class IncompatibleMetadata(val isOlder: Boolean) : KlibCompatibilityInfo(false) -} - - -internal fun <T> KotlinLibrary.safeRead(defaultValue: T, action: KotlinLibrary.() -> T) = try { - action() -} catch (_: IOException) { - defaultValue -} -internal val KotlinLibrary.compatibilityInfo: KlibCompatibilityInfo - get() { - val hasPre14Manifest = safeRead(false) { has_pre_1_4_manifest } - if (hasPre14Manifest) - return KlibCompatibilityInfo.Pre14Layout - - val metadataVersion = safeRead(null) { this.metadataVersion } - @Suppress("DEPRECATION") - return when { - metadataVersion == null -> { - // Too old KLIB format, even doesn't have metadata version - KlibCompatibilityInfo.IncompatibleMetadata(true) - } - - !metadataVersion.isCompatible() -> { - val isOlder = metadataVersion.isAtLeast(KlibMetadataVersion.INSTANCE) - KlibCompatibilityInfo.IncompatibleMetadata(!isOlder) - } - - else -> KlibCompatibilityInfo.Compatible - } - } diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/KlibLoadingMetadataCache.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/KlibLoadingMetadataCache.kt deleted file mode 100644 index 55c615f6..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/klib/KlibLoadingMetadataCache.kt +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.jetbrains.kotlin.idea.klib - -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.util.containers.ContainerUtil -import org.jetbrains.kotlin.library.KLIB_MANIFEST_FILE_NAME -import org.jetbrains.kotlin.library.KLIB_METADATA_FILE_EXTENSION -import org.jetbrains.kotlin.library.KLIB_MODULE_METADATA_FILE_NAME -import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf -import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion -import org.jetbrains.kotlin.library.metadata.parseModuleHeader -import org.jetbrains.kotlin.library.metadata.parsePackageFragment -import org.jetbrains.kotlin.library.readKonanLibraryVersioning -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion -import java.io.IOException -import java.util.* - -internal class KlibLoadingMetadataCache { - // Use special CacheKey class instead of VirtualFile for cache keys. Certain types of VirtualFiles (for example, obtained from JarFileSystem) - // do not compare path (url) and modification stamp in equals() method. - private data class CacheKey( - val url: String, - val modificationStamp: Long - ) { - constructor(virtualFile: VirtualFile) : this(virtualFile.url, virtualFile.modificationStamp) - } - - // ConcurrentWeakValueHashMap does not allow null values. - private class CacheValue<T : Any>(val value: T?) - - private val packageFragmentCache = ContainerUtil.createConcurrentWeakValueMap<CacheKey, CacheValue<ProtoBuf.PackageFragment>>() - private val moduleHeaderCache = ContainerUtil.createConcurrentWeakValueMap<CacheKey, CacheValue<KlibMetadataProtoBuf.Header>>() - private val libraryMetadataVersionCache = ContainerUtil.createConcurrentWeakValueMap<CacheKey, CacheValue<KlibMetadataVersion>>() - - fun getCachedPackageFragment(packageFragmentFile: VirtualFile): ProtoBuf.PackageFragment? { - check(packageFragmentFile.extension == KLIB_METADATA_FILE_EXTENSION) { - "Not a package metadata file: $packageFragmentFile" - } - - return packageFragmentCache.computeIfAbsent( - CacheKey(packageFragmentFile) - ) { - CacheValue(computePackageFragment(packageFragmentFile)) - }.value - } - - fun getCachedModuleHeader(moduleHeaderFile: VirtualFile): KlibMetadataProtoBuf.Header? { - check(moduleHeaderFile.name == KLIB_MODULE_METADATA_FILE_NAME) { - "Not a module header file: $moduleHeaderFile" - } - - return moduleHeaderCache.computeIfAbsent( - CacheKey(moduleHeaderFile) - ) { - CacheValue(computeModuleHeader(moduleHeaderFile)) - }.value - } - - private fun isMetadataCompatible(libraryRoot: VirtualFile): Boolean { - val manifestFile = libraryRoot.findChild(KLIB_MANIFEST_FILE_NAME) ?: return false - - val metadataVersion = libraryMetadataVersionCache.computeIfAbsent( - CacheKey(manifestFile) - ) { - CacheValue(computeLibraryMetadataVersion(manifestFile)) - }.value ?: return false - - @Suppress("DEPRECATION") - return metadataVersion.isCompatible() - } - - private fun computePackageFragment(packageFragmentFile: VirtualFile): ProtoBuf.PackageFragment? { - if (!isMetadataCompatible(packageFragmentFile.parent.parent.parent)) - return null - - return try { - parsePackageFragment(packageFragmentFile.contentsToByteArray(false)) - } catch (_: IOException) { - null - } - } - - private fun computeModuleHeader(moduleHeaderFile: VirtualFile): KlibMetadataProtoBuf.Header? { - if (!isMetadataCompatible(moduleHeaderFile.parent.parent)) - return null - - return try { - parseModuleHeader(moduleHeaderFile.contentsToByteArray(false)) - } catch (_: IOException) { - null - } - } - - private fun computeLibraryMetadataVersion(manifestFile: VirtualFile): KlibMetadataVersion? = try { - val versioning = Properties().apply { manifestFile.inputStream.use { load(it) } }.readKonanLibraryVersioning() - versioning.metadataVersion?.let(BinaryVersion.Companion::parseVersionArray)?.let(::KlibMetadataVersion) - } catch (_: IOException) { - // ignore and cache null value - null - } catch (_: IllegalArgumentException) { - // ignore and cache null value - null - } - - companion object { - @JvmStatic - fun getInstance(): KlibLoadingMetadataCache = - ApplicationManager.getApplication().getService(KlibLoadingMetadataCache::class.java) - } - -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt deleted file mode 100644 index c4adb2e3..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.jetbrains.kotlin.idea.resolve - -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.analyzer.AnalysisResult -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.analyzer.ResolverForProject -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.diagnostics.DiagnosticSink -import org.jetbrains.kotlin.idea.FrontendInternals -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode - -internal interface ResolutionFacade { - val project: Project - - fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): BindingContext - fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext - - fun analyzeWithAllCompilerChecks(element: KtElement, callback: DiagnosticSink.DiagnosticsCallback? = null): AnalysisResult - = analyzeWithAllCompilerChecks(listOf(element), callback) - - fun analyzeWithAllCompilerChecks(elements: Collection<KtElement>, callback: DiagnosticSink.DiagnosticsCallback? = null): AnalysisResult - - fun fetchWithAllCompilerChecks(element: KtElement): AnalysisResult? = null - - fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): DeclarationDescriptor - - val moduleDescriptor: ModuleDescriptor - - // get service for the module this resolution was created for - @FrontendInternals - fun <T : Any> getFrontendService(serviceClass: Class<T>): T - - fun <T : Any> getIdeService(serviceClass: Class<T>): T - - // get service for the module defined by PsiElement/ModuleDescriptor passed as parameter - @FrontendInternals - fun <T : Any> getFrontendService(element: PsiElement, serviceClass: Class<T>): T - - @FrontendInternals - fun <T : Any> tryGetFrontendService(element: PsiElement, serviceClass: Class<T>): T? - - @Deprecated("DO NOT USE IT AS IT IS A ROOT CAUSE OF KTIJ-17649") - @FrontendInternals - fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T - - fun getResolverForProject(): ResolverForProject<out ModuleInfo> -} - -@FrontendInternals -internal inline fun <reified T : Any> ResolutionFacade.frontendService(): T = this.getFrontendService(T::class.java) - -internal inline fun <reified T : Any> ResolutionFacade.ideService(): T = this.getIdeService(T::class.java) diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/CallType.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/CallType.kt deleted file mode 100644 index 6d3077e2..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/CallType.kt +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.util - -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude -import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter - - -@Suppress("ClassName") -internal sealed class CallType<TReceiver : KtElement?>(val descriptorKindFilter: DescriptorKindFilter) { - object UNKNOWN : CallType<Nothing?>(DescriptorKindFilter.ALL) - - object DEFAULT : CallType<Nothing?>(DescriptorKindFilter.ALL) - - object DOT : CallType<KtExpression>(DescriptorKindFilter.ALL) - - object SAFE : CallType<KtExpression>(DescriptorKindFilter.ALL) - - object SUPER_MEMBERS : CallType<KtSuperExpression>( - DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions exclude AbstractMembersExclude - ) - - object INFIX : CallType<KtExpression>(DescriptorKindFilter.FUNCTIONS exclude NonInfixExclude) - - object OPERATOR : CallType<KtExpression>(DescriptorKindFilter.FUNCTIONS exclude NonOperatorExclude) - - class CallableReference(settings: LanguageVersionSettings) : - CallType<KtExpression?>(DescriptorKindFilter.CALLABLES exclude LocalsAndSyntheticExclude(settings)) { - override fun equals(other: Any?): Boolean = other is CallableReference - override fun hashCode(): Int = javaClass.hashCode() - } - - object IMPORT_DIRECTIVE : CallType<KtExpression?>(DescriptorKindFilter.ALL) - - object PACKAGE_DIRECTIVE : CallType<KtExpression?>(DescriptorKindFilter.PACKAGES) - - object TYPE : CallType<KtExpression?>( - DescriptorKindFilter(DescriptorKindFilter.CLASSIFIERS_MASK or DescriptorKindFilter.PACKAGES_MASK) - exclude DescriptorKindExclude.EnumEntry - ) - - object DELEGATE : CallType<KtExpression?>(DescriptorKindFilter.FUNCTIONS exclude NonOperatorExclude) - - object ANNOTATION : CallType<KtExpression?>( - DescriptorKindFilter(DescriptorKindFilter.CLASSIFIERS_MASK or DescriptorKindFilter.PACKAGES_MASK) - exclude NonAnnotationClassifierExclude - ) - - private object NonInfixExclude : DescriptorKindExclude() { - override fun excludes(descriptor: DeclarationDescriptor) = - !(descriptor is SimpleFunctionDescriptor && descriptor.isInfix) - - override val fullyExcludedDescriptorKinds: Int - get() = 0 - } - - private object NonOperatorExclude : DescriptorKindExclude() { - override fun excludes(descriptor: DeclarationDescriptor) = - !(descriptor is SimpleFunctionDescriptor && descriptor.isOperator) - - override val fullyExcludedDescriptorKinds: Int - get() = 0 - } - - private class LocalsAndSyntheticExclude(private val settings: LanguageVersionSettings) : DescriptorKindExclude() { - // Currently, Kotlin doesn't support references to local variables - // References to Java synthetic properties are supported only since Kotlin 1.9 - override fun excludes(descriptor: DeclarationDescriptor): Boolean = - descriptor !is CallableMemberDescriptor || descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED && - !settings.supportsFeature(LanguageFeature.ReferencesToSyntheticJavaProperties) - - override val fullyExcludedDescriptorKinds: Int - get() = 0 - } - - private object NonAnnotationClassifierExclude : DescriptorKindExclude() { - override fun excludes(descriptor: DeclarationDescriptor): Boolean { - if (descriptor !is ClassifierDescriptor) return false - return descriptor !is ClassDescriptor || descriptor.kind != ClassKind.ANNOTATION_CLASS - } - - override val fullyExcludedDescriptorKinds: Int get() = 0 - } - - private object AbstractMembersExclude : DescriptorKindExclude() { - override fun excludes(descriptor: DeclarationDescriptor) = - descriptor is CallableMemberDescriptor && descriptor.modality == Modality.ABSTRACT - - override val fullyExcludedDescriptorKinds: Int - get() = 0 - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/ExtensionsUtils.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/ExtensionsUtils.kt deleted file mode 100644 index b8a1ae56..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/ExtensionsUtils.kt +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -@file:JvmName("ExtensionUtils") - -package org.jetbrains.kotlin.idea.util - -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeSubstitutor -import org.jetbrains.kotlin.types.typeUtil.TypeNullability -import org.jetbrains.kotlin.types.typeUtil.makeNotNullable -import org.jetbrains.kotlin.types.typeUtil.nullability - - -internal fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCallable( - receiverTypes: Collection<KotlinType>, - callType: CallType<*>, - ignoreTypeParameters: Boolean = false, -): Collection<TCallable> { - if (!callType.descriptorKindFilter.accepts(this)) return listOf() - - var types = receiverTypes.asSequence() - if (callType == CallType.SAFE) { - types = types.map { it.makeNotNullable() } - } - - val extensionReceiverType = fuzzyExtensionReceiverType()!! - val substitutors = types.mapNotNull { - // NOTE: this creates a fuzzy type for `it` without type parameters - var substitutor = extensionReceiverType.checkIsSuperTypeOf(it) - - // If enabled, we can ignore type parameters in the receiver type, and only check whether the constructors match - if (ignoreTypeParameters && substitutor == null && it.constructor == extensionReceiverType.type.constructor) { - substitutor = TypeSubstitutor.EMPTY - } - - // check if we may fail due to receiver expression being nullable - if (substitutor == null && it.nullability() == TypeNullability.NULLABLE && extensionReceiverType.nullability() == TypeNullability.NOT_NULL) { - substitutor = extensionReceiverType.checkIsSuperTypeOf(it.makeNotNullable()) - } - substitutor - } - - return if (typeParameters.isEmpty()) { // optimization for non-generic callables - if (substitutors.any()) listOf(this) else listOf() - } else { - substitutors - .mapNotNull { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable?) } - .toList() - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/FuzzyTypeUtils.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/FuzzyTypeUtils.kt deleted file mode 100644 index de0895e6..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/idea/util/FuzzyTypeUtils.kt +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -@file:JvmName("FuzzyTypeUtils") -package org.jetbrains.kotlin.idea.util - -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.resolve.calls.inference.CallHandle -import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind -import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.error.ErrorUtils -import org.jetbrains.kotlin.types.checker.StrictEqualityTypeChecker -import org.jetbrains.kotlin.types.typeUtil.* -import java.util.* - -internal fun CallableDescriptor.fuzzyExtensionReceiverType() = extensionReceiverParameter?.type?.toFuzzyType(typeParameters) - -internal fun FuzzyType.nullability() = type.nullability() - -internal fun KotlinType.toFuzzyType(freeParameters: Collection<TypeParameterDescriptor>) = FuzzyType(this, freeParameters) - -internal class FuzzyType(val type: KotlinType, freeParameters: Collection<TypeParameterDescriptor>) { - val freeParameters: Set<TypeParameterDescriptor> - - init { - if (freeParameters.isNotEmpty()) { - // we allow to pass type parameters from another function with the same original in freeParameters - val usedTypeParameters = HashSet<TypeParameterDescriptor>().apply { addUsedTypeParameters(type) } - if (usedTypeParameters.isNotEmpty()) { - val originalFreeParameters = freeParameters.map { it.toOriginal() }.toSet() - this.freeParameters = usedTypeParameters.filter { it.toOriginal() in originalFreeParameters }.toSet() - } else { - this.freeParameters = emptySet() - } - } else { - this.freeParameters = emptySet() - } - } - - // Diagnostic for EA-109046 - @Suppress("USELESS_ELVIS") - private fun TypeParameterDescriptor.toOriginal(): TypeParameterDescriptor { - val callableDescriptor = containingDeclaration as? CallableMemberDescriptor ?: return this - val original = callableDescriptor.original ?: error("original = null for $callableDescriptor") - val typeParameters = original.typeParameters ?: error("typeParameters = null for $original") - return typeParameters[index] - } - - override fun equals(other: Any?) = other is FuzzyType && other.type == type && other.freeParameters == freeParameters - - override fun hashCode() = type.hashCode() - - private fun MutableSet<TypeParameterDescriptor>.addUsedTypeParameters(type: KotlinType) { - val typeParameter = type.constructor.declarationDescriptor as? TypeParameterDescriptor - if (typeParameter != null && add(typeParameter)) { - typeParameter.upperBounds.forEach { addUsedTypeParameters(it) } - } - - for (argument in type.arguments) { - if (!argument.isStarProjection) { // otherwise we can fall into infinite recursion - addUsedTypeParameters(argument.type) - } - } - } - - fun checkIsSubtypeOf(otherType: FuzzyType): TypeSubstitutor? = matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE) - - fun checkIsSuperTypeOf(otherType: FuzzyType): TypeSubstitutor? = matchedSubstitutor(otherType, - MatchKind.IS_SUPERTYPE - ) - - fun checkIsSubtypeOf(otherType: KotlinType): TypeSubstitutor? = checkIsSubtypeOf(otherType.toFuzzyType(emptyList())) - - fun checkIsSuperTypeOf(otherType: KotlinType): TypeSubstitutor? = checkIsSuperTypeOf(otherType.toFuzzyType(emptyList())) - - private enum class MatchKind { - IS_SUBTYPE, - IS_SUPERTYPE - } - - private fun matchedSubstitutor(otherType: FuzzyType, matchKind: MatchKind): TypeSubstitutor? { - if (type.isError) return null - if (otherType.type.isError) return null - if (otherType.type.isUnit() && matchKind == MatchKind.IS_SUBTYPE) return TypeSubstitutor.EMPTY - - fun KotlinType.checkInheritance(otherType: KotlinType): Boolean { - return when (matchKind) { - MatchKind.IS_SUBTYPE -> this.isSubtypeOf(otherType) - MatchKind.IS_SUPERTYPE -> otherType.isSubtypeOf(this) - } - } - - if (freeParameters.isEmpty() && otherType.freeParameters.isEmpty()) { - return if (type.checkInheritance(otherType.type)) TypeSubstitutor.EMPTY else null - } - - val builder = ConstraintSystemBuilderImpl() - val typeVariableSubstitutor = builder.registerTypeVariables(CallHandle.NONE, freeParameters + otherType.freeParameters) - - val typeInSystem = typeVariableSubstitutor.substitute(type, Variance.INVARIANT) - val otherTypeInSystem = typeVariableSubstitutor.substitute(otherType.type, Variance.INVARIANT) - - when (matchKind) { - MatchKind.IS_SUBTYPE -> - builder.addSubtypeConstraint(typeInSystem, otherTypeInSystem, ConstraintPositionKind.RECEIVER_POSITION.position()) - MatchKind.IS_SUPERTYPE -> - builder.addSubtypeConstraint(otherTypeInSystem, typeInSystem, ConstraintPositionKind.RECEIVER_POSITION.position()) - } - - builder.fixVariables() - - val constraintSystem = builder.build() - - if (constraintSystem.status.hasContradiction()) return null - - // currently ConstraintSystem return successful status in case there are problems with nullability - // that's why we have to check subtyping manually - val substitutor = constraintSystem.resultingSubstitutor - val substitutedType = substitutor.substitute(type, Variance.INVARIANT) ?: return null - if (substitutedType.isError) return TypeSubstitutor.EMPTY - val otherSubstitutedType = substitutor.substitute(otherType.type, Variance.INVARIANT) ?: return null - if (otherSubstitutedType.isError) return TypeSubstitutor.EMPTY - if (!substitutedType.checkInheritance(otherSubstitutedType)) return null - - val substitutorToKeepCapturedTypes = object : DelegatedTypeSubstitution(substitutor.substitution) { - override fun approximateCapturedTypes() = false - }.buildSubstitutor() - - val substitutionMap: Map<TypeConstructor, TypeProjection> = constraintSystem.typeVariables - .map { it.originalTypeParameter } - .associateBy( - keySelector = { it.typeConstructor }, - valueTransform = { parameterDescriptor -> - val typeProjection = TypeProjectionImpl(Variance.INVARIANT, parameterDescriptor.defaultType) - val substitutedProjection = substitutorToKeepCapturedTypes.substitute(typeProjection) - substitutedProjection?.takeUnless { ErrorUtils.containsUninferredTypeVariable(it.type) } ?: typeProjection - }) - return TypeConstructorSubstitution.createByConstructorsMap(substitutionMap, approximateCapturedTypes = true).buildSubstitutor() - } -} - - -internal fun TypeSubstitution.hasConflictWith(other: TypeSubstitution, freeParameters: Collection<TypeParameterDescriptor>): Boolean { - return freeParameters.any { parameter -> - val type = parameter.defaultType - val substituted1 = this[type] ?: return@any false - val substituted2 = other[type] ?: return@any false - !StrictEqualityTypeChecker.strictEqualTypes( - substituted1.type.unwrap(), - substituted2.type.unwrap() - ) || substituted1.projectionKind != substituted2.projectionKind - } -}
\ No newline at end of file diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/resolve/lazy/BodyResolveMode.kt b/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/resolve/lazy/BodyResolveMode.kt deleted file mode 100644 index d5c4b745..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/kotlin/org/jetbrains/kotlin/resolve/lazy/BodyResolveMode.kt +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.jetbrains.kotlin.resolve.lazy - -import org.jetbrains.kotlin.resolve.BindingTraceFilter - -internal enum class BodyResolveMode(val bindingTraceFilter: BindingTraceFilter, val doControlFlowAnalysis: Boolean, val resolveAdditionals: Boolean = true) { - // All body statements are analyzed, diagnostics included - FULL(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true), - - // Analyzes only dependent statements, including all declaration statements (difference from PARTIAL_WITH_CFA) - PARTIAL_FOR_COMPLETION(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true), - - // Analyzes only dependent statements, diagnostics included - PARTIAL_WITH_DIAGNOSTICS(BindingTraceFilter.ACCEPT_ALL, doControlFlowAnalysis = true), - - // Analyzes only dependent statements, performs control flow analysis (mostly needed for isUsedAsExpression / AsStatement) - PARTIAL_WITH_CFA(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = true), - - // Analyzes only dependent statements, including only used declaration statements, does not perform control flow analysis - PARTIAL(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = false), - - // Resolve mode to resolve only the element itself without the additional elements (annotation resolve would not lead to function resolve or default parameters) - PARTIAL_NO_ADDITIONAL(BindingTraceFilter.NO_DIAGNOSTICS, doControlFlowAnalysis = false, resolveAdditionals = false) - ; - - fun doesNotLessThan(other: BodyResolveMode): Boolean { - return this <= other && this.bindingTraceFilter.includesEverythingIn(other.bindingTraceFilter) - } -} diff --git a/subprojects/analysis-kotlin-descriptors/ide/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin b/subprojects/analysis-kotlin-descriptors/ide/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin deleted file mode 100644 index ceff7e6c..00000000 --- a/subprojects/analysis-kotlin-descriptors/ide/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin +++ /dev/null @@ -1,5 +0,0 @@ -# -# Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. -# - -org.jetbrains.dokka.analysis.kotlin.descriptors.ide.IdeDescriptorAnalysisPlugin |