Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dokka-subprojects/analysis-java-psi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dependencies {
implementation(libs.intellij.java.psi.impl) {
exclude("org.jetbrains.intellij.deps", "log4j")
}

implementation(libs.intellij.util)
implementation(projects.dokkaSubprojects.analysisMarkdownJb)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.jsoup)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ 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
Expand All @@ -27,6 +25,7 @@ import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.AnalysisContextC
import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KLibService
import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.MockApplicationHack
import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.configuration.resolve.*
import org.jetbrains.kotlin.K1Deprecation
import org.jetbrains.kotlin.analyzer.*
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer
Expand Down Expand Up @@ -112,6 +111,7 @@ public class AnalysisEnvironment(
Platform.js, Platform.wasm -> EnvironmentConfigFiles.JS_CONFIG_FILES
}

@OptIn(K1Deprecation::class)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val environment = KotlinCoreEnvironment.createForProduction(this, configuration, configFiles)
val projectComponentManager = environment.project as MockComponentManager

Expand Down Expand Up @@ -139,11 +139,6 @@ public class AnalysisEnvironment(
JavadocManagerImpl(environment.project)
)

projectComponentManager.registerService(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already added somewhere

PsiNameHelper::class.java,
PsiNameHelperImpl(environment.project)
)

projectComponentManager.registerService(
CustomJavadocTagProvider::class.java,
CustomJavadocTagProvider { emptyList() }
Expand Down Expand Up @@ -302,7 +297,9 @@ public class AnalysisEnvironment(

@OptIn(ExperimentalStdlibApi::class)
private fun resolveKotlinLibraries(): Map<AbsolutePathString, KotlinLibrary> {
return if (analysisPlatform == Platform.jvm) emptyMap() else buildMap {
return if (analysisPlatform == Platform.jvm) emptyMap() else {
val result = mutableMapOf<AbsolutePathString, KotlinLibrary>()

classpath
.filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION }
.forEach { libraryFile ->
Expand All @@ -313,7 +310,7 @@ public class AnalysisEnvironment(
)
if (kLibService.isAnalysisCompatible(kotlinLibrary)) {
// exists, is KLIB, has compatible format
put(
result.put(
libraryFile.absolutePath,
kotlinLibrary
)
Expand All @@ -323,6 +320,7 @@ public class AnalysisEnvironment(
.report(CompilerMessageSeverity.WARNING, "Can not resolve KLIB. " + e.message)
}
}
result
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.components.metadata
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.resolve.KlibCompilerDeserializationConfiguration
import org.jetbrains.kotlin.library.metadata.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
Expand All @@ -43,8 +45,8 @@ internal class DokkaKlibMetadataCommonDependencyContainer(
private val mutableDependenciesForAllModules = mutableListOf<ModuleInfo>()

private val moduleDescriptorsForKotlinLibraries: Map<KotlinLibrary, ModuleDescriptorImpl> =
kotlinLibraries.associateBy({ it }) { library ->
val moduleHeader = parseModuleHeader(library.moduleHeaderData)
kotlinLibraries.keysToMap { library ->
val moduleHeader = parseModuleHeader(library.metadata.moduleHeaderData)
val moduleName = Name.special(moduleHeader.moduleName)
val moduleOrigin = DeserializedKlibModuleOrigin(library)
MetadataFactories.DefaultDescriptorFactory.createDescriptor(
Expand Down Expand Up @@ -116,15 +118,14 @@ internal class DokkaKlibMetadataCommonDependencyContainer(
val languageVersionSettings = configuration.languageVersionSettings

val libraryModuleDescriptor = moduleDescriptorsForKotlinLibraries.getValue(library)
val packageFragmentNames = parseModuleHeader(library.moduleHeaderData).packageFragmentNameList

return klibMetadataModuleDescriptorFactory.createPackageFragmentProvider(
library,
library = library,
packageAccessHandler = null,
packageFragmentNames = packageFragmentNames,
customMetadataProtoLoader = null,
storageManager = LockBasedStorageManager("KlibMetadataPackageFragmentProvider"),
moduleDescriptor = libraryModuleDescriptor,
configuration = CompilerDeserializationConfiguration(languageVersionSettings),
configuration = KlibCompilerDeserializationConfiguration(languageVersionSettings),
compositePackageFragmentAddend = null,
lookupTracker = LookupTracker.DO_NOTHING
).also {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2014-2025 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package org.jetbrains.dokka.analysis.kotlin.descriptors.ide

import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.analysis.decompiler.konan.KlibLoadingMetadataCache
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.components.KlibMetadataComponentLayout
import org.jetbrains.kotlin.library.metadata.CustomMetadataProtoLoader
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.konan.file.File as KFile


internal object CachingIdeKlibMetadataLoader : CustomMetadataProtoLoader {
override fun loadModuleHeader(library: KotlinLibrary): KlibMetadataProtoBuf.Header {
val isZipped = library.isZipped
val moduleHeaderFile: KFile = library.metadataLayout(isZipped).moduleHeaderFile
val virtualFile: VirtualFile? = getVirtualFile(isZipped, library, moduleHeaderFile)
return virtualFile?.let { cache.getCachedModuleHeader(virtualFile) } ?: KlibMetadataProtoBuf.Header.getDefaultInstance()
}

override fun loadPackageFragment(library: KotlinLibrary, packageFqName: String, partName: String): ProtoBuf.PackageFragment {
val isZipped = library.isZipped
val packageFragmentFile: KFile = library.metadataLayout(isZipped).getPackageFragmentFile(packageFqName, partName)
val virtualFile: VirtualFile? = getVirtualFile(isZipped, library, packageFragmentFile)
return virtualFile?.let { cache.getCachedPackageFragment(virtualFile) } ?: ProtoBuf.PackageFragment.getDefaultInstance()
}

private fun getVirtualFile(isZipped: Boolean, library: KotlinLibrary, file: KFile): VirtualFile? =
if (isZipped) asJarFileSystemFile(library.libraryFile, file) else asLocalFile(file)

private fun asJarFileSystemFile(jarFile: KFile, localFile: KFile): VirtualFile? {
val fullPath = jarFile.absolutePath + "!" + toSystemIndependentName(localFile.path)
return StandardFileSystems.jar().findFileByPath(fullPath)
}

private fun asLocalFile(localFile: KFile): VirtualFile? {
val fullPath = localFile.absolutePath
return StandardFileSystems.local().findFileByPath(fullPath)
}

private val cache: KlibLoadingMetadataCache
get() = KlibLoadingMetadataCache.getInstance()

private val KotlinLibrary.isZipped: Boolean
get() = this.location.isFile

private fun KotlinLibrary.metadataLayout(isZipped: Boolean): KlibMetadataComponentLayout =
if (isZipped) ZIPPED_KLIB_METADATA_LAYOUT else KlibMetadataComponentLayout(this.location)

private val ZIPPED_KLIB_METADATA_LAYOUT = KlibMetadataComponentLayout(KFile("/"))
}

// copy-pasted from com.intellij.util.PathUtil
internal fun toSystemIndependentName(path: String): String {
return path.replace('\\', '/')
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
package org.jetbrains.dokka.analysis.kotlin.descriptors.ide

import org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.KLibService
import org.jetbrains.kotlin.analysis.decompiler.konan.CachingIdeKlibMetadataLoader
import org.jetbrains.kotlin.library.metadata.KlibMetadataModuleDescriptorFactory
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.idea.klib.compatibilityInfo
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.resolve.KlibCompilerDeserializationConfiguration
import org.jetbrains.kotlin.storage.StorageManager

internal class IdeKLibService : KLibService {
Expand Down Expand Up @@ -43,16 +42,14 @@ internal fun KotlinLibrary.createKlibPackageFragmentProvider(
): PackageFragmentProvider? {
if (!compatibilityInfo.isCompatible) return null

val packageFragmentNames = CachingIdeKlibMetadataLoader.loadModuleHeader(this).packageFragmentNameList

return metadataModuleDescriptorFactory.createPackageFragmentProvider(
library = this,
packageAccessHandler = CachingIdeKlibMetadataLoader,
packageFragmentNames = packageFragmentNames,
packageAccessHandler = null,
customMetadataProtoLoader = CachingIdeKlibMetadataLoader,
storageManager = storageManager,
moduleDescriptor = moduleDescriptor,
configuration = CompilerDeserializationConfiguration(languageVersionSettings),
configuration = KlibCompilerDeserializationConfiguration(languageVersionSettings),
compositePackageFragmentAddend = null,
lookupTracker = lookupTracker
)
}
}
7 changes: 4 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ ktor = "2.3.11"
javaDiffUtils = "4.12"

## Analysis
kotlin-compiler = "2.2.0-dev-8822"
kotlin-compiler-k2 = "2.3.0-dev-5493"
kotlin-compiler = "2.3.20-dev-1838"
kotlin-compiler-k2 = "2.3.20-dev-1838"

# MUST match the version of the intellij platform used in the kotlin compiler,
# otherwise this will lead to different versions of psi API and implementations
# on the classpath and will fail with hard to debug problems in runtime.
# See: https://github.com/JetBrains/kotlin/blob/79b4def109dc73f882ec8a291a69d0197ad55c58/gradle/versions.properties#L1
intellij-platform = "241.19416.19"
intellij-platform = "251.27812.49"

## HTML
jsoup = "1.16.1"
Expand Down Expand Up @@ -121,6 +121,7 @@ kotlin-symbol-light-classes = { module = "org.jetbrains.kotlin:symbol-light-clas
#### Java analysis ####
intellij-java-psi-api = { module = "com.jetbrains.intellij.java:java-psi", version.ref = "intellij-platform" }
intellij-java-psi-impl = { module = "com.jetbrains.intellij.java:java-psi-impl", version.ref = "intellij-platform" }
intellij-util= { module = "com.jetbrains.intellij.platform:util", version.ref = "intellij-platform" }

#### HTML ####
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
Expand Down
Loading