From e3402fcc8757ce8c6e5cced27646243711466fc4 Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Mon, 13 Mar 2023 12:31:56 +0100 Subject: [PATCH] [K2 JS] Do not load transitive dependencies for building K2/JS klibs ^KT-57262 Fixed --- .../kotlin/cli/js/klib/compilerPipeline.kt | 10 +++--- .../cli/common/FirSessionConstructionUtils.kt | 3 +- .../fir/session/FirCommonSessionFactory.kt | 2 +- .../kotlin/fir/session/FirJsSessionFactory.kt | 3 +- .../fir/session/FirNativeSessionFactory.kt | 2 +- .../fir/session/KlibBasedSymbolProvider.kt | 34 +++++++++---------- .../jetbrains/kotlin/ir/backend/js/klib.kt | 4 --- .../frontend/fir/TestFirJsSessionFactory.kt | 2 +- .../kotlin/js/test/BoxJsTestGenerated.java | 6 ++++ .../js/test/fir/FirJsBoxTestGenerated.java | 6 ++++ .../js/test/ir/IrBoxJsES6TestGenerated.java | 6 ++++ .../js/test/ir/IrBoxJsTestGenerated.java | 6 ++++ .../box/multiModule/transitiveDependency.kt | 15 ++++++++ .../kotlin/gradle/Kotlin2JsGradlePluginIT.kt | 29 ++++++++++++++-- 14 files changed, 94 insertions(+), 34 deletions(-) create mode 100644 js/js.translator/testData/box/multiModule/transitiveDependency.kt diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt index 937920ce829..3b3b8f8d146 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt @@ -78,7 +78,7 @@ fun compileModuleToAnalyzedFir( // TODO: !!! dependencies module data? } - val resolvedLibraries = moduleStructure.fullResolvedLibraries + val resolvedLibraries = moduleStructure.allDependencies val sessionsWithSources = prepareJsSessions( ktFiles, moduleStructure.compilerConfiguration, escapedMainModuleName, @@ -106,11 +106,11 @@ fun transformFirToIr( var builtInsModule: KotlinBuiltIns? = null val dependencies = mutableListOf() - val librariesDescriptors = moduleStructure.fullResolvedLibraries.map { resolvedLibrary -> + val librariesDescriptors = moduleStructure.allDependencies.map { resolvedLibrary -> val storageManager = LockBasedStorageManager("ModulesStructure") val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns( - resolvedLibrary.library, + resolvedLibrary, moduleStructure.compilerConfiguration.languageVersionSettings, storageManager, builtInsModule, @@ -120,7 +120,7 @@ fun transformFirToIr( dependencies += moduleDescriptor moduleDescriptor.setDependencies(ArrayList(dependencies)) - val isBuiltIns = resolvedLibrary.library.unresolvedDependencies.isEmpty() + val isBuiltIns = resolvedLibrary.unresolvedDependencies.isEmpty() if (isBuiltIns) builtInsModule = moduleDescriptor.builtIns moduleDescriptor @@ -170,7 +170,7 @@ fun serializeFirKlib( moduleStructure.compilerConfiguration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None, sourceFiles, klibPath = outputKlibPath, - moduleStructure.fullResolvedLibraries.map { it.library }, + moduleStructure.allDependencies, irResult.irModuleFragment, expectDescriptorToSymbol = mutableMapOf(), cleanFiles = icData, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt index 0c5e3307383..12874c97913 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.session.* import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices +import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider import org.jetbrains.kotlin.name.Name @@ -110,7 +111,7 @@ fun prepareJsSessions( files: List, configuration: CompilerConfiguration, rootModuleName: Name, - resolvedLibraries: List, + resolvedLibraries: List, libraryList: DependencyListForCliModule, extensionRegistrars: List, isCommonSource: (F) -> Boolean, diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt index 90f78cd2d27..5a35a0e623f 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt @@ -66,7 +66,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { session, moduleDataProvider, kotlinScopeProvider, - resolvedKLibs + resolvedKLibs.map { it.library } ) }, FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt index 61623036def..c0e6e83e0f0 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper import org.jetbrains.kotlin.fir.scopes.impl.FirEnumEntriesSupport import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.name.Name @@ -58,7 +59,7 @@ object FirJsSessionFactory : FirAbstractSessionFactory() { fun createLibrarySession( mainModuleName: Name, - resolvedLibraries: List, + resolvedLibraries: List, sessionProvider: FirProjectSessionProvider, moduleDataProvider: ModuleDataProvider, languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt index 8a32b374a7a..16fafef9fee 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt @@ -46,7 +46,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() { bindSession(session) } listOf( - KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries), + KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries.map { it.library }), NativeForwardDeclarationsSymbolProvider(session, forwardDeclarationsModuleData, kotlinScopeProvider, resolvedLibraries), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt index e35aba5bbab..5f2e54bb07c 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt @@ -15,10 +15,8 @@ import org.jetbrains.kotlin.fir.isNewPlaceForBodyGeneration import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.SymbolInternals -import org.jetbrains.kotlin.library.metadata.KlibDeserializedContainerSource -import org.jetbrains.kotlin.library.metadata.KlibMetadataClassDataFinder -import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf -import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol +import org.jetbrains.kotlin.library.KotlinLibrary +import org.jetbrains.kotlin.library.metadata.* import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.NameResolver @@ -34,17 +32,17 @@ class KlibBasedSymbolProvider( session: FirSession, moduleDataProvider: ModuleDataProvider, kotlinScopeProvider: FirKotlinScopeProvider, - private val resolvedLibraries: Collection, + private val resolvedLibraries: Collection, defaultDeserializationOrigin: FirDeclarationOrigin = FirDeclarationOrigin.Library ) : AbstractFirDeserializedSymbolProvider( session, moduleDataProvider, kotlinScopeProvider, defaultDeserializationOrigin, KlibMetadataSerializerProtocol ) { private val moduleHeaders by lazy { - resolvedLibraries.associate { it to it.loadModuleHeader(it.library) } + resolvedLibraries.associate { it to parseModuleHeader(it.moduleHeaderData) } } - private val fragmentNamesInLibraries: Map> by lazy { - buildMap> { + private val fragmentNamesInLibraries: Map> by lazy { + buildMap> { for ((library, header) in moduleHeaders) { for (fragmentName in header.packageFragmentNameList) { getOrPut(fragmentName) { SmartList() } @@ -57,15 +55,15 @@ class KlibBasedSymbolProvider( private val annotationDeserializer = KlibBasedAnnotationDeserializer(session) private val constDeserializer = FirConstDeserializer(session, KlibMetadataSerializerProtocol) private val deserializationConfiguration = CompilerDeserializationConfiguration(session.languageVersionSettings) - private val cachedFragments = mutableMapOf, ProtoBuf.PackageFragment>>() + private val cachedFragments = mutableMapOf, ProtoBuf.PackageFragment>>() private fun getPackageFragment( - resolvedLibrary: KotlinResolvedLibrary, packageStringName: String, packageMetadataPart: String + resolvedLibrary: KotlinLibrary, packageStringName: String, packageMetadataPart: String ): ProtoBuf.PackageFragment { return cachedFragments.getOrPut(resolvedLibrary) { mutableMapOf() }.getOrPut(packageStringName to packageMetadataPart) { - resolvedLibrary.loadPackageFragment(resolvedLibrary.library, packageStringName, packageMetadataPart) + parsePackageFragment(resolvedLibrary.packageMetadata(packageStringName, packageMetadataPart)) } } @@ -75,10 +73,10 @@ class KlibBasedSymbolProvider( val librariesWithFragment = fragmentNamesInLibraries[packageStringName] ?: return emptyList() return librariesWithFragment.flatMap { resolvedLibrary -> - resolvedLibrary.library.packageMetadataParts(packageStringName).mapNotNull { + resolvedLibrary.packageMetadataParts(packageStringName).mapNotNull { val fragment = getPackageFragment(resolvedLibrary, packageStringName, it) - val libraryPath = Paths.get(resolvedLibrary.library.libraryFile.path) + val libraryPath = Paths.get(resolvedLibrary.libraryFile.path) val moduleData = moduleDataProvider.getModuleData(libraryPath) ?: return@mapNotNull null val packageProto = fragment.`package` @@ -117,7 +115,7 @@ class KlibBasedSymbolProvider( val finder = KlibMetadataClassDataFinder(fragment, nameResolver) val classProto = finder.findClassData(classId)?.classProto ?: return@forEachFragmentInPackage - val libraryPath = Paths.get(resolvedLibrary.library.libraryFile.path) + val libraryPath = Paths.get(resolvedLibrary.libraryFile.path) val moduleData = moduleDataProvider.getModuleData(libraryPath) ?: return null return ClassMetadataFindResult.NoMetadata { symbol -> @@ -150,14 +148,14 @@ class KlibBasedSymbolProvider( private inline fun forEachFragmentInPackage( packageFqName: FqName, - f: (KotlinResolvedLibrary, ProtoBuf.PackageFragment, NameResolver) -> Unit + f: (KotlinLibrary, ProtoBuf.PackageFragment, NameResolver) -> Unit ) { val packageStringName = packageFqName.asString() val librariesWithFragment = fragmentNamesInLibraries[packageStringName] ?: return for (resolvedLibrary in librariesWithFragment) { - for (packageMetadataPart in resolvedLibrary.library.packageMetadataParts(packageStringName)) { + for (packageMetadataPart in resolvedLibrary.packageMetadataParts(packageStringName)) { val fragment = getPackageFragment(resolvedLibrary, packageStringName, packageMetadataPart) @@ -172,10 +170,10 @@ class KlibBasedSymbolProvider( } private fun createDeserializedContainerSource( - resolvedLibrary: KotlinResolvedLibrary, + resolvedLibrary: KotlinLibrary, packageFqName: FqName ) = KlibDeserializedContainerSource( - resolvedLibrary.library, + resolvedLibrary, moduleHeaders[resolvedLibrary]!!, deserializationConfiguration, packageFqName diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index a82bc258c61..7c5596fcc06 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -477,10 +477,6 @@ class ModulesStructure( compilerConfiguration.get(JSConfigurationKeys.ZIP_FILE_SYSTEM_ACCESSOR) ) - val fullResolvedLibraries by lazy { - allDependenciesResolution.resolveWithDependencies().getFullResolvedList() - } - val allDependencies: List get() = allDependenciesResolution.libraries diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/TestFirJsSessionFactory.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/TestFirJsSessionFactory.kt index c1a84e2a9e4..7ff14106304 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/TestFirJsSessionFactory.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/TestFirJsSessionFactory.kt @@ -42,7 +42,7 @@ object TestFirJsSessionFactory { return FirJsSessionFactory.createLibrarySession( mainModuleName, - resolvedLibraries, + resolvedLibraries.map { it.library }, sessionProvider, moduleDataProvider, languageVersionSettings, diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java index a0700835543..89302137673 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java @@ -7138,6 +7138,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/multiModule/symbolRedeclaration.kt"); } + @Test + @TestMetadata("transitiveDependency.kt") + public void testTransitiveDependency() throws Exception { + runTest("js/js.translator/testData/box/multiModule/transitiveDependency.kt"); + } + @Test @TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt") public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java index 9dde912ed9c..4630d5b10ed 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java @@ -7820,6 +7820,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest { runTest("js/js.translator/testData/box/multiModule/symbolRedeclaration.kt"); } + @Test + @TestMetadata("transitiveDependency.kt") + public void testTransitiveDependency() throws Exception { + runTest("js/js.translator/testData/box/multiModule/transitiveDependency.kt"); + } + @Test @TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt") public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java index a4786bc2199..96b4a508ad1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java @@ -7926,6 +7926,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { runTest("js/js.translator/testData/box/multiModule/symbolRedeclaration.kt"); } + @Test + @TestMetadata("transitiveDependency.kt") + public void testTransitiveDependency() throws Exception { + runTest("js/js.translator/testData/box/multiModule/transitiveDependency.kt"); + } + @Test @TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt") public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index 0ecf1ff8901..bbf2ca85717 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -7820,6 +7820,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/multiModule/symbolRedeclaration.kt"); } + @Test + @TestMetadata("transitiveDependency.kt") + public void testTransitiveDependency() throws Exception { + runTest("js/js.translator/testData/box/multiModule/transitiveDependency.kt"); + } + @Test @TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt") public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception { diff --git a/js/js.translator/testData/box/multiModule/transitiveDependency.kt b/js/js.translator/testData/box/multiModule/transitiveDependency.kt new file mode 100644 index 00000000000..0520ed01f2d --- /dev/null +++ b/js/js.translator/testData/box/multiModule/transitiveDependency.kt @@ -0,0 +1,15 @@ +// KJS_WITH_FULL_RUNTIME +// MODULE: lib1 +// FILE: lib1.kt + +fun module1() = "K" + +// MODULE: lib2(lib1) +// FILE: lib2.kt + +fun module2() = "O" + module1() + +// MODULE: main(lib2) +// FILE: main.kt + +fun box() = module2() diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt index 572039028cd..4c22af3935f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt @@ -385,9 +385,9 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) { } } - @DisplayName("JS IR implementation dependency") + @DisplayName("K1/JS IR implementation dependency") @GradleTest - fun testJsIrImplementationDependency(gradleVersion: GradleVersion) { + fun testK1JsIrImplementationDependency(gradleVersion: GradleVersion) { project("kotlin-js-browser-project", gradleVersion) { buildGradleKts.modify(::transformBuildScriptWithPluginsDsl) @@ -401,6 +401,31 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) { } } + @DisplayName("K2/JS IR implementation dependency") + @GradleTest + fun testK2JsIrImplementationDependency(gradleVersion: GradleVersion) { + project("kotlin-js-browser-project", gradleVersion) { + buildGradleKts.modify(::transformBuildScriptWithPluginsDsl) + buildGradleKts.append( + """ + rootProject.subprojects.forEach { + it.tasks.withType { + kotlinOptions.languageVersion = "2.0" + } + } + """.trimIndent() + ) + + build(":app:compileProductionExecutableKotlinJs") + + projectPath.resolve("app/src/main/kotlin/App.kt").modify { + it.replace("sheldon()", "best()") + } + + buildAndFail(":app:compileProductionExecutableKotlinJs") + } + } + @DisplayName("JS IR compiled against automatically added dom-api-compat") @GradleTest fun testJsIrCompiledAgainstAutomaticallyAddedDomApiCompat(gradleVersion: GradleVersion) {