Correctly load multifile package parts from binaries

JvmPackagePartProvider should not just blindly load all multifile parts from
all libraries on the classpath, but only those from multifile classes which
shadow (come earlier on the classpath) other classes with the same name.
Otherwise if you have different versions of the same library (which uses
multifile classes) on the classpath, the compiler will see parts from both
versions. If some declaration have moved from one part to another, it's
possible to observe an overload resolution ambiguity error

 #KT-15287 Fixed
This commit is contained in:
Alexander Udalov
2016-12-29 20:51:46 +03:00
parent 69bfc5b4bb
commit 7b5c90ebaf
@@ -22,7 +22,6 @@ import com.intellij.util.SmartList
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.PackageParts
import java.io.EOFException
@@ -47,11 +46,18 @@ class JvmPackagePartProvider(
val rootToPackageParts = getPackageParts(packageFqName)
if (rootToPackageParts.isEmpty()) return emptyList()
val result = arrayListOf<String>()
val result = linkedSetOf<String>()
val visitedMultifileFacades = linkedSetOf<String>()
for ((_, packageParts) in rootToPackageParts) {
result.addAll(packageParts.parts)
for (name in packageParts.parts) {
val facadeName = packageParts.getMultifileFacadeName(name)
if (facadeName == null || facadeName !in visitedMultifileFacades) {
result.add(name)
}
}
packageParts.parts.mapNotNullTo(visitedMultifileFacades, packageParts::getMultifileFacadeName)
}
return result.distinct()
return result.toList()
}
override fun findMetadataPackageParts(packageFqName: String): List<String> =