diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt index a6beb4b1b34..8025084eade 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleFinder.kt @@ -120,14 +120,41 @@ class CliJavaModuleFinder( moduleInfo, when { useLastJdkApi -> listOf(JavaModule.Root(moduleRoot, isBinary = true, isBinarySignature = useSig)) - //TODO: distinguish roots from different modules under JDK 10-11 - useSig -> listFoldersForRelease().map { JavaModule.Root(it, isBinary = true, isBinarySignature = true) } + useSig -> createModuleFromSignature(moduleInfo) else -> error("Can't find ${moduleRoot.path} module") }, file, true ) } + private fun createModuleFromSignature(moduleInfo: JavaModuleInfo): List { + val packageParts = + if (isCompilationJDK12OrLater) emptyMap() + else hashMapOf().also { parts -> + moduleInfo.exports.forEach { + it.packageFqName.pathSegments().fold("") { acc, v -> + val packagePart = if (acc.isEmpty()) v.asString() else "$acc.${v.asString()}" + parts[packagePart] = false + packagePart + } + } + //Do it separately to avoid reset to false + moduleInfo.exports.forEach { + parts[it.packageFqName.asString()] = true + } + } + + + return listFoldersForRelease().map { virtualFile -> + JavaModule.Root( + if (isCompilationJDK12OrLater) virtualFile + else ModuleVirtualFileForRootPart(virtualFile.parent, virtualFile, packageParts, ""), + isBinary = true, + isBinarySignature = true + ) + } + } + private fun codeFor(release: Int): String = release.toString(36).toUpperCase() private fun matchesRelease(fileName: String, release: Int) = diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt index 6afec412dc6..e3ea14f7f90 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt @@ -54,8 +54,7 @@ class CliJavaModuleResolver( private val sourceModule: JavaModule? = userModules.firstOrNull(JavaModule::isSourceModule) private fun findJavaModule(file: VirtualFile): JavaModule? { - //TODO: proper root filtering is required - if (file.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL /*|| file.extension == "sig"*/) { + if (file.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL) { return systemModules.firstOrNull { module -> file in module } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/ModuleVirtualFileForRootPart.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/ModuleVirtualFileForRootPart.kt new file mode 100644 index 00000000000..ba59ed744db --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/ModuleVirtualFileForRootPart.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.cli.jvm.modules + +import com.intellij.openapi.vfs.VirtualFile +import java.io.InputStream + +class ModuleVirtualFileForRootPart( + private val parent: VirtualFile?, + private val virtualFile: VirtualFile, + private val packages: Map, + private val currentPackage: String +) : VirtualFile() { + + private val _children by lazy { + val children = virtualFile.children ?: return@lazy null + val isExported = packages.getOrDefault(currentPackage, false) + children.mapNotNull { + when { + it.isDirectory -> { + val childPackage = if (currentPackage.isEmpty()) it.name else currentPackage + "." + it.name + if (packages.contains(childPackage)) + ModuleVirtualFileForRootPart(this, it, packages, childPackage) + else null + } + isExported -> ModuleVirtualFileForRootPart(this, it, emptyMap(), currentPackage) + else -> null + } + }.toTypedArray() + } + + override fun getName() = virtualFile.name + + override fun getFileSystem() = virtualFile.fileSystem + + override fun getPath() = virtualFile.path + + override fun isWritable() = virtualFile.isWritable + + override fun isDirectory() = virtualFile.isDirectory + + override fun isValid() = virtualFile.isValid + + override fun getParent(): VirtualFile? = parent + + override fun getChildren(): Array? = _children + + override fun getOutputStream(p0: Any?, p1: Long, p2: Long) = virtualFile.getOutputStream(p0, p1, p2) + + override fun contentsToByteArray(): ByteArray = virtualFile.contentsToByteArray() + + override fun getTimeStamp() = virtualFile.timeStamp + + override fun getLength() = virtualFile.length + + override fun refresh(p0: Boolean, p1: Boolean, p2: Runnable?) = virtualFile.refresh(p0, p1, p2) + + override fun getInputStream(): InputStream? = virtualFile.inputStream +} \ No newline at end of file diff --git a/compiler/testData/javaModules/releaseFlag/moduleSwing.txt b/compiler/testData/javaModules/releaseFlag/moduleSwing.txt index 3c90171892d..a7fce1d9ab4 100644 --- a/compiler/testData/javaModules/releaseFlag/moduleSwing.txt +++ b/compiler/testData/javaModules/releaseFlag/moduleSwing.txt @@ -1,4 +1,4 @@ -compiler/testData/javaModules/releaseFlag/moduleSwing/foo/Foo.kt:5:24: error: symbol is declared in module 'javafx.media' which current module does not depend on +compiler/testData/javaModules/releaseFlag/moduleSwing/foo/Foo.kt:5:18: error: unresolved reference: swing val z: javax.swing.JFrame? = null - ^ + ^ COMPILATION_ERROR