diff --git a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/LLFirStandaloneLibrarySymbolProviderFactory.kt b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/LLFirStandaloneLibrarySymbolProviderFactory.kt index 42464a2eec8..f966cd97596 100644 --- a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/LLFirStandaloneLibrarySymbolProviderFactory.kt +++ b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/LLFirStandaloneLibrarySymbolProviderFactory.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory @@ -26,7 +27,7 @@ import org.jetbrains.kotlin.library.metadata.impl.KlibResolvedModuleDescriptorsF import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory -import org.jetbrains.kotlin.util.DummyLogger +import java.lang.IllegalStateException class LLFirStandaloneLibrarySymbolProviderFactory(private val project: Project) : LLFirLibrarySymbolProviderFactory() { override fun createJvmLibrarySymbolProvider( @@ -107,10 +108,35 @@ class LLFirStandaloneLibrarySymbolProviderFactory(private val project: Project) private fun LLFirModuleData.getLibraryKLibs(): List { val ktLibraryModule = ktModule as? KtLibraryModule ?: return emptyList() + val resolveResult = CommonKLibResolver.resolve( ktLibraryModule.getBinaryRoots().map { it.toString() }, - DummyLogger + IntellijLogBasedLogger, + lenient = true, ) return resolveResult.getFullResolvedList().map { it.library } } -} \ No newline at end of file + + companion object { + private val LOG = Logger.getInstance(LLFirStandaloneLibrarySymbolProviderFactory::class.java) + } + + private object IntellijLogBasedLogger : org.jetbrains.kotlin.util.Logger { + override fun log(message: String) { + LOG.info(message) + } + + override fun error(message: String) { + LOG.error(message) + } + + override fun warning(message: String) { + LOG.warn(message) + } + + override fun fatal(message: String): Nothing { + throw IllegalStateException(message) + } + } +} + diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/session/builder/StandaloneSessionBuilderTest.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/session/builder/StandaloneSessionBuilderTest.kt index 2aeb12628d4..040c922e549 100644 --- a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/session/builder/StandaloneSessionBuilderTest.kt +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/session/builder/StandaloneSessionBuilderTest.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtTypeReference import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -92,6 +93,18 @@ class StandaloneSessionBuilderTest { doTestKotlinStdLibResolve(JsPlatforms.defaultJsPlatform, Paths.get("dist/kotlinc/lib/kotlin-stdlib-js.jar")) } + @Test + fun testKotlinStdLibJsWithInvalidKlib() { + doTestKotlinStdLibResolve( + JsPlatforms.defaultJsPlatform, + Paths.get("dist/kotlinc/lib/kotlin-stdlib-js.jar"), + additionalStdlibRoots = listOf( + Paths.get(System.getProperty("java.home")), // directory which exists and does not contain KLibs inside + ForTestCompileRuntime.runtimeJarForTests().toPath(), // file which exists and not a KLib + ) + ) + } + @Test fun testKotlinSourceModuleSessionBuilder() { lateinit var sourceModule: KtSourceModule @@ -122,7 +135,10 @@ class StandaloneSessionBuilderTest { ktCallExpression.assertIsCallOf(CallableId(FqName.ROOT, Name.identifier("foo"))) } - private fun doTestKotlinStdLibResolve(targetPlatform: TargetPlatform, platformStdlibPath: Path) { + private fun doTestKotlinStdLibResolve( + targetPlatform: TargetPlatform, platformStdlibPath: Path, + additionalStdlibRoots: List = emptyList(), + ) { lateinit var sourceModule: KtSourceModule val session = buildStandaloneAnalysisAPISession { registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider()) @@ -132,6 +148,7 @@ class StandaloneSessionBuilderTest { val stdlib = addModule( buildKtLibraryModule { addBinaryRoot(platformStdlibPath) + addBinaryRoots(additionalStdlibRoots) platform = targetPlatform libraryName = "stdlib" } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/CommonKLibResolver.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/CommonKLibResolver.kt index b3176c5800e..89f317af018 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/CommonKLibResolver.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/CommonKLibResolver.kt @@ -20,20 +20,23 @@ object CommonKLibResolver { fun resolve( libraries: Collection, logger: Logger, - zipAccessor: ZipFileSystemAccessor? = null + zipAccessor: ZipFileSystemAccessor? = null, + lenient: Boolean = false, ): KotlinLibraryResolveResult = resolveWithoutDependencies( libraries, logger, - zipAccessor + zipAccessor, + lenient, ).resolveWithDependencies() fun resolveWithoutDependencies( libraries: Collection, logger: Logger, - zipAccessor: ZipFileSystemAccessor? + zipAccessor: ZipFileSystemAccessor?, + lenient: Boolean = false, ): KLibResolution { - val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null) } + val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null, lenient) } val libraryAbsolutePaths = libraries.map { File(it).absolutePath } // Configure the resolver to only work with absolute paths for now. val libraryResolver = KLibResolverHelper(