Compare commits

...

3 Commits

Author SHA1 Message Date
Simon Ogorodnik
64ceaf7921 Do not throw exception on not-found serialized class from knm 2018-09-12 20:53:09 +03:00
Simon Ogorodnik
ee412e6fd0 Support free-form .knm package part names 2018-09-11 20:24:10 +03:00
Simon Ogorodnik
f0381ad4fa Support for split-packages in Kotlin Native
See JetBrains/kotlin-native#2034
2018-09-11 20:23:41 +03:00
11 changed files with 63 additions and 27 deletions

View File

@@ -23,13 +23,13 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultPackageFragmentsFactory
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryDir
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryFile
import org.jetbrains.kotlin.konan.library.MetadataReader
import org.jetbrains.kotlin.konan.library.createKonanLibrary
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultPackageFragmentsFactory
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
@@ -104,9 +104,10 @@ internal object CachingIdeMetadataReaderImpl : MetadataReader {
override fun loadSerializedPackageFragment(
libraryLayout: KonanLibraryLayout,
packageFqName: String
packageFqName: String,
partName: String
): KonanProtoBuf.LinkDataPackageFragment =
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName)))
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName, partName)))
private fun KonanLibraryLayout.getVirtualFile(file: File): VirtualFile {
val source = this.source

View File

@@ -6,7 +6,10 @@
package org.jetbrains.kotlin.ide.konan
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.VirtualFileVisitor
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
@@ -28,8 +31,11 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
return if (virtualFile.isDirectory) {
virtualFile.findChild("linkdata")?.takeIf { it.isDirectory }
?.children?.any { it.extension == KLIB_METADATA_FILE_EXTENSION } == true
val dir = virtualFile.findChild("linkdata") ?: return false
// False means we hit .knm file
!VfsUtil.processFilesRecursively(dir) {
it.extension != KLIB_METADATA_FILE_EXTENSION
}
} else {
virtualFile.extension == KLIB_FILE_EXTENSION
}

View File

@@ -101,10 +101,10 @@ sealed class FileWithMetadata {
open class Compatible(
val proto: KonanProtoBuf.LinkDataPackageFragment,
serializerProtocol: SerializerExtensionProtocol
serializerProtocol: SerializerExtensionProtocol // TODO: Is it required?
) : FileWithMetadata() {
val nameResolver = NameResolverImpl(proto.stringTable, proto.nameTable)
val packageFqName = FqName(nameResolver.getPackageFqName(proto.`package`.getExtension(serializerProtocol.packageFqName)))
val packageFqName = FqName(proto.fqName)
open val classesToDecompile: List<ProtoBuf.Class> =
proto.classes.classesList.filter { proto ->

View File

@@ -44,7 +44,8 @@ interface KonanLibrary {
val dataFlowGraph: ByteArray?
val moduleHeaderData: KonanProtoBuf.LinkDataLibrary
fun packageMetadata(packageFqName: String): KonanProtoBuf.LinkDataPackageFragment
fun packageMetadataParts(fqName: String): Set<String>
fun packageMetadata(packageFqName: String, partName: String): KonanProtoBuf.LinkDataPackageFragment
}
val KonanLibrary.uniqueName

View File

@@ -35,11 +35,11 @@ interface KonanLibraryLayout {
val moduleHeaderFile get() = File(linkdataDir, KLIB_MODULE_METADATA_FILE_NAME)
val dataFlowGraphFile get() = File(linkdataDir, "module_data_flow_graph")
fun packageFragmentFile(packageFqName: String) =
File(
linkdataDir,
if (packageFqName == "") "root_package.$KLIB_METADATA_FILE_EXTENSION" else "package_$packageFqName.$KLIB_METADATA_FILE_EXTENSION"
)
fun packageFragmentsDir(packageFqName: String) =
File(linkdataDir, if (packageFqName == "") "root_package" else "package_$packageFqName")
fun packageFragmentFile(packageFqName: String, partName: String) =
File(packageFragmentsDir(packageFqName), "$partName$KLIB_METADATA_FILE_EXTENSION_WITH_DOT")
}
sealed class KonanLibrarySource {

View File

@@ -9,5 +9,9 @@ import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
interface MetadataReader {
fun loadSerializedModule(libraryLayout: KonanLibraryLayout): KonanProtoBuf.LinkDataLibrary
fun loadSerializedPackageFragment(libraryLayout: KonanLibraryLayout, packageFqName: String): KonanProtoBuf.LinkDataPackageFragment
fun loadSerializedPackageFragment(
libraryLayout: KonanLibraryLayout,
packageFqName: String,
partName: String
): KonanProtoBuf.LinkDataPackageFragment
}

View File

@@ -18,7 +18,10 @@ object DefaultMetadataReaderImpl : MetadataReader {
override fun loadSerializedPackageFragment(
libraryLayout: KonanLibraryLayout,
packageFqName: String
packageFqName: String,
partName: String
): KonanProtoBuf.LinkDataPackageFragment =
parsePackageFragment(libraryLayout.packageFragmentFile(packageFqName).readBytes())
parsePackageFragment(
libraryLayout.packageFragmentFile(packageFqName, partName).readBytes()
)
}

View File

@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.konan.library.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KLIB_PROPERTY_ABI_VERSION
import org.jetbrains.kotlin.konan.library.KLIB_PROPERTY_LINKED_OPTS
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.MetadataReader
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.properties.propertyList
@@ -65,7 +62,25 @@ internal class KonanLibraryImpl(
override val moduleHeaderData: KonanProtoBuf.LinkDataLibrary by lazy { layout.inPlace { metadataReader.loadSerializedModule(it) } }
override fun packageMetadata(packageFqName: String) = layout.inPlace { metadataReader.loadSerializedPackageFragment(it, packageFqName) }
override fun packageMetadata(packageFqName: String, partName: String) =
layout.inPlace { metadataReader.loadSerializedPackageFragment(it, packageFqName, partName) }
override fun packageMetadataParts(fqName: String): Set<String> =
layout.inPlace { inPlaceLayout ->
val fileList =
inPlaceLayout.packageFragmentsDir(fqName)
.listFiles
.mapNotNull {
it.name
.substringBeforeLast(KLIB_METADATA_FILE_EXTENSION_WITH_DOT, missingDelimiterValue = "")
.takeIf { it.isNotEmpty() }
}
fileList.toSortedSet().also {
require(it.size == fileList.size) { "Duplicated names: ${fileList.groupingBy { it }.eachCount().filter { (_, count) -> count > 1 }}" }
}
}
override fun toString() = "$libraryName[default=$isDefault]"
}

View File

@@ -23,8 +23,9 @@ class KonanClassDataFinder(
val nameList = proto.classNameList
val index = nameList.indexOfFirst { nameResolver.getClassId(it) == classId }
if (index == -1)
error("Could not find serialized class $classId")
if (index == -1) {
return null
}
val foundClass = proto.getClasses(index) ?: error("Could not find data for serialized class $classId")

View File

@@ -24,7 +24,8 @@ class KonanPackageFragment(
private val library: KonanLibrary,
private val packageAccessedHandler: PackageAccessedHandler?,
storageManager: StorageManager,
module: ModuleDescriptor
module: ModuleDescriptor,
partName: String
) : DeserializedPackageFragment(fqName, storageManager, module) {
lateinit var components: DeserializationComponents
@@ -35,7 +36,7 @@ class KonanPackageFragment(
// The proto field is lazy so that we can load only needed
// packages from the library.
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString()) }
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString(), partName) }
val proto: KonanProtoBuf.LinkDataPackageFragment
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName) }

View File

@@ -36,8 +36,12 @@ internal object KonanDeserializedPackageFragmentsFactoryImpl : KonanDeserialized
moduleDescriptor: ModuleDescriptor,
packageAccessedHandler: PackageAccessedHandler?,
storageManager: StorageManager
) = packageFragmentNames.map {
KonanPackageFragment(FqName(it), library, packageAccessedHandler, storageManager, moduleDescriptor)
) = packageFragmentNames.flatMap {
val fqName = FqName(it)
val parts = library.packageMetadataParts(it)
parts.map { partName ->
KonanPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partName)
}
}
override fun createSyntheticPackageFragments(