diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-07-05 10:04:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-05 10:04:55 +0200 |
commit | 9559158bfeeb274e9ccf1b4563f1b23b42afc493 (patch) | |
tree | 3ece0887623cfe2b7148af23001867a1dd5e6597 /kotlin-analysis | |
parent | cbd9733d3dd2f52992e98e7cebd072091a572529 (diff) | |
download | dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.tar.gz dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.tar.bz2 dokka-9559158bfeeb274e9ccf1b4563f1b23b42afc493.zip |
Decompose Kotlin/Java analysis (#3034)
* Extract analysis into separate modules
Diffstat (limited to 'kotlin-analysis')
24 files changed, 0 insertions, 2354 deletions
diff --git a/kotlin-analysis/build.gradle.kts b/kotlin-analysis/build.gradle.kts deleted file mode 100644 index a5908b4e..00000000 --- a/kotlin-analysis/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -import org.jetbrains.registerDokkaArtifactPublication - -plugins { - id("org.jetbrains.conventions.kotlin-jvm") - id("org.jetbrains.conventions.maven-publish") - id("com.github.johnrengelman.shadow") -} - -dependencies { - compileOnly(projects.core) - api(project("intellij-dependency", configuration = "shadow")) - api(project("compiler-dependency", configuration = "shadow")) -} - -registerDokkaArtifactPublication("dokkaAnalysis") { - artifactId = "dokka-analysis" -} diff --git a/kotlin-analysis/compiler-dependency/build.gradle.kts b/kotlin-analysis/compiler-dependency/build.gradle.kts deleted file mode 100644 index 5d0a01e0..00000000 --- a/kotlin-analysis/compiler-dependency/build.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -import org.jetbrains.DokkaPublicationBuilder.Component.Shadow -import org.jetbrains.registerDokkaArtifactPublication - -plugins { - id("org.jetbrains.conventions.kotlin-jvm") - id("org.jetbrains.conventions.maven-publish") - id("com.github.johnrengelman.shadow") -} - -dependencies { - api(libs.kotlin.compiler) -} - -tasks { - shadowJar { - val dokka_version: String by project - archiveFileName.set("dokka-kotlin-analysis-compiler-$dokka_version.jar") - archiveClassifier.set("") - exclude("com/intellij/") - } -} - -registerDokkaArtifactPublication("kotlinAnalysisCompiler") { - artifactId = "kotlin-analysis-compiler" - component = Shadow -} diff --git a/kotlin-analysis/intellij-dependency/build.gradle.kts b/kotlin-analysis/intellij-dependency/build.gradle.kts deleted file mode 100644 index af099902..00000000 --- a/kotlin-analysis/intellij-dependency/build.gradle.kts +++ /dev/null @@ -1,75 +0,0 @@ -import org.jetbrains.DokkaPublicationBuilder.Component.Shadow -import org.jetbrains.registerDokkaArtifactPublication - -plugins { - id("org.jetbrains.conventions.kotlin-jvm") - id("org.jetbrains.conventions.maven-publish") - id("com.github.johnrengelman.shadow") -} - -repositories { - // Override the shared repositories defined in the root settings.gradle.kts - // These repositories are very specific and are not needed in other projects - mavenCentral() - maven("https://www.jetbrains.com/intellij-repository/snapshots") { - mavenContent { snapshotsOnly() } - } - maven("https://www.jetbrains.com/intellij-repository/releases") - maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide") - maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies") - maven("https://cache-redirector.jetbrains.com/intellij-dependencies") - maven("https://www.myget.org/F/rd-snapshots/maven/") -} - -val intellijCore: Configuration by configurations.creating - -fun intellijCoreAnalysis() = zipTree(intellijCore.singleFile).matching { - include("intellij-core.jar") -} - -val jpsStandalone: Configuration by configurations.creating - -fun jpsModel() = zipTree(jpsStandalone.singleFile).matching { - include("jps-model.jar") - include("aalto-xml-*.jar") -} - -dependencies { - api(libs.kotlin.idePlugin.common) - api(libs.kotlin.idePlugin.idea) { - isTransitive = false - } - api(libs.kotlin.idePlugin.core) - api(libs.kotlin.idePlugin.native) - - @Suppress("UnstableApiUsage") - intellijCore(libs.jetbrains.intellij.core) - implementation(intellijCoreAnalysis()) - - @Suppress("UnstableApiUsage") - jpsStandalone(libs.jetbrains.intellij.jpsStandalone) - implementation(jpsModel()) -} - -tasks { - shadowJar { - val dokka_version: String by project - archiveFileName.set("dokka-kotlin-analysis-intellij-$dokka_version.jar") - archiveClassifier.set("") - - exclude("colorScheme/**") - exclude("fileTemplates/**") - exclude("inspectionDescriptions/**") - exclude("intentionDescriptions/**") - exclude("tips/**") - exclude("messages/**") - exclude("src/**") - exclude("**/*.kotlin_metadata") - exclude("**/*.kotlin_builtins") - } -} - -registerDokkaArtifactPublication("kotlinAnalysisIntelliJ") { - artifactId = "kotlin-analysis-intellij" - component = Shadow -} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AbsolutePathString.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AbsolutePathString.kt deleted file mode 100644 index 7c8b6840..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AbsolutePathString.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.jetbrains.dokka.analysis - -internal typealias AbsolutePathString = String diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisContext.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisContext.kt deleted file mode 100644 index ca83d029..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisContext.kt +++ /dev/null @@ -1,94 +0,0 @@ -package org.jetbrains.dokka.analysis - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.Platform -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 java.io.Closeable -import java.io.File - -internal fun createAnalysisContext( - logger: DokkaLogger, - 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( - logger = logger, - classpath = classpath, - sourceRoots = sources, - sourceSet = sourceSet, - analysisConfiguration = analysisConfiguration - ) -} - -internal fun createAnalysisContext( - logger: DokkaLogger, - classpath: List<File>, - sourceRoots: Set<File>, - sourceSet: DokkaConfiguration.DokkaSourceSet, - analysisConfiguration: DokkaAnalysisConfiguration -): AnalysisContext { - val analysisEnvironment = AnalysisEnvironment(DokkaMessageCollector(logger), sourceSet.analysisPlatform).apply { - if (analysisPlatform == Platform.jvm) { - configureJdkClasspathRoots() - } - addClasspath(classpath) - addSources(sourceRoots) - - loadLanguageVersionSettings(sourceSet.languageVersion, sourceSet.apiVersion) - } - - val environment = analysisEnvironment.createCoreEnvironment() - val (facade, _) = analysisEnvironment.createResolutionFacade( - environment, - analysisConfiguration.ignoreCommonBuiltIns - ) - - return AnalysisContext(environment, facade, analysisEnvironment) -} - -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 -} - -// It is not data class due to ill-defined equals -class AnalysisContext( - environment: KotlinCoreEnvironment, - facade: DokkaResolutionFacade, - private val analysisEnvironment: AnalysisEnvironment -) : Closeable { - private var isClosed: Boolean = false - val environment: KotlinCoreEnvironment = environment - get() = field.takeUnless { isClosed } ?: throw IllegalStateException("AnalysisEnvironment is already closed") - val facade: DokkaResolutionFacade = facade - get() = field.takeUnless { isClosed } ?: throw IllegalStateException("AnalysisEnvironment is already closed") - - operator fun component1() = environment - operator fun component2() = facade - override fun close() { - isClosed = true - analysisEnvironment.dispose() - } -} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt deleted file mode 100644 index bbc6dda6..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt +++ /dev/null @@ -1,618 +0,0 @@ -package org.jetbrains.dokka.analysis - -import com.intellij.core.CoreApplicationEnvironment -import com.intellij.mock.MockApplication -import com.intellij.mock.MockComponentManager -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.Platform -import org.jetbrains.dokka.analysis.resolve.* -import org.jetbrains.kotlin.analyzer.* -import org.jetbrains.kotlin.analyzer.common.* -import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns -import org.jetbrains.kotlin.caches.resolve.* -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.extensions.ApplicationExtensionDescriptor -import org.jetbrains.kotlin.ide.konan.NativePlatformKindResolution -import org.jetbrains.kotlin.idea.klib.KlibLoadingMetadataCache -import org.jetbrains.kotlin.idea.klib.getCompatibilityInfo -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.IdePlatformKind -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind -import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind -import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind -import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind -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 - -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 - */ -class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPlatform: Platform) : Disposable { - val configuration = CompilerConfiguration() - - init { - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) - } - - 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) { - if (getService(KlibLoadingMetadataCache::class.java) == null) - registerService(KlibLoadingMetadataCache::class.java, KlibLoadingMetadataCache()) - } - - projectComponentManager.registerService( - JavadocManager::class.java, - JavadocManagerImpl(environment.project) - ) - - projectComponentManager.registerService( - PsiNameHelper::class.java, - PsiNameHelperImpl(environment.project) - ) - - projectComponentManager.registerService( - CustomJavadocTagProvider::class.java, - CustomJavadocTagProvider { emptyList() } - ) - - registerExtensionPoint( - ApplicationExtensionDescriptor("org.jetbrains.kotlin.idePlatformKind", IdePlatformKind::class.java), - listOf( - CommonIdePlatformKind, - JvmIdePlatformKind, - JsIdePlatformKind, - NativeIdePlatformKind - ), - this - ) - - registerExtensionPoint( - IdePlatformKindResolution, - listOf( - CommonPlatformKindResolution(), - JvmPlatformKindResolution(), - JsPlatformKindResolution(), - NativePlatformKindResolution() - ), - this - ) - - 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() - ) - } - - fun createResolutionFacade(environment: KotlinCoreEnvironment, ignoreCommonBuiltIns: Boolean = false): Pair<DokkaResolutionFacade, DokkaResolutionFacade> { - 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) - - } - val libraryModuleDescriptor = resolverForProject.descriptorForModule(library) - val moduleDescriptor = resolverForProject.descriptorForModule(module) - builtIns?.initialize(moduleDescriptor, true) - - val resolverForLibrary = - resolverForProject.resolverForModule(library) // Required before module to initialize library properly - val resolverForModule = resolverForProject.resolverForModule(module) - val libraryResolutionFacade = - DokkaResolutionFacade( - environment.project, - libraryModuleDescriptor, - resolverForLibrary - ) - val created = - DokkaResolutionFacade( - environment.project, - moduleDescriptor, - resolverForModule - ) - val projectComponentManager = environment.project as MockComponentManager - projectComponentManager.registerService( - KotlinCacheService:: - class.java, - CoreKotlinCacheService(created) - ) - - return created to libraryResolutionFacade - } - - private fun Platform.analyzerServices() = when (this) { - Platform.js, Platform.wasm -> JsPlatformAnalyzerServices - Platform.common -> CommonPlatformAnalyzerServices - Platform.native -> NativePlatformAnalyzerServices - Platform.jvm -> JvmPlatformAnalyzerServices - } - - 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 (kotlinLibrary.getCompatibilityInfo().isCompatible) { - // 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( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT, - CliSealedClassInheritorsProvider, - ) - - 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).createResolverForModule( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT, - CliSealedClassInheritorsProvider, - ) - - 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).createResolverForModule( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT, - CliSealedClassInheritorsProvider, - ) - } - - 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( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - configuration.languageVersionSettings, - CliSealedClassInheritorsProvider, - ) - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - 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. - */ - 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 - */ - 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 - fun configureJdkClasspathRoots() = configuration.configureJdkClasspathRoots() - /** - * Adds path to classpath. - * $path: path to add - */ - 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. - */ - 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 - */ - fun addSources(sourceDirectories: Iterable<File>) { - sourceDirectories.forEach { directory -> - configuration.addKotlinSourceRoot(directory.path) - if (directory.isDirectory || directory.extension == "java") { - configuration.addJavaSourceRoot(directory) - } - } - } - - 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) - } - - companion object { - private fun <T : Any> registerExtensionPoint( - appExtension: ApplicationExtensionDescriptor<T>, - instances: List<T>, - disposable: Disposable - ) { - @Suppress("DEPRECATION") - val extensionArea = Extensions.getRootArea() - - if (extensionArea.hasExtensionPoint(appExtension.extensionPointName)) { - return - } - - appExtension.registerExtensionPoint() - instances.forEach { extension -> appExtension.registerExtension(extension, disposable) } - } - } -} - - diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt deleted file mode 100644 index de48cfae..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.jetbrains.dokka.analysis - -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 - -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) } - ) -} - -fun Callable.Companion.from(psi: PsiMethod) = with(psi) { - Callable( - name, - null, - parameterList.parameters.map { param -> JavaClassReference(param.type.canonicalText) }) -} - -fun Callable.Companion.from(psi: PsiField): Callable { - return Callable( - name = psi.name, - receiver = null, - params = emptyList() - ) -} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt deleted file mode 100644 index e2cd328a..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.jetbrains.dokka.analysis - -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 - - -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: org.jetbrains.kotlin.platform.TargetPlatform - ): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeByModuleInfo( - moduleInfo: ModuleInfo, - settings: PlatformAnalysisSettings - ): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeByModuleInfo( - moduleInfo: ModuleInfo, - platform: org.jetbrains.kotlin.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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt deleted file mode 100644 index 73b20885..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.jetbrains.dokka.analysis - -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 -import org.jetbrains.kotlin.utils.addToStdlib.safeAs - -fun DRI.Companion.from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run { - val parameter = firstIsInstanceOrNull<ValueParameterDescriptor>() - val callable = parameter?.containingDeclaration ?: firstIsInstanceOrNull() - - 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.safeAs<ClassDescriptor>()?.kind == ClassKind.ENUM_ENTRY) - DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode() - else null - ) -} - -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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt deleted file mode 100644 index e1e93962..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.jetbrains.dokka.analysis - -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 - -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 - } - } -} - - -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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt deleted file mode 100644 index 0c55fed4..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.dokka.analysis - -import com.intellij.psi.PsiNamedElement -import org.jetbrains.dokka.model.DocumentableSource -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.load.kotlin.toSourceElement - -class DescriptorDocumentableSource(val descriptor: DeclarationDescriptor) : DocumentableSource { - override val path = descriptor.toSourceElement.containingFile.toString() -} - -class PsiDocumentableSource(val psi: PsiNamedElement) : DocumentableSource { - override val path = psi.containingFile.virtualFile.path -} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DokkaResolutionFacade.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DokkaResolutionFacade.kt deleted file mode 100644 index b278ef6e..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DokkaResolutionFacade.kt +++ /dev/null @@ -1,123 +0,0 @@ -@file:OptIn(FrontendInternals::class) - -package org.jetbrains.dokka.analysis - -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 - -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) - } - - 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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JvmDependenciesIndexImpl.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JvmDependenciesIndexImpl.kt deleted file mode 100644 index 1075665e..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JvmDependenciesIndexImpl.kt +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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 it.unimi.dsi.fastutil.ints.IntArrayList -import gnu.trove.THashMap -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import java.util.* - -// speeds up finding files/classes in classpath/java source roots -// NOT THREADSAFE, 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 -class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex { - //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 - val rootIndices = 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.trim() - } - } - - // 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 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 - ) { - 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? { - // 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.identifier } - // 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.getInt(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.getInt(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.trim() - } - return null - } - - return synchronized(packageCache) { - 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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt deleted file mode 100644 index 27328a6c..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt +++ /dev/null @@ -1,111 +0,0 @@ -package org.jetbrains.dokka.analysis - -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.DokkaSourceSetID -import org.jetbrains.dokka.model.SourceSetDependent -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.utilities.DokkaLogger -import java.io.Closeable - -@Suppress("FunctionName") -fun ProjectKotlinAnalysis( - sourceSets: List<DokkaSourceSet>, - logger: DokkaLogger, - analysisConfiguration: DokkaAnalysisConfiguration = DokkaAnalysisConfiguration() -): KotlinAnalysis { - val environments = sourceSets.associateWith { sourceSet -> - createAnalysisContext( - logger = logger, - 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. - */ -@Suppress("FunctionName") -fun SamplesKotlinAnalysis( - sourceSets: List<DokkaSourceSet>, - logger: DokkaLogger, - projectKotlinAnalysis: KotlinAnalysis, - analysisConfiguration: DokkaAnalysisConfiguration = DokkaAnalysisConfiguration() -): KotlinAnalysis { - val environments = sourceSets - .filter { it.samples.isNotEmpty() } - .associateWith { sourceSet -> - createAnalysisContext( - logger = logger, - classpath = sourceSet.classpath, - sourceRoots = sourceSet.samples, - sourceSet = sourceSet, - analysisConfiguration = analysisConfiguration - ) - } - - return EnvironmentKotlinAnalysis(environments, projectKotlinAnalysis) -} - -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 = false -) - -@Deprecated( - message = "Construct using list of DokkaSourceSets and logger", - replaceWith = ReplaceWith("KotlinAnalysis(context.configuration.sourceSets, context.logger)") -) -fun KotlinAnalysis(context: DokkaContext): KotlinAnalysis = - ProjectKotlinAnalysis(context.configuration.sourceSets, context.logger) - -@Deprecated( - message = "It was renamed to `ProjectKotlinAnalysis`", - replaceWith = ReplaceWith("ProjectKotlinAnalysis(sourceSets, logger, analysisConfiguration)") -) -fun KotlinAnalysis( - sourceSets: List<DokkaSourceSet>, - logger: DokkaLogger, - analysisConfiguration: DokkaAnalysisConfiguration = DokkaAnalysisConfiguration() -) = ProjectKotlinAnalysis(sourceSets, logger, analysisConfiguration) - - -/** - * First child delegation. It does not close [parent]. - */ -abstract class KotlinAnalysis( - val parent: KotlinAnalysis? = null -) : Closeable { - - operator fun get(key: DokkaSourceSet): AnalysisContext { - return get(key.sourceSetID) - } - - operator fun get(key: DokkaSourceSetID): AnalysisContext { - return find(key) - ?: parent?.get(key) - ?: throw IllegalStateException("Missing EnvironmentAndFacade for sourceSet $key") - } - - protected 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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinCliJavaFileManagerImpl.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinCliJavaFileManagerImpl.kt deleted file mode 100644 index 37a5e3f7..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinCliJavaFileManagerImpl.kt +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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 -import org.jetbrains.kotlin.utils.addIfNotNull -import java.util.* - -// 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 -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 - - 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() - - 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 - } - - result.addIfNotNull( - singleJavaFileRootsIndex.findJavaSourceClass(classId) - ?.takeIf { it in scope } - ?.findPsiClassInVirtualFile(relativeClassName) - ) - - 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() - - 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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt deleted file mode 100644 index 091e54ce..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.jetbrains.dokka.analysis - -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 - -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 - } - } - -fun TypeReference.Companion.from(d: ValueParameterDescriptor): TypeReference = - fromPossiblyNullable(d.type, emptyList()) - -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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/CommonKlibModuleInfo.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/CommonKlibModuleInfo.kt deleted file mode 100644 index 22c86dd7..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/CommonKlibModuleInfo.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.jetbrains.dokka.analysis.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 -}
\ No newline at end of file diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaJsKlibLibraryInfo.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaJsKlibLibraryInfo.kt deleted file mode 100644 index 9d28cc3c..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaJsKlibLibraryInfo.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.jetbrains.dokka.analysis.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) -}
\ No newline at end of file diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaJsResolverForModuleFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaJsResolverForModuleFactory.kt deleted file mode 100644 index 353c71fb..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaJsResolverForModuleFactory.kt +++ /dev/null @@ -1,122 +0,0 @@ -package org.jetbrains.dokka.analysis.resolve - -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.idea.klib.createKlibPackageFragmentProvider -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices -import org.jetbrains.kotlin.konan.util.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.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl -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 -) : ResolverForModuleFactory() { - companion object { - private val metadataFactories = KlibMetadataFactories({ DefaultBuiltIns.Instance }, DynamicTypeDeserializer) - - private val metadataModuleDescriptorFactory = KlibMetadataModuleDescriptorFactoryImpl( - metadataFactories.DefaultDescriptorFactory, - metadataFactories.DefaultPackageFragmentsFactory, - metadataFactories.flexibleTypeDeserializer, - metadataFactories.platformDependentTypeTransformer - ) - } - - override fun <M : ModuleInfo> createResolverForModule( - moduleDescriptor: ModuleDescriptorImpl, - moduleContext: ModuleContext, - moduleContent: ModuleContent<M>, - resolverForProject: ResolverForProject<M>, - languageVersionSettings: LanguageVersionSettings, - sealedInheritorsProvider: SealedClassInheritorsProvider - ): ResolverForModule { - val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory( - moduleContext.project, - moduleContext.storageManager, - moduleContent.syntheticFiles, - moduleContent.moduleContentScope, - moduleContent.moduleInfo - ) - - val container = createContainerForLazyResolve( - moduleContext, - declarationProviderFactory, - CodeAnalyzerInitializer.getInstance(moduleContext.project).createTrace(), // BindingTraceContext(/* allowSliceRewrite = */ true), - moduleDescriptor.platform!!, - JsPlatformAnalyzerServices, - targetEnvironment, - languageVersionSettings - ) - - 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 -> { - listOfNotNull( - moduleInfo.kotlinLibrary - .createKlibPackageFragmentProvider( - 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.isCompatible() } - .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() - } -}
\ No newline at end of file diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibLibraryDependencyResolver.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibLibraryDependencyResolver.kt deleted file mode 100644 index 9259deff..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibLibraryDependencyResolver.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.jetbrains.dokka.analysis.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/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibLibraryInfo.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibLibraryInfo.kt deleted file mode 100644 index e4e12b66..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibLibraryInfo.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.dokka.analysis.resolve - -import org.jetbrains.kotlin.analyzer.LibraryModuleInfo -import org.jetbrains.kotlin.library.KotlinLibrary - -abstract class DokkaKlibLibraryInfo : LibraryModuleInfo { - abstract val kotlinLibrary: KotlinLibrary - internal val libraryRoot: String - get() = kotlinLibrary.libraryFile.path -}
\ No newline at end of file diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibMetadataCommonDependencyContainer.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibMetadataCommonDependencyContainer.kt deleted file mode 100644 index 1a987a1f..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaKlibMetadataCommonDependencyContainer.kt +++ /dev/null @@ -1,140 +0,0 @@ -package org.jetbrains.dokka.analysis.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.descriptors.konan.DeserializedKlibModuleOrigin -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.konan.util.KlibMetadataFactories -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer -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.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl -import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.utils.keysToMap - -/** - * Adapted from org.jetbrains.kotlin.cli.metadata.KlibMetadataDependencyContainer - */ -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.keysToMap { 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, - MetadataFactories.platformDependentTypeTransformer - ) - } - - 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, - NativeTypeTransformer() - )
\ No newline at end of file diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaNativeKlibLibraryInfo.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaNativeKlibLibraryInfo.kt deleted file mode 100644 index e2b388a9..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaNativeKlibLibraryInfo.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.jetbrains.dokka.analysis.resolve - -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.descriptors.ModuleCapability -import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin -import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin -import org.jetbrains.kotlin.idea.klib.safeRead -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 - -/** 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 - } -} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaNativeResolverForModuleFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaNativeResolverForModuleFactory.kt deleted file mode 100644 index 0114f1ac..00000000 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/resolve/DokkaNativeResolverForModuleFactory.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.jetbrains.dokka.analysis.resolve - -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.idea.klib.createKlibPackageFragmentProvider -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.konan.util.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.ResolveSession -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService - -/** TODO: replace by [NativeResolverForModuleFactory] after fix of KT-40734 */ -internal class DokkaNativeResolverForModuleFactory( - private val targetEnvironment: TargetEnvironment -) : 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 - ): ResolverForModule { - - val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory( - moduleContext.project, - moduleContext.storageManager, - moduleContent.syntheticFiles, - moduleContent.moduleContentScope, - moduleContent.moduleInfo - ) - - val container = createContainerForLazyResolve( - moduleContext, - declarationProviderFactory, - CodeAnalyzerInitializer.getInstance(moduleContext.project).createTrace(), - moduleDescriptor.platform!!, - NativePlatformAnalyzerServices, - targetEnvironment, - languageVersionSettings - ) - - var packageFragmentProvider = container.get<ResolveSession>().packageFragmentProvider - - val klibPackageFragmentProvider = (moduleContent.moduleInfo as? DokkaNativeKlibLibraryInfo) - ?.kotlinLibrary - ?.createKlibPackageFragmentProvider( - 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) - } -} |