From 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Fri, 10 Nov 2023 11:46:54 +0100 Subject: 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 --- .../descriptors/compiler/AnalysisContextCreator.kt | 24 + .../compiler/CompilerDescriptorAnalysisPlugin.kt | 156 +++ .../CompilerDocumentableSourceLanguageParser.kt | 27 + .../compiler/CompilerExtensionPointProvider.kt | 18 + .../descriptors/compiler/DescriptorFinder.kt | 14 + .../kotlin/descriptors/compiler/KDocFinder.kt | 34 + .../kotlin/descriptors/compiler/KLibService.kt | 27 + .../descriptors/compiler/MockApplicationHack.kt | 13 + .../compiler/configuration/AbsolutePathString.kt | 7 + .../compiler/configuration/AnalysisContext.kt | 102 ++ .../compiler/configuration/AnalysisEnvironment.kt | 595 +++++++++ .../compiler/configuration/CallableFactory.kt | 35 + .../compiler/configuration/DRIFactory.kt | 53 + .../compiler/configuration/DRITargetFactory.kt | 46 + .../compiler/configuration/Documentable.kt | 28 + .../configuration/JvmDependenciesIndexImpl.kt | 257 ++++ .../compiler/configuration/KotlinAnalysis.kt | 106 ++ .../configuration/KotlinCliJavaFileManagerImpl.kt | 301 +++++ .../compiler/configuration/TypeReferenceFactory.kt | 72 ++ .../configuration/resolve/CommonKlibModuleInfo.kt | 29 + .../resolve/DokkaJsKlibLibraryInfo.kt | 34 + .../resolve/DokkaJsResolverForModuleFactory.kt | 133 ++ .../resolve/DokkaKlibLibraryDependencyResolver.kt | 21 + .../configuration/resolve/DokkaKlibLibraryInfo.kt | 14 + .../DokkaKlibMetadataCommonDependencyContainer.kt | 140 +++ .../resolve/DokkaNativeKlibLibraryInfo.kt | 54 + .../resolve/DokkaNativeResolverForModuleFactory.kt | 88 ++ .../impl/DescriptorFullClassHierarchyBuilder.kt | 89 ++ .../compiler/impl/DescriptorInheritanceBuilder.kt | 95 ++ .../compiler/impl/DescriptorKotlinToJavaMapper.kt | 35 + .../DescriptorSyntheticDocumentableDetector.kt | 37 + .../compiler/impl/KotlinSampleProvider.kt | 119 ++ .../IllegalModuleAndPackageDocumentation.kt | 11 + .../moduledocs/ModuleAndPackageDocumentation.kt | 15 + .../ModuleAndPackageDocumentationFragment.kt | 13 + .../ModuleAndPackageDocumentationParsingContext.kt | 75 ++ .../ModuleAndPackageDocumentationReader.kt | 117 ++ .../ModuleAndPackageDocumentationSource.kt | 18 + .../parseModuleAndPackageDocumentation.kt | 16 + .../parseModuleAndPackageDocumentationFragments.kt | 59 + .../java/DescriptorDocumentationContent.kt | 20 + .../compiler/java/DescriptorKotlinDocComment.kt | 83 ++ .../java/DescriptorKotlinDocCommentCreator.kt | 30 + .../java/DescriptorKotlinDocCommentParser.kt | 58 + .../compiler/java/KotlinAnalysisProjectProvider.kt | 20 + .../java/KotlinAnalysisSourceRootsExtractor.kt | 31 + .../java/KotlinInheritDocTagContentProvider.kt | 35 + .../compiler/translator/CollectionExtensions.kt | 16 + .../DefaultDescriptorToDocumentableTranslator.kt | 1284 ++++++++++++++++++++ .../DefaultExternalDocumentablesProvider.kt | 47 + .../translator/DescriptorAccessorConventionUtil.kt | 148 +++ .../translator/ExternalClasslikesTranslator.kt | 16 + .../compiler/translator/KdocMarkdownParser.kt | 105 ++ .../SyntheticDescriptorDocumentationProvider.kt | 82 ++ .../compiler/translator/annotationsValue.kt | 7 + .../descriptors/compiler/translator/isException.kt | 22 + 56 files changed, 5131 insertions(+) create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/CallableFactory.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRIFactory.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/DRITargetFactory.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/Documentable.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/JvmDependenciesIndexImpl.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinAnalysis.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/KotlinCliJavaFileManagerImpl.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/TypeReferenceFactory.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/CommonKlibModuleInfo.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsKlibLibraryInfo.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaJsResolverForModuleFactory.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryDependencyResolver.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibLibraryInfo.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaKlibMetadataCommonDependencyContainer.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeKlibLibraryInfo.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/resolve/DokkaNativeResolverForModuleFactory.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorFullClassHierarchyBuilder.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorInheritanceBuilder.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorKotlinToJavaMapper.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/DescriptorSyntheticDocumentableDetector.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/KotlinSampleProvider.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/IllegalModuleAndPackageDocumentation.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentation.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationFragment.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationParsingContext.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationReader.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/ModuleAndPackageDocumentationSource.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentation.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/impl/moduledocs/parseModuleAndPackageDocumentationFragments.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorDocumentationContent.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocComment.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentCreator.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/DescriptorKotlinDocCommentParser.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisProjectProvider.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinAnalysisSourceRootsExtractor.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/java/KotlinInheritDocTagContentProvider.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/CollectionExtensions.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultDescriptorToDocumentableTranslator.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DefaultExternalDocumentablesProvider.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/DescriptorAccessorConventionUtil.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/ExternalClasslikesTranslator.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/KdocMarkdownParser.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/SyntheticDescriptorDocumentationProvider.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/annotationsValue.kt create mode 100644 dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/translator/isException.kt (limited to 'dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains') diff --git a/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt new file mode 100644 index 00000000..67476a50 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/AnalysisContextCreator.kt @@ -0,0 +1,24 @@ +/* + * 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt new file mode 100644 index 00000000..c59a43b2 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDescriptorAnalysisPlugin.kt @@ -0,0 +1,156 @@ +/* + * 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 by extensionPoint() + + @InternalDokkaApi + public val descriptorFinder: ExtensionPoint by extensionPoint() + + @InternalDokkaApi + public val klibService: ExtensionPoint by extensionPoint() + + @InternalDokkaApi + public val compilerExtensionPointProvider: ExtensionPoint by extensionPoint() + + @InternalDokkaApi + public val mockApplicationHack: ExtensionPoint by extensionPoint() + + @InternalDokkaApi + public val analysisContextCreator: ExtensionPoint by extensionPoint() + + @InternalDokkaApi + public val kotlinAnalysis: ExtensionPoint by extensionPoint() + + internal val documentableAnalyzerImpl by extending { + plugin().documentableSourceLanguageParser providing { CompilerDocumentableSourceLanguageParser() } + } + + internal val defaultKotlinAnalysis by extending { + @OptIn(DokkaPluginApiPreview::class) + kotlinAnalysis providing { ctx -> + val configuration = configuration(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().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 by extending { + plugin().sampleProviderFactory providing ::KotlinSampleProviderFactory + } + + internal val descriptorSyntheticDocumentableDetector by extending { + plugin().syntheticDocumentableDetector providing { DescriptorSyntheticDocumentableDetector() } + } + + internal val moduleAndPackageDocumentationReader by extending { + plugin().moduleAndPackageDocumentationReader providing ::ModuleAndPackageDocumentationReader + } + + internal val kotlinToJavaMapper by extending { + plugin().kotlinToJavaService providing { DescriptorKotlinToJavaMapper() } + } + + internal val descriptorInheritanceBuilder by extending { + plugin().inheritanceBuilder providing { DescriptorInheritanceBuilder() } + } + + internal val defaultExternalDocumentablesProvider by extending { + plugin().externalDocumentablesProvider providing ::DefaultExternalDocumentablesProvider + } + + private val javaAnalysisPlugin by lazy { plugin() } + + 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt new file mode 100644 index 00000000..2dbc242a --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerDocumentableSourceLanguageParser.kt @@ -0,0 +1,27 @@ +/* + * 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt new file mode 100644 index 00000000..e42efe41 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/CompilerExtensionPointProvider.kt @@ -0,0 +1,18 @@ +/* + * 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 + + public class CompilerExtensionPoint( + public val extensionDescriptor: ApplicationExtensionDescriptor, + public val extensions: List + ) +} diff --git a/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt new file mode 100644 index 00000000..db06647d --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/DescriptorFinder.kt @@ -0,0 +1,14 @@ +/* + * 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt new file mode 100644 index 00000000..e5367211 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KDocFinder.kt @@ -0,0 +1,34 @@ +/* + * 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 +} diff --git a/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt new file mode 100644 index 00000000..fc173298 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/KLibService.kt @@ -0,0 +1,27 @@ +/* + * 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt new file mode 100644 index 00000000..39ca666b --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/MockApplicationHack.kt @@ -0,0 +1,13 @@ +/* + * 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt new file mode 100644 index 00000000..8cf05053 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AbsolutePathString.kt @@ -0,0 +1,7 @@ +/* + * 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt new file mode 100644 index 00000000..917a86e7 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisContext.kt @@ -0,0 +1,102 @@ +/* + * 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, + 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, + sourceRoots: Set, + sourceSet: DokkaConfiguration.DokkaSourceSet, + analysisConfiguration: DokkaAnalysisConfiguration +): AnalysisContext { + val analysisEnvironment = AnalysisEnvironment( + DokkaMessageCollector(context.logger), + sourceSet.analysisPlatform, + context.plugin().querySingle { mockApplicationHack }, + context.plugin().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().querySingle { 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/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt new file mode 100644 index 00000000..5a0fc396 --- /dev/null +++ b/dokka-subprojects/analysis-kotlin-descriptors-compiler/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/descriptors/compiler/configuration/AnalysisEnvironment.kt @@ -0,0 +1,595 @@ +/* + * 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): 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 = 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("") + override val platform: TargetPlatform = targetPlatform + override fun dependencies(): List = listOf(this) + override fun getLibraryRoots(): Collection = 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("") + override val platform: TargetPlatform = targetPlatform + override fun dependencies(): List = + 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 = { + 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.registerLibraries(): List { + 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 { + 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, + environment: KotlinCoreEnvironment, + dependencyContainer: CommonDependenciesContainer? + ): ResolverForProject { + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = module.dependencies() + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = 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 + ): ResolverForProject { + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = module.dependencies() + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = 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 + ): ResolverForProject { + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = module.dependencies() + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = 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, + sourcesScope: GlobalSearchScope, + builtIns: KotlinBuiltIns + ): ResolverForProject { + 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( + "Dokka", + projectContext, + modules = listOf(module, library) + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = + 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 + 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) { + 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.WAR