Commonizing klib metadata between native and js
This commit is contained in:
committed by
alexander-gorshenev
parent
f38123e78c
commit
c227c13799
@@ -215,6 +215,7 @@ extra["compilerModules"] = arrayOf(
|
|||||||
":compiler:ir.serialization.js",
|
":compiler:ir.serialization.js",
|
||||||
":kotlin-util-io",
|
":kotlin-util-io",
|
||||||
":kotlin-util-klib",
|
":kotlin-util-klib",
|
||||||
|
":kotlin-util-klib-metadata",
|
||||||
":compiler:backend-common",
|
":compiler:backend-common",
|
||||||
":compiler:backend",
|
":compiler:backend",
|
||||||
":compiler:plugin-api",
|
":compiler:plugin-api",
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ import org.jetbrains.kotlin.js.config.EcmaVersion
|
|||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.js.config.JsConfig
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||||
|
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrarySearchPathResolver
|
||||||
|
import org.jetbrains.kotlin.library.UnresolvedLibrary
|
||||||
|
import org.jetbrains.kotlin.library.toUnresolvedLibraries
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
@@ -138,20 +142,21 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
// TODO: Handle non-empty main call arguments
|
// TODO: Handle non-empty main call arguments
|
||||||
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
|
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
|
||||||
|
|
||||||
val loadedLibrariesNames = mutableSetOf<String>()
|
val unresolvedLibraries = libraries.toUnresolvedLibraries
|
||||||
val dependencies = mutableListOf<KotlinLibrary>()
|
// Configure resolver to only understands absolute path libraries.
|
||||||
val friendDependencies = mutableListOf<KotlinLibrary>()
|
val libraryResolver = KotlinLibrarySearchPathResolver<KotlinLibrary>(
|
||||||
|
repositories = emptyList(),
|
||||||
for (library in libraries) {
|
directLibs = libraries,
|
||||||
val irLib = loadKlib(library)
|
distributionKlib = null,
|
||||||
if (irLib.moduleName !in loadedLibrariesNames) {
|
localKotlinDir = null,
|
||||||
dependencies.add(irLib)
|
skipCurrentDir = true
|
||||||
loadedLibrariesNames.add(irLib.moduleName)
|
// TODO: pass logger attached to message collector here.
|
||||||
if (library in friendLibraries) {
|
).libraryResolver()
|
||||||
friendDependencies.add(irLib)
|
val resolvedLibraries = libraryResolver.resolveWithDependencies(unresolvedLibraries, true, true, true)
|
||||||
}
|
val friendDependencies = resolvedLibraries.getFullList()
|
||||||
|
.filter {
|
||||||
|
it.moduleName in friendLibraries
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val produceKind = produceMap[arguments.irProduceOnly]
|
val produceKind = produceMap[arguments.irProduceOnly]
|
||||||
if (produceKind == null) {
|
if (produceKind == null) {
|
||||||
@@ -169,7 +174,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
project = config.project,
|
project = config.project,
|
||||||
files = sourcesFiles,
|
files = sourcesFiles,
|
||||||
configuration = config.configuration,
|
configuration = config.configuration,
|
||||||
allDependencies = dependencies,
|
allDependencies = resolvedLibraries,
|
||||||
friendDependencies = friendDependencies,
|
friendDependencies = friendDependencies,
|
||||||
outputKlibPath = outputKlibPath,
|
outputKlibPath = outputKlibPath,
|
||||||
nopack = arguments.irLegacyGradlePluginCompatibility
|
nopack = arguments.irLegacyGradlePluginCompatibility
|
||||||
@@ -184,7 +189,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
sourcesFiles,
|
sourcesFiles,
|
||||||
configuration,
|
configuration,
|
||||||
phaseConfig,
|
phaseConfig,
|
||||||
allDependencies = dependencies,
|
allDependencies = resolvedLibraries,
|
||||||
friendDependencies = friendDependencies,
|
friendDependencies = friendDependencies,
|
||||||
mainArguments = mainCallArguments
|
mainArguments = mainCallArguments
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
@@ -28,7 +29,7 @@ fun compile(
|
|||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
phaseConfig: PhaseConfig,
|
phaseConfig: PhaseConfig,
|
||||||
allDependencies: List<KotlinLibrary>,
|
allDependencies: KotlinLibraryResolveResult,
|
||||||
friendDependencies: List<KotlinLibrary>,
|
friendDependencies: List<KotlinLibrary>,
|
||||||
mainArguments: List<String>?,
|
mainArguments: List<String>?,
|
||||||
exportedDeclarations: Set<FqName> = emptySet()
|
exportedDeclarations: Set<FqName> = emptySet()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.wasm
|
package org.jetbrains.kotlin.backend.wasm
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||||
import org.jetbrains.kotlin.backend.wasm.codegen.IrModuleToWasm
|
import org.jetbrains.kotlin.backend.wasm.codegen.IrModuleToWasm
|
||||||
@@ -24,7 +25,7 @@ fun compileWasm(
|
|||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
phaseConfig: PhaseConfig,
|
phaseConfig: PhaseConfig,
|
||||||
allDependencies: List<KotlinLibrary>,
|
allDependencies: KotlinLibraryResolveResult,
|
||||||
friendDependencies: List<KotlinLibrary>,
|
friendDependencies: List<KotlinLibrary>,
|
||||||
exportedDeclarations: Set<FqName> = emptySet()
|
exportedDeclarations: Set<FqName> = emptySet()
|
||||||
): WasmCompilerResult {
|
): WasmCompilerResult {
|
||||||
|
|||||||
@@ -5,9 +5,19 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// TODO: decouple from backend.common
|
// TODO: decouple from backend.common
|
||||||
|
compile(project(":compiler:frontend"))
|
||||||
compile(project(":compiler:ir.backend.common"))
|
compile(project(":compiler:ir.backend.common"))
|
||||||
compile(project(":compiler:ir.tree"))
|
compile(project(":compiler:ir.tree"))
|
||||||
|
compile(project(":compiler:serialization"))
|
||||||
compile(project(":kotlin-util-klib"))
|
compile(project(":kotlin-util-klib"))
|
||||||
|
compile(project(":kotlin-util-klib-metadata"))
|
||||||
|
|
||||||
|
compile(project(":compiler:util"))
|
||||||
|
compile(project(":compiler:ir.psi2ir"))
|
||||||
|
compile(project(":compiler:ir.backend.common"))
|
||||||
|
|
||||||
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|||||||
+1
-1
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
|
|
||||||
// This is all information needed to find a descriptor in the
|
// This is all information needed to find a descriptor in the
|
||||||
// tree of deserialized descriptors. Think of it as base + offset.
|
// tree of deserialized descriptors. Think of it as base + offset.
|
||||||
|
|||||||
+18
-3
@@ -5,9 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.serialization
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
//import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataProtoBuf
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.UniqId as ProtoUniqId
|
import org.jetbrains.kotlin.backend.common.serialization.proto.UniqId as ProtoUniqId
|
||||||
|
|
||||||
// This is an abstract uniqIdIndex any serialized IR declarations gets.
|
// This is an abstract uniqIdIndex any serialized IR declarations gets.
|
||||||
@@ -35,4 +37,17 @@ interface DescriptorUniqIdAware {
|
|||||||
fun DeclarationDescriptor.getUniqId(): Long?
|
fun DeclarationDescriptor.getUniqId(): Long?
|
||||||
}
|
}
|
||||||
|
|
||||||
//val UniqId.declarationFileName: String get() = "$index${if (isLocal) "L" else "G"}.kjd"
|
object DeserializedDescriptorUniqIdAware : DescriptorUniqIdAware {
|
||||||
|
override fun DeclarationDescriptor.getUniqId(): Long? = when (this) {
|
||||||
|
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(KlibMetadataProtoBuf.classUniqId)
|
||||||
|
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.functionUniqId)
|
||||||
|
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.propertyUniqId)
|
||||||
|
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.constructorUniqId)
|
||||||
|
is DeserializedTypeParameterDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.typeParamUniqId)
|
||||||
|
is DeserializedTypeAliasDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.typeAliasUniqId)
|
||||||
|
else -> null
|
||||||
|
}?.index
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newDescriptorUniqId(index: Long): KlibMetadataProtoBuf.DescriptorUniqId =
|
||||||
|
KlibMetadataProtoBuf.DescriptorUniqId.newBuilder().setIndex(index).build()
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.ir.backend.js.lower.serialization.metadata
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer
|
import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer
|
||||||
+5
-4
@@ -5,13 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
sealed class JsKlibFileMetadata
|
sealed class KlibFileMetadata
|
||||||
|
|
||||||
data class KotlinPsiFileMetadata(val ktFile: KtFile) : JsKlibFileMetadata()
|
data class KotlinPsiFileMetadata(val ktFile: KtFile) : KlibFileMetadata()
|
||||||
|
|
||||||
data class KotlinDeserializedFileMetadata(
|
data class KotlinDeserializedFileMetadata(
|
||||||
val packageFragment: JsKlibMetadataPackageFragment,
|
val packageFragment: KlibMetadataPackageFragment,
|
||||||
val fileId: Int
|
val fileId: Int
|
||||||
) : JsKlibFileMetadata()
|
) : KlibFileMetadata()
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.extractFileId
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||||
|
|
||||||
|
|
||||||
|
class KlibMetadataFileRegistry {
|
||||||
|
private val fileIdsImpl = mutableMapOf<KlibFileMetadata, Int>()
|
||||||
|
|
||||||
|
fun lookup(file: KlibFileMetadata) = fileIdsImpl.getOrPut(file) { fileIdsImpl.size }
|
||||||
|
|
||||||
|
val fileIds: Map<KlibFileMetadata, Int>
|
||||||
|
get() = fileIdsImpl
|
||||||
|
|
||||||
|
fun getFileId(descriptor: DeclarationDescriptor): Int? {
|
||||||
|
if (!DescriptorUtils.isTopLevelDeclaration(descriptor) || descriptor !is DeclarationDescriptorWithSource) return null
|
||||||
|
|
||||||
|
val fileId = descriptor.extractFileId()
|
||||||
|
if (fileId != null) {
|
||||||
|
(descriptor.containingDeclaration as? KlibMetadataPackageFragment)?.let { packageFragment ->
|
||||||
|
return this.lookup(KotlinDeserializedFileMetadata(packageFragment, fileId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val file = descriptor.source.containingFile as? PsiSourceFile ?: return null
|
||||||
|
|
||||||
|
val psiFile = file.psiFile
|
||||||
|
return (psiFile as? KtFile)?.let { this.lookup(KotlinPsiFileMetadata(it)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.isExpectMember
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.isSerializableExpectClass
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataSerializer
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
|
||||||
|
// TODO: need a refactoring between IncrementalSerializer and MonolithicSerializer.
|
||||||
|
class KlibMetadataIncrementalSerializer(
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
metadataVersion: BinaryVersion,
|
||||||
|
descriptorTable: DescriptorTable
|
||||||
|
) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable) {
|
||||||
|
|
||||||
|
fun serializePackageFragment(
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
module: ModuleDescriptor,
|
||||||
|
scope: Collection<DeclarationDescriptor>,
|
||||||
|
fqName: FqName
|
||||||
|
): ProtoBuf.PackageFragment {
|
||||||
|
|
||||||
|
val allDescriptors = scope.filter {
|
||||||
|
it.module == module
|
||||||
|
}
|
||||||
|
|
||||||
|
val classifierDescriptors = allDescriptors
|
||||||
|
.filterIsInstance<ClassifierDescriptor>()
|
||||||
|
.filter { !it.isExpectMember || it.isSerializableExpectClass }
|
||||||
|
.sortedBy { it.fqNameSafe.asString() }
|
||||||
|
|
||||||
|
val topLevelDescriptors = DescriptorSerializer.sort(
|
||||||
|
allDescriptors
|
||||||
|
.filterIsInstance<CallableDescriptor>()
|
||||||
|
.filter { !it.isExpectMember }
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: For now, in the incremental serializer, we assume
|
||||||
|
// there is only a single package fragment per file.
|
||||||
|
// This is no always the case, actually.
|
||||||
|
// But marrying split package fragments with incremental compilation is an endeavour.
|
||||||
|
// See monolithic serializer for details.
|
||||||
|
return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors, bindingContext).single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun serializedMetadata(
|
||||||
|
fragments: Map<String, List<ByteArray>>,
|
||||||
|
header: ByteArray
|
||||||
|
): SerializedMetadata {
|
||||||
|
val fragmentNames = mutableListOf<String>()
|
||||||
|
val fragmentParts = mutableListOf<List<ByteArray>>()
|
||||||
|
|
||||||
|
for ((fqName, fragment) in fragments.entries.sortedBy { it.key }) {
|
||||||
|
fragmentNames += fqName
|
||||||
|
fragmentParts += fragment
|
||||||
|
}
|
||||||
|
|
||||||
|
return SerializedMetadata(header, fragmentParts, fragmentNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: For now, in the incremental serializer, we assume
|
||||||
|
// there is only a single package fragment per file.
|
||||||
|
// This is no always the case, actually.
|
||||||
|
// But marrying split package fragments with incremental compilation is an endeavour.
|
||||||
|
// See monolithic serializer for details.
|
||||||
|
override val TOP_LEVEL_DECLARATION_COUNT_PER_FILE = null
|
||||||
|
override val TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE = null
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.isExpectMember
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.isSerializableExpectClass
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
|
||||||
|
// TODO: need a refactoring between IncrementalSerializer and MonolithicSerializer.
|
||||||
|
class KlibMetadataMonolithicSerializer(
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
metadataVersion: BinaryVersion,
|
||||||
|
descriptorTable: DescriptorTable,
|
||||||
|
val bindingContext: BindingContext
|
||||||
|
) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable) {
|
||||||
|
|
||||||
|
protected fun serializePackageFragment(fqName: FqName,
|
||||||
|
module: ModuleDescriptor,
|
||||||
|
bindingContext: BindingContext
|
||||||
|
):
|
||||||
|
List<ProtoBuf.PackageFragment> {
|
||||||
|
|
||||||
|
// TODO: ModuleDescriptor should be able to return
|
||||||
|
// the package only with the contents of that module, without dependencies
|
||||||
|
|
||||||
|
val fragments = module.getPackage(fqName).fragments.filter { it.module == module }
|
||||||
|
if (fragments.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
val classifierDescriptors = DescriptorSerializer.sort(
|
||||||
|
fragments.flatMap {
|
||||||
|
it.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.CLASSIFIERS)
|
||||||
|
}.filter { !it.isExpectMember || it.isSerializableExpectClass }
|
||||||
|
)
|
||||||
|
|
||||||
|
val topLevelDescriptors = DescriptorSerializer.sort(
|
||||||
|
fragments.flatMap { fragment ->
|
||||||
|
fragment.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.CALLABLES)
|
||||||
|
}.filter { !it.isExpectMember }
|
||||||
|
)
|
||||||
|
|
||||||
|
return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors, bindingContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun serializeModule(moduleDescriptor: ModuleDescriptor): SerializedMetadata {
|
||||||
|
|
||||||
|
val fragments = mutableListOf<List<ByteArray>>()
|
||||||
|
val fragmentNames = mutableListOf<String>()
|
||||||
|
val emptyPackages = mutableListOf<String>()
|
||||||
|
|
||||||
|
for (packageFqName in getPackagesFqNames(moduleDescriptor)) {
|
||||||
|
val packageProtos =
|
||||||
|
serializePackageFragment(packageFqName, moduleDescriptor, bindingContext)
|
||||||
|
if (packageProtos.isEmpty()) continue
|
||||||
|
|
||||||
|
val packageFqNameStr = packageFqName.asString()
|
||||||
|
|
||||||
|
if (packageProtos.all { it.getExtension(KlibMetadataProtoBuf.isEmpty)}) {
|
||||||
|
emptyPackages.add(packageFqNameStr)
|
||||||
|
}
|
||||||
|
fragments.add(packageProtos.map { it.toByteArray() })
|
||||||
|
fragmentNames.add(packageFqNameStr)
|
||||||
|
|
||||||
|
}
|
||||||
|
val header = serializeHeader(moduleDescriptor, fragmentNames, emptyPackages)
|
||||||
|
|
||||||
|
val libraryAsByteArray = header.toByteArray()
|
||||||
|
return SerializedMetadata(libraryAsByteArray, fragments, fragmentNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
// For platform libraries we get HUGE files.
|
||||||
|
// Indexing them in IDEA takes ages.
|
||||||
|
// So we split them into chunks.
|
||||||
|
override val TOP_LEVEL_DECLARATION_COUNT_PER_FILE = 128
|
||||||
|
override val TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE = 64
|
||||||
|
|
||||||
|
}
|
||||||
+314
@@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.backend.common.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.newDescriptorUniqId
|
||||||
|
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.KlibMetadataFileRegistry
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.KotlinPsiFileMetadata
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.filterOutSourceAnnotations
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.serialization.AnnotationSerializer
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||||
|
|
||||||
|
internal fun <T, R> Iterable<T>.maybeChunked(size: Int?, transform: (List<T>) -> R): List<R>
|
||||||
|
= size?.let { this.chunked(size, transform) } ?: listOf(transform(this.toList()))
|
||||||
|
|
||||||
|
abstract class KlibMetadataSerializer(
|
||||||
|
val languageVersionSettings: LanguageVersionSettings,
|
||||||
|
val metadataVersion: BinaryVersion,
|
||||||
|
val descriptorTable: DescriptorTable
|
||||||
|
) {
|
||||||
|
|
||||||
|
val fileRegistry = KlibMetadataFileRegistry()
|
||||||
|
|
||||||
|
lateinit var serializerContext: SerializerContext
|
||||||
|
|
||||||
|
data class SerializerContext(
|
||||||
|
val serializerExtension: KlibMetadataSerializerExtension,
|
||||||
|
val topSerializer: DescriptorSerializer,
|
||||||
|
var classSerializer: DescriptorSerializer = topSerializer
|
||||||
|
)
|
||||||
|
|
||||||
|
fun declarationTableHandler(declarationDescriptor: DeclarationDescriptor): KlibMetadataProtoBuf.DescriptorUniqId {
|
||||||
|
val index = descriptorTable.get(declarationDescriptor) ?: error("No descriptor ID found for $declarationDescriptor")
|
||||||
|
return index.let { newDescriptorUniqId(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun createNewContext(): SerializerContext {
|
||||||
|
|
||||||
|
val extension = KlibMetadataSerializerExtension(
|
||||||
|
languageVersionSettings,
|
||||||
|
metadataVersion,
|
||||||
|
::declarationTableHandler,
|
||||||
|
{descriptor -> fileRegistry.getFileId(descriptor) } ,
|
||||||
|
KlibMetadataStringTable()
|
||||||
|
)
|
||||||
|
return SerializerContext(
|
||||||
|
extension,
|
||||||
|
DescriptorSerializer.createTopLevel(extension)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected inline fun <T> withNewContext(crossinline block: SerializerContext.() -> T): T {
|
||||||
|
serializerContext = createNewContext()
|
||||||
|
return with(serializerContext, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun SerializerContext.buildFragment(
|
||||||
|
packageProto: ProtoBuf.Package,
|
||||||
|
classesProto: List<Pair<ProtoBuf.Class, Int>>,
|
||||||
|
fqName: FqName,
|
||||||
|
isEmpty: Boolean,
|
||||||
|
bindingContext: BindingContext
|
||||||
|
): ProtoBuf.PackageFragment {
|
||||||
|
|
||||||
|
val (stringTableProto, nameTableProto) = serializerExtension.stringTable.buildProto()
|
||||||
|
|
||||||
|
// TODO: we place files table to each and every fragment.
|
||||||
|
// Need to refactor it out sonehow.
|
||||||
|
val files = serializeFiles(fileRegistry, bindingContext, AnnotationSerializer(serializerExtension.stringTable))
|
||||||
|
|
||||||
|
return ProtoBuf.PackageFragment.newBuilder()
|
||||||
|
.setPackage(packageProto)
|
||||||
|
.addAllClass_(classesProto.map { it.first })
|
||||||
|
.setStrings(stringTableProto)
|
||||||
|
.setQualifiedNames(nameTableProto)
|
||||||
|
.also { packageFragment ->
|
||||||
|
classesProto.forEach {
|
||||||
|
packageFragment.addExtension(KlibMetadataProtoBuf.className, it.second )
|
||||||
|
}
|
||||||
|
packageFragment.setExtension(KlibMetadataProtoBuf.packageFragmentFiles, files)
|
||||||
|
packageFragment.setExtension(KlibMetadataProtoBuf.isEmpty, isEmpty)
|
||||||
|
packageFragment.setExtension(KlibMetadataProtoBuf.fqName, fqName.asString())
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun serializeClass(packageName: FqName,
|
||||||
|
classDescriptor: ClassDescriptor): List<Pair<ProtoBuf.Class, Int>> {
|
||||||
|
with(serializerContext) {
|
||||||
|
val previousSerializer = classSerializer
|
||||||
|
|
||||||
|
classSerializer = DescriptorSerializer.create(classDescriptor, serializerExtension, classSerializer)
|
||||||
|
val classProto = classSerializer.classProto(classDescriptor).build() ?: error("Class not serialized: $classDescriptor")
|
||||||
|
//builder.addClass(classProto)
|
||||||
|
|
||||||
|
val index = classSerializer.stringTable.getFqNameIndex(classDescriptor)
|
||||||
|
//builder.addExtension(KlibMetadataProtoBuf.className, index)
|
||||||
|
|
||||||
|
val classes = serializeClasses(packageName/*, builder*/,
|
||||||
|
classDescriptor.unsubstitutedInnerClassesScope
|
||||||
|
.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS))
|
||||||
|
|
||||||
|
classSerializer = previousSerializer
|
||||||
|
return classes + Pair(classProto, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun serializeClasses(packageName: FqName,
|
||||||
|
//builder: ProtoBuf.PackageFragment.Builder,
|
||||||
|
descriptors: Collection<DeclarationDescriptor>): List<Pair<ProtoBuf.Class, Int>> {
|
||||||
|
|
||||||
|
return descriptors.filterIsInstance<ClassDescriptor>().flatMap {
|
||||||
|
serializeClass(packageName, /*builder, */it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun emptyPackageProto(): ProtoBuf.Package = ProtoBuf.Package.newBuilder().build()
|
||||||
|
|
||||||
|
private fun SerializerContext.buildPackageProto(
|
||||||
|
fqName: FqName,
|
||||||
|
descriptors: List<DeclarationDescriptor>) = topSerializer.packagePartProto(fqName, descriptors).build()
|
||||||
|
?: error("Package fragments not serialized: for $descriptors")
|
||||||
|
|
||||||
|
protected fun serializeDescriptors(
|
||||||
|
fqName: FqName,
|
||||||
|
classifierDescriptors: List<DeclarationDescriptor>,
|
||||||
|
topLevelDescriptors: List<DeclarationDescriptor>,
|
||||||
|
bindingContext: BindingContext
|
||||||
|
): List<ProtoBuf.PackageFragment> {
|
||||||
|
|
||||||
|
if (TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE == null &&
|
||||||
|
TOP_LEVEL_DECLARATION_COUNT_PER_FILE == null) {
|
||||||
|
|
||||||
|
val typeAliases = classifierDescriptors.filterIsInstance<TypeAliasDescriptor>()
|
||||||
|
val nonCassDescriptors = topLevelDescriptors+typeAliases
|
||||||
|
|
||||||
|
|
||||||
|
return listOf(withNewContext {
|
||||||
|
val packageProto = if (nonCassDescriptors.isEmpty())
|
||||||
|
emptyPackageProto()
|
||||||
|
else
|
||||||
|
buildPackageProto(fqName, nonCassDescriptors)
|
||||||
|
|
||||||
|
buildFragment(
|
||||||
|
packageProto,
|
||||||
|
serializeClasses(fqName, classifierDescriptors),
|
||||||
|
fqName,
|
||||||
|
topLevelDescriptors.isEmpty() && classifierDescriptors.isEmpty(),
|
||||||
|
bindingContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = mutableListOf<ProtoBuf.PackageFragment>()
|
||||||
|
|
||||||
|
result += classifierDescriptors.maybeChunked(TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE) { descriptors ->
|
||||||
|
|
||||||
|
withNewContext {
|
||||||
|
|
||||||
|
//val classesProto = buildClassesProto { classesBuilder ->
|
||||||
|
// serializeClasses(fqName, classesBuilder, descriptors)
|
||||||
|
//}
|
||||||
|
val classesProto = serializeClasses(fqName, descriptors)
|
||||||
|
|
||||||
|
val typeAliases = descriptors.filterIsInstance<TypeAliasDescriptor>()
|
||||||
|
val packageProto =
|
||||||
|
if (typeAliases.isNotEmpty()) buildPackageProto(fqName, typeAliases)
|
||||||
|
else emptyPackageProto()
|
||||||
|
|
||||||
|
buildFragment(
|
||||||
|
packageProto,
|
||||||
|
classesProto,
|
||||||
|
fqName,
|
||||||
|
descriptors.isEmpty(),
|
||||||
|
bindingContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result += topLevelDescriptors.maybeChunked(TOP_LEVEL_DECLARATION_COUNT_PER_FILE) { descriptors ->
|
||||||
|
withNewContext {
|
||||||
|
buildFragment(
|
||||||
|
buildPackageProto(fqName, descriptors),
|
||||||
|
emptyList(),
|
||||||
|
fqName,
|
||||||
|
descriptors.isEmpty(),
|
||||||
|
bindingContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
result += withNewContext {
|
||||||
|
buildFragment(
|
||||||
|
emptyPackageProto(),
|
||||||
|
emptyList(),
|
||||||
|
fqName,
|
||||||
|
true,
|
||||||
|
bindingContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun serializeFiles(
|
||||||
|
fileRegistry: KlibMetadataFileRegistry,
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
serializer: AnnotationSerializer
|
||||||
|
): KlibMetadataProtoBuf.Files {
|
||||||
|
val filesProto = KlibMetadataProtoBuf.Files.newBuilder()
|
||||||
|
for ((file, id) in fileRegistry.fileIds.entries.sortedBy { it.value }) {
|
||||||
|
val fileProto = KlibMetadataProtoBuf.File.newBuilder()
|
||||||
|
if (id != filesProto.fileCount) {
|
||||||
|
fileProto.id = id
|
||||||
|
}
|
||||||
|
val annotations = when (file) {
|
||||||
|
is KotlinPsiFileMetadata -> file.ktFile.annotationEntries.map { bindingContext[BindingContext.ANNOTATION, it]!! }
|
||||||
|
//is KotlinDeserializedFileMetadata -> file.packageFragment.fileMap[file.fileId]!!.annotations
|
||||||
|
else -> TODO("support other file types")
|
||||||
|
}
|
||||||
|
for (annotation in annotations.filterOutSourceAnnotations()) {
|
||||||
|
fileProto.addAnnotation(serializer.serializeAnnotation(annotation))
|
||||||
|
}
|
||||||
|
val name = when (file) {
|
||||||
|
is KotlinPsiFileMetadata -> file.ktFile.getName()
|
||||||
|
else -> TODO("support other file types")
|
||||||
|
}
|
||||||
|
fileProto.name = name
|
||||||
|
filesProto.addFile(fileProto)
|
||||||
|
}
|
||||||
|
return filesProto.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
|
||||||
|
val result = mutableSetOf<FqName>()
|
||||||
|
|
||||||
|
fun getSubPackages(fqName: FqName) {
|
||||||
|
result.add(fqName)
|
||||||
|
module.getSubPackagesOf(fqName) { true }.forEach { getSubPackages(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubPackages(FqName.ROOT)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun serializeHeader(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
fragmentNames: List<String>,
|
||||||
|
emptyPackages: List<String> = emptyList()
|
||||||
|
): KlibMetadataProtoBuf.Header {
|
||||||
|
val header = KlibMetadataProtoBuf.Header.newBuilder()
|
||||||
|
|
||||||
|
header.moduleName = moduleDescriptor.name.asString()
|
||||||
|
|
||||||
|
if (languageVersionSettings.isPreRelease()) {
|
||||||
|
header.flags = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val experimentalAnnotationFqNames = languageVersionSettings.getFlag(AnalysisFlags.experimental)
|
||||||
|
if (experimentalAnnotationFqNames.isNotEmpty()) {
|
||||||
|
val stringTable = StringTableImpl()
|
||||||
|
for (fqName in experimentalAnnotationFqNames) {
|
||||||
|
val descriptor = moduleDescriptor.resolveClassByFqName(FqName(fqName), NoLookupLocation.FOR_ALREADY_TRACKED) ?: continue
|
||||||
|
header.addAnnotation(ProtoBuf.Annotation.newBuilder().apply {
|
||||||
|
id = stringTable.getFqNameIndex(descriptor)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
val (strings, qualifiedNames) = stringTable.buildProto()
|
||||||
|
header.strings = strings
|
||||||
|
header.qualifiedNames = qualifiedNames
|
||||||
|
}
|
||||||
|
fragmentNames.forEach {
|
||||||
|
header.addPackageFragmentName(it)
|
||||||
|
}
|
||||||
|
emptyPackages.forEach {
|
||||||
|
header.addEmptyPackage(it)
|
||||||
|
}
|
||||||
|
return header.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
// For platform libraries we get HUGE files.
|
||||||
|
// Indexing them in IDEA takes ages.
|
||||||
|
// So we split them into chunks.
|
||||||
|
abstract protected val TOP_LEVEL_DECLARATION_COUNT_PER_FILE: Int?
|
||||||
|
abstract protected val TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE: Int?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeclarationDescriptor.extractFileId(): Int? = when (this) {
|
||||||
|
is DeserializedClassDescriptor -> classProto.getExtension(KlibMetadataProtoBuf.classFile)
|
||||||
|
is DeserializedSimpleFunctionDescriptor -> proto.getExtension(KlibMetadataProtoBuf.functionFile)
|
||||||
|
is DeserializedPropertyDescriptor -> proto.getExtension(KlibMetadataProtoBuf.propertyFile)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
+24
-46
@@ -3,56 +3,57 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.ir.backend.js.lower.serialization.metadata
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
||||||
|
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||||
import org.jetbrains.kotlin.types.FlexibleType
|
import org.jetbrains.kotlin.types.FlexibleType
|
||||||
|
|
||||||
class JsKlibMetadataSerializerExtension(
|
class KlibMetadataSerializerExtension(
|
||||||
private val fileRegistry: JsKlibMetadataFileRegistry,
|
|
||||||
private val languageVersionSettings: LanguageVersionSettings,
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
override val metadataVersion: BinaryVersion,
|
override val metadataVersion: BinaryVersion,
|
||||||
val declarationTableHandler: ((DeclarationDescriptor) -> JsKlibMetadataProtoBuf.DescriptorUniqId?)
|
val declarationTableHandler: (DeclarationDescriptor) -> KlibMetadataProtoBuf.DescriptorUniqId?,
|
||||||
) : KotlinSerializerExtensionBase(JsKlibMetadataSerializerProtocol) {
|
val descriptorFileId: (DeclarationDescriptor) -> Int?,
|
||||||
override val stringTable = JsKlibMetadataStringTable()
|
override val stringTable: StringTableImpl
|
||||||
|
) : KotlinSerializerExtensionBase(KlibMetadataSerializerProtocol) {
|
||||||
|
override fun shouldUseTypeTable(): Boolean = true
|
||||||
|
|
||||||
override fun serializeFlexibleType(flexibleType: FlexibleType, lowerProto: ProtoBuf.Type.Builder, upperProto: ProtoBuf.Type.Builder) {
|
override fun serializeFlexibleType(flexibleType: FlexibleType, lowerProto: ProtoBuf.Type.Builder, upperProto: ProtoBuf.Type.Builder) {
|
||||||
lowerProto.flexibleTypeCapabilitiesId = stringTable.getStringIndex(DynamicTypeDeserializer.id)
|
lowerProto.flexibleTypeCapabilitiesId = stringTable.getStringIndex(DynamicTypeDeserializer.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun uniqId(descriptor: DeclarationDescriptor): JsKlibMetadataProtoBuf.DescriptorUniqId? {
|
private fun uniqId(descriptor: DeclarationDescriptor): KlibMetadataProtoBuf.DescriptorUniqId? {
|
||||||
return declarationTableHandler(descriptor)
|
return declarationTableHandler(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeTypeParameter(typeParameter: TypeParameterDescriptor, proto: ProtoBuf.TypeParameter.Builder) {
|
override fun serializeTypeParameter(typeParameter: TypeParameterDescriptor, proto: ProtoBuf.TypeParameter.Builder) {
|
||||||
uniqId(typeParameter)?.let { proto.setExtension(JsKlibMetadataProtoBuf.typeParamUniqId, it) }
|
uniqId(typeParameter)?.let { proto.setExtension(KlibMetadataProtoBuf.typeParamUniqId, it) }
|
||||||
super.serializeTypeParameter(typeParameter, proto)
|
super.serializeTypeParameter(typeParameter, proto)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeTypeAlias(typeAlias: TypeAliasDescriptor, proto: ProtoBuf.TypeAlias.Builder) {
|
override fun serializeTypeAlias(typeAlias: TypeAliasDescriptor, proto: ProtoBuf.TypeAlias.Builder) {
|
||||||
uniqId(typeAlias)?.let { proto.setExtension(JsKlibMetadataProtoBuf.typeAliasUniqId, it) }
|
uniqId(typeAlias)?.let { proto.setExtension(KlibMetadataProtoBuf.typeAliasUniqId, it) }
|
||||||
super.serializeTypeAlias(typeAlias, proto)
|
super.serializeTypeAlias(typeAlias, proto)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeEnumEntry(descriptor: ClassDescriptor, proto: ProtoBuf.EnumEntry.Builder) {
|
override fun serializeEnumEntry(descriptor: ClassDescriptor, proto: ProtoBuf.EnumEntry.Builder) {
|
||||||
uniqId(descriptor)?.let { proto.setExtension(JsKlibMetadataProtoBuf.enumEntryUniqId, it) }
|
uniqId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.enumEntryUniqId, it) }
|
||||||
super.serializeEnumEntry(descriptor, proto)
|
super.serializeEnumEntry(descriptor, proto)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder,
|
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder,
|
||||||
childSerializer: DescriptorSerializer
|
childSerializer: DescriptorSerializer
|
||||||
) {
|
) {
|
||||||
uniqId(descriptor)?.let { proto.setExtension(JsKlibMetadataProtoBuf.constructorUniqId, it) }
|
uniqId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.constructorUniqId, it) }
|
||||||
super.serializeConstructor(descriptor, proto, childSerializer)
|
super.serializeConstructor(descriptor, proto, childSerializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,12 +63,10 @@ class JsKlibMetadataSerializerExtension(
|
|||||||
versionRequirementTable: MutableVersionRequirementTable,
|
versionRequirementTable: MutableVersionRequirementTable,
|
||||||
childSerializer: DescriptorSerializer
|
childSerializer: DescriptorSerializer
|
||||||
) {
|
) {
|
||||||
uniqId(descriptor)?.let { proto.setExtension(JsKlibMetadataProtoBuf.classUniqId, it) }
|
uniqId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.classUniqId, it) }
|
||||||
val id = getFileId(descriptor)
|
descriptorFileId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.classFile, it) }
|
||||||
if (id != null) {
|
|
||||||
proto.setExtension(JsKlibMetadataProtoBuf.classContainingFileId, id)
|
|
||||||
}
|
|
||||||
super.serializeClass(descriptor, proto, versionRequirementTable, childSerializer)
|
super.serializeClass(descriptor, proto, versionRequirementTable, childSerializer)
|
||||||
|
childSerializer.typeTable.serialize()?.let { proto.mergeTypeTable(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeProperty(
|
override fun serializeProperty(
|
||||||
@@ -76,11 +75,8 @@ class JsKlibMetadataSerializerExtension(
|
|||||||
versionRequirementTable: MutableVersionRequirementTable?,
|
versionRequirementTable: MutableVersionRequirementTable?,
|
||||||
childSerializer: DescriptorSerializer
|
childSerializer: DescriptorSerializer
|
||||||
) {
|
) {
|
||||||
uniqId(descriptor)?.let { proto.setExtension(JsKlibMetadataProtoBuf.propertyUniqId, it) }
|
uniqId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.propertyUniqId, it) }
|
||||||
val id = getFileId(descriptor)
|
descriptorFileId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.propertyFile, it) }
|
||||||
if (id != null) {
|
|
||||||
proto.setExtension(JsKlibMetadataProtoBuf.propertyContainingFileId, id)
|
|
||||||
}
|
|
||||||
super.serializeProperty(descriptor, proto, versionRequirementTable, childSerializer)
|
super.serializeProperty(descriptor, proto, versionRequirementTable, childSerializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,29 +86,11 @@ class JsKlibMetadataSerializerExtension(
|
|||||||
versionRequirementTable: MutableVersionRequirementTable?,
|
versionRequirementTable: MutableVersionRequirementTable?,
|
||||||
childSerializer: DescriptorSerializer
|
childSerializer: DescriptorSerializer
|
||||||
) {
|
) {
|
||||||
uniqId(descriptor)?.let { proto.setExtension(JsKlibMetadataProtoBuf.functionUniqId, it) }
|
uniqId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.functionUniqId, it) }
|
||||||
val id = getFileId(descriptor)
|
descriptorFileId(descriptor)?.let { proto.setExtension(KlibMetadataProtoBuf.functionFile, it) }
|
||||||
if (id != null) {
|
|
||||||
proto.setExtension(JsKlibMetadataProtoBuf.functionContainingFileId, id)
|
|
||||||
}
|
|
||||||
super.serializeFunction(descriptor, proto, versionRequirementTable, childSerializer)
|
super.serializeFunction(descriptor, proto, versionRequirementTable, childSerializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFileId(descriptor: DeclarationDescriptor): Int? {
|
override fun releaseCoroutines() =
|
||||||
if (!DescriptorUtils.isTopLevelDeclaration(descriptor) || descriptor !is DeclarationDescriptorWithSource) return null
|
languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||||
|
|
||||||
val fileId = descriptor.extractFileId()
|
|
||||||
if (fileId != null) {
|
|
||||||
(descriptor.containingDeclaration as? JsKlibMetadataPackageFragment)?.let { packageFragment ->
|
|
||||||
return fileRegistry.lookup(KotlinDeserializedFileMetadata(packageFragment, fileId))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val file = descriptor.source.containingFile as? PsiSourceFile ?: return null
|
|
||||||
|
|
||||||
val psiFile = file.psiFile
|
|
||||||
return (psiFile as? KtFile)?.let { fileRegistry.lookup(KotlinPsiFileMetadata(it)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun releaseCoroutines() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
|
||||||
}
|
}
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata;
|
|
||||||
|
|
||||||
import "core/metadata/src/metadata.proto";
|
|
||||||
|
|
||||||
option java_outer_classname = "JsKlibMetadataProtoBuf";
|
|
||||||
option optimize_for = LITE_RUNTIME;
|
|
||||||
|
|
||||||
message Header {
|
|
||||||
/*
|
|
||||||
preRelease
|
|
||||||
*/
|
|
||||||
optional int32 flags = 1;
|
|
||||||
|
|
||||||
// (patch << 16) + (minor << 8) + major
|
|
||||||
optional int32 js_code_binary_version = 2 [default = 1];
|
|
||||||
|
|
||||||
optional string package_fq_name = 3;
|
|
||||||
|
|
||||||
optional org.jetbrains.kotlin.metadata.StringTable strings = 4;
|
|
||||||
|
|
||||||
optional org.jetbrains.kotlin.metadata.QualifiedNameTable qualified_names = 5;
|
|
||||||
|
|
||||||
// Annotations on the whole module
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation annotation = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message File {
|
|
||||||
// If absent, id is the index of the file in the Files.file list
|
|
||||||
optional int32 id = 1;
|
|
||||||
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation annotation = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Files {
|
|
||||||
repeated File file = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DescriptorUniqId {
|
|
||||||
required int64 index = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Package {
|
|
||||||
optional int32 package_fq_name = 131;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Class {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation class_annotation = 130;
|
|
||||||
optional int32 class_containing_file_id = 135;
|
|
||||||
optional DescriptorUniqId class_uniq_id = 136;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Constructor {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation constructor_annotation = 130;
|
|
||||||
optional DescriptorUniqId constructor_uniq_id = 131;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Function {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation function_annotation = 130;
|
|
||||||
optional int32 function_containing_file_id = 135;
|
|
||||||
optional DescriptorUniqId function_uniq_id = 136;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Property {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation property_annotation = 130;
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation property_getter_annotation = 132;
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation property_setter_annotation = 133;
|
|
||||||
optional org.jetbrains.kotlin.metadata.Annotation.Argument.Value compile_time_value = 131;
|
|
||||||
optional int32 property_containing_file_id = 135;
|
|
||||||
optional DescriptorUniqId property_uniq_id = 136;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.EnumEntry {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation enum_entry_annotation = 130;
|
|
||||||
optional DescriptorUniqId enum_entry_uniq_id = 131;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.ValueParameter {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation parameter_annotation = 130;
|
|
||||||
optional DescriptorUniqId value_param_uniq_id = 131;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Type {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation type_annotation = 130;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.TypeParameter {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation type_parameter_annotation = 130;
|
|
||||||
optional DescriptorUniqId type_param_uniq_id = 131;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.PackageFragment {
|
|
||||||
optional Files package_fragment_files = 130;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.TypeAlias {
|
|
||||||
// TODO repeated org.jetbrains.kotlin.metadata.Annotation type_alias_annotation = 130;
|
|
||||||
optional DescriptorUniqId type_alias_uniq_id = 131;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Classes {
|
|
||||||
// id in StringTable
|
|
||||||
repeated int32 class_name = 1 [packed = true];
|
|
||||||
}
|
|
||||||
|
|
||||||
message Library {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.PackageFragment package_fragment = 2;
|
|
||||||
|
|
||||||
repeated string imported_module = 3;
|
|
||||||
}
|
|
||||||
@@ -10,22 +10,20 @@ import com.intellij.openapi.vfs.VfsUtilCore
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.newJsDescriptorUniqId
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataVersion
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.*
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.KlibMetadataIncrementalSerializer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.util.ExpectDeclarationRemover
|
import org.jetbrains.kotlin.ir.util.ExpectDeclarationRemover
|
||||||
@@ -37,11 +35,13 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.konan.KonanVersionImpl
|
import org.jetbrains.kotlin.konan.KonanVersionImpl
|
||||||
import org.jetbrains.kotlin.konan.MetaVersion
|
import org.jetbrains.kotlin.konan.MetaVersion
|
||||||
import org.jetbrains.kotlin.konan.properties.propertyList
|
import org.jetbrains.kotlin.konan.properties.propertyList
|
||||||
|
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||||
import org.jetbrains.kotlin.library.*
|
import org.jetbrains.kotlin.library.*
|
||||||
import org.jetbrains.kotlin.library.impl.buildKoltinLibrary
|
import org.jetbrains.kotlin.library.impl.buildKoltinLibrary
|
||||||
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
|
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||||
@@ -49,8 +49,8 @@ import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
|||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.jetbrains.kotlin.konan.file.File as KFile
|
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||||
@@ -69,8 +69,6 @@ val KotlinLibrary.isBuiltIns: Boolean
|
|||||||
fun loadKlib(klibPath: String) =
|
fun loadKlib(klibPath: String) =
|
||||||
createKotlinLibrary(KFile(KFile(klibPath).absolutePath))
|
createKotlinLibrary(KFile(KFile(klibPath).absolutePath))
|
||||||
|
|
||||||
internal val JS_KLIBRARY_CAPABILITY = ModuleDescriptor.Capability<KotlinLibrary>("JS KLIBRARY")
|
|
||||||
|
|
||||||
private val emptyLoggingContext = object : LoggingContext {
|
private val emptyLoggingContext = object : LoggingContext {
|
||||||
override var inVerbosePhase = false
|
override var inVerbosePhase = false
|
||||||
|
|
||||||
@@ -86,7 +84,7 @@ fun generateKLib(
|
|||||||
project: Project,
|
project: Project,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
allDependencies: List<KotlinLibrary>,
|
allDependencies: KotlinLibraryResolveResult,
|
||||||
friendDependencies: List<KotlinLibrary>,
|
friendDependencies: List<KotlinLibrary>,
|
||||||
outputKlibPath: String,
|
outputKlibPath: String,
|
||||||
nopack: Boolean
|
nopack: Boolean
|
||||||
@@ -136,7 +134,7 @@ fun generateKLib(
|
|||||||
psi2IrContext.bindingContext,
|
psi2IrContext.bindingContext,
|
||||||
files,
|
files,
|
||||||
outputKlibPath,
|
outputKlibPath,
|
||||||
allDependencies,
|
allDependencies.getFullList(),
|
||||||
moduleFragment,
|
moduleFragment,
|
||||||
icData,
|
icData,
|
||||||
nopack
|
nopack
|
||||||
@@ -164,7 +162,7 @@ fun loadIr(
|
|||||||
project: Project,
|
project: Project,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
allDependencies: List<KotlinLibrary>,
|
allDependencies: KotlinLibraryResolveResult,
|
||||||
friendDependencies: List<KotlinLibrary>
|
friendDependencies: List<KotlinLibrary>
|
||||||
): IrModuleInfo {
|
): IrModuleInfo {
|
||||||
val depsDescriptors = ModulesStructure(project, files, configuration, allDependencies, friendDependencies)
|
val depsDescriptors = ModulesStructure(project, files, configuration, allDependencies, friendDependencies)
|
||||||
@@ -177,7 +175,7 @@ fun loadIr(
|
|||||||
|
|
||||||
val deserializer = JsIrLinker(moduleDescriptor, JsMangler, emptyLoggingContext, irBuiltIns, symbolTable)
|
val deserializer = JsIrLinker(moduleDescriptor, JsMangler, emptyLoggingContext, irBuiltIns, symbolTable)
|
||||||
|
|
||||||
val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map {
|
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
|
||||||
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,70 +201,29 @@ private fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deseria
|
|||||||
Psi2IrTranslator(languageVersionSettings, configuration).generateModuleFragment(this, files, deserializer)
|
Psi2IrTranslator(languageVersionSettings, configuration).generateModuleFragment(this, files, deserializer)
|
||||||
|
|
||||||
|
|
||||||
private fun loadKlibMetadataParts(
|
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
|
||||||
moduleId: KotlinLibrary
|
val JsFactories = KlibMetadataFactories(::createBuiltIns, DynamicTypeDeserializer)
|
||||||
): JsKlibMetadataParts {
|
|
||||||
return JsKlibMetadataSerializationUtil.readModuleAsProto(moduleId.moduleHeaderData)
|
|
||||||
}
|
|
||||||
|
|
||||||
val ModuleDescriptor.kotlinLibrary get() = this.getCapability(JS_KLIBRARY_CAPABILITY)!!
|
|
||||||
|
|
||||||
private fun loadKlibMetadata(
|
|
||||||
parts: JsKlibMetadataParts,
|
|
||||||
moduleId: KotlinLibrary,
|
|
||||||
isBuiltIn: Boolean,
|
|
||||||
lookupTracker: LookupTracker,
|
|
||||||
storageManager: LockBasedStorageManager,
|
|
||||||
metadataVersion: JsKlibMetadataVersion,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
builtinsModule: ModuleDescriptorImpl?,
|
|
||||||
dependencies: List<ModuleDescriptorImpl>
|
|
||||||
): ModuleDescriptorImpl {
|
|
||||||
assert(isBuiltIn == (builtinsModule === null))
|
|
||||||
val builtIns = builtinsModule?.builtIns ?: object : KotlinBuiltIns(storageManager) {}
|
|
||||||
val md = ModuleDescriptorImpl(
|
|
||||||
Name.special("<${moduleId.moduleName}>"),
|
|
||||||
storageManager,
|
|
||||||
builtIns,
|
|
||||||
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to moduleId)
|
|
||||||
)
|
|
||||||
if (isBuiltIn) builtIns.builtInsModule = md
|
|
||||||
val currentModuleFragmentProvider = createJsKlibMetadataPackageFragmentProvider(
|
|
||||||
storageManager, md, parts.header, parts.body, metadataVersion,
|
|
||||||
CompilerDeserializationConfiguration(languageVersionSettings),
|
|
||||||
lookupTracker
|
|
||||||
)
|
|
||||||
|
|
||||||
val packageFragmentProvider = if (isBuiltIn) {
|
|
||||||
val functionFragmentProvider = functionInterfacePackageFragmentProvider(storageManager, md)
|
|
||||||
CompositePackageFragmentProvider(listOf(functionFragmentProvider, currentModuleFragmentProvider))
|
|
||||||
} else currentModuleFragmentProvider
|
|
||||||
|
|
||||||
md.initialize(packageFragmentProvider)
|
|
||||||
md.setDependencies(listOf(md) + dependencies)
|
|
||||||
|
|
||||||
return md
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ModulesStructure(
|
private class ModulesStructure(
|
||||||
private val project: Project,
|
private val project: Project,
|
||||||
private val files: List<KtFile>,
|
private val files: List<KtFile>,
|
||||||
val compilerConfiguration: CompilerConfiguration,
|
val compilerConfiguration: CompilerConfiguration,
|
||||||
private val allDependencies: List<KotlinLibrary>,
|
val allDependencies: KotlinLibraryResolveResult,
|
||||||
private val friendDependencies: List<KotlinLibrary>
|
private val friendDependencies: List<KotlinLibrary>
|
||||||
) {
|
) {
|
||||||
private val deserializedModuleParts: Map<KotlinLibrary, JsKlibMetadataParts> =
|
val moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>> = {
|
||||||
allDependencies.associateWith { loadKlibMetadataParts(it) }
|
val result = mutableMapOf<KotlinLibrary, List<KotlinLibrary>>()
|
||||||
|
|
||||||
fun findModuleByName(name: String): KotlinLibrary =
|
allDependencies.forEach { klib, _ ->
|
||||||
allDependencies.find { it.moduleName == name } ?: error("Module is not found: $name")
|
val dependencies = allDependencies.filterRoots {
|
||||||
|
it.library == klib
|
||||||
val moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>> =
|
}.getFullList(TopologicalLibraryOrder)
|
||||||
deserializedModuleParts.mapValues { (_, parts) ->
|
result.put(klib, dependencies.minus(klib))
|
||||||
parts.importedModules.map(::findModuleByName)
|
|
||||||
}
|
}
|
||||||
|
result
|
||||||
|
}()
|
||||||
|
|
||||||
val builtInsDep = allDependencies.find { it.isBuiltIns }
|
val builtInsDep = allDependencies.getFullList().find { it.isBuiltIns }
|
||||||
|
|
||||||
fun runAnalysis(): JsAnalysisResult {
|
fun runAnalysis(): JsAnalysisResult {
|
||||||
val analysisResult =
|
val analysisResult =
|
||||||
@@ -274,7 +231,7 @@ private class ModulesStructure(
|
|||||||
files,
|
files,
|
||||||
project,
|
project,
|
||||||
compilerConfiguration,
|
compilerConfiguration,
|
||||||
allDependencies.map { getModuleDescriptor(it) },
|
allDependencies.getFullList().map { getModuleDescriptor(it) },
|
||||||
friendModuleDescriptors = friendDependencies.map { getModuleDescriptor(it) },
|
friendModuleDescriptors = friendDependencies.map { getModuleDescriptor(it) },
|
||||||
thisIsBuiltInsModule = builtInModuleDescriptor == null,
|
thisIsBuiltInsModule = builtInModuleDescriptor == null,
|
||||||
customBuiltInsModule = builtInModuleDescriptor
|
customBuiltInsModule = builtInModuleDescriptor
|
||||||
@@ -286,31 +243,29 @@ private class ModulesStructure(
|
|||||||
return analysisResult
|
return analysisResult
|
||||||
}
|
}
|
||||||
|
|
||||||
private val lookupTracker: LookupTracker = LookupTracker.DO_NOTHING
|
|
||||||
private val metadataVersion: JsKlibMetadataVersion = compilerConfiguration.metadataVersion
|
|
||||||
private val languageVersionSettings: LanguageVersionSettings = compilerConfiguration.languageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings = compilerConfiguration.languageVersionSettings
|
||||||
|
|
||||||
private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure")
|
private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure")
|
||||||
private var runtimeModule: ModuleDescriptorImpl? = null
|
private var runtimeModule: ModuleDescriptorImpl? = null
|
||||||
|
|
||||||
|
// TODO: these are roughly equivalent to KlibResolvedModuleDescriptorsFactoryImpl. Refactor me.
|
||||||
val descriptors = mutableMapOf<KotlinLibrary, ModuleDescriptorImpl>()
|
val descriptors = mutableMapOf<KotlinLibrary, ModuleDescriptorImpl>()
|
||||||
|
|
||||||
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl = descriptors.getOrPut(current) {
|
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl = descriptors.getOrPut(current) {
|
||||||
val parts = loadKlibMetadataParts(current)
|
val isBuiltIns = current.unresolvedDependencies.isEmpty()
|
||||||
val isBuiltIns = parts.importedModules.isEmpty()
|
|
||||||
loadKlibMetadata(
|
val md = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||||
parts,
|
|
||||||
current,
|
current,
|
||||||
isBuiltIns,
|
|
||||||
lookupTracker,
|
|
||||||
storageManager,
|
|
||||||
metadataVersion,
|
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
runtimeModule,
|
storageManager,
|
||||||
moduleDependencies.getValue(current).map { getModuleDescriptor(it) }
|
runtimeModule?.builtIns,
|
||||||
).also {
|
packageAccessHandler = null // TODO: This is a speed optimization used by Native. Don't bother for now.
|
||||||
if (isBuiltIns) runtimeModule = it
|
)
|
||||||
}
|
if (isBuiltIns) runtimeModule = md
|
||||||
|
|
||||||
|
val dependencies = moduleDependencies.getValue(current).map { getModuleDescriptor(it) }
|
||||||
|
md.setDependencies(listOf(md) + dependencies)
|
||||||
|
md
|
||||||
}
|
}
|
||||||
|
|
||||||
val builtInModuleDescriptor =
|
val builtInModuleDescriptor =
|
||||||
@@ -318,6 +273,7 @@ private class ModulesStructure(
|
|||||||
getModuleDescriptor(builtInsDep)
|
getModuleDescriptor(builtInsDep)
|
||||||
else
|
else
|
||||||
null // null in case compiling builtInModule itself
|
null // null in case compiling builtInModule itself
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDescriptorForElement(
|
private fun getDescriptorForElement(
|
||||||
@@ -344,23 +300,20 @@ fun serializeModuleIntoKlib(
|
|||||||
|
|
||||||
val moduleDescriptor = moduleFragment.descriptor
|
val moduleDescriptor = moduleFragment.descriptor
|
||||||
|
|
||||||
val descriptorSelector = { declarationDescriptor: DeclarationDescriptor ->
|
|
||||||
val index = descriptorTable.get(declarationDescriptor) ?: error("No descriptor ID found for $declarationDescriptor")
|
|
||||||
newJsDescriptorUniqId(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
val metadataVersion = configuration.metadataVersion
|
val metadataVersion = configuration.metadataVersion
|
||||||
val languageVersionSettings = configuration.languageVersionSettings
|
val languageVersionSettings = configuration.languageVersionSettings
|
||||||
|
|
||||||
|
val metadataSerializer = KlibMetadataIncrementalSerializer(
|
||||||
|
languageVersionSettings,
|
||||||
|
metadataVersion,
|
||||||
|
descriptorTable)
|
||||||
|
|
||||||
fun serializeScope(fqName: FqName, memberScope: Collection<DeclarationDescriptor>): ByteArray {
|
fun serializeScope(fqName: FqName, memberScope: Collection<DeclarationDescriptor>): ByteArray {
|
||||||
return JsKlibMetadataSerializationUtil.serializeDescriptors(
|
return metadataSerializer.serializePackageFragment(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
moduleDescriptor,
|
moduleDescriptor,
|
||||||
memberScope,
|
memberScope,
|
||||||
fqName,
|
fqName
|
||||||
languageVersionSettings,
|
|
||||||
metadataVersion,
|
|
||||||
descriptorSelector
|
|
||||||
).toByteArray()
|
).toByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,25 +346,28 @@ fun serializeModuleIntoKlib(
|
|||||||
processCompiledFileData(VfsUtilCore.virtualToIoFile(ktFile.virtualFile), compiledKotlinFile)
|
processCompiledFileData(VfsUtilCore.virtualToIoFile(ktFile.virtualFile), compiledKotlinFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
incrementalResultsConsumer?.run {
|
|
||||||
processHeader(JsKlibMetadataSerializationUtil.serializeHeader(moduleDescriptor, null, languageVersionSettings).toByteArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
val compiledKotlinFiles = cleanFiles + additionalFiles
|
val compiledKotlinFiles = cleanFiles + additionalFiles
|
||||||
|
|
||||||
|
val header = metadataSerializer.serializeHeader(
|
||||||
|
moduleDescriptor,
|
||||||
|
compiledKotlinFiles.map { it.irData.fqName }.distinct()
|
||||||
|
).toByteArray()
|
||||||
|
incrementalResultsConsumer?.run {
|
||||||
|
processHeader(header)
|
||||||
|
}
|
||||||
|
|
||||||
val serializedMetadata =
|
val serializedMetadata =
|
||||||
JsKlibMetadataSerializationUtil.serializedMetadata(
|
metadataSerializer.serializedMetadata(
|
||||||
moduleDescriptor,
|
compiledKotlinFiles.groupBy { it.irData.fqName }.map { (fqn, data) -> fqn to data.sortedBy { it.irData.path }.map { it.metadata } }.toMap(),
|
||||||
languageVersionSettings,
|
header
|
||||||
dependencies.map { it.moduleName },
|
|
||||||
compiledKotlinFiles.groupBy { it.irData.fqName }.map { (fqn, data) -> fqn to data.sortedBy { it.irData.path }.map { it.metadata } }.toMap()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val fullSerializedIr = SerializedIrModule(compiledKotlinFiles.map { it.irData })
|
val fullSerializedIr = SerializedIrModule(compiledKotlinFiles.map { it.irData })
|
||||||
|
|
||||||
val abiVersion = KotlinAbiVersion.CURRENT
|
val abiVersion = KotlinAbiVersion.CURRENT
|
||||||
|
// DO NOT PUSH. Commonize me.
|
||||||
val compilerVersion = KonanVersionImpl(MetaVersion.DEV, 1, 3, 0, -1)
|
val compilerVersion = KonanVersionImpl(MetaVersion.DEV, 1, 3, 0, -1)
|
||||||
val libraryVersion = "JSIR"
|
val libraryVersion = null
|
||||||
|
|
||||||
val versions = KonanLibraryVersioning(abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion)
|
val versions = KonanLibraryVersioning(abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion)
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -6,16 +6,15 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorReferenceDeserializer
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.backend.common.serialization.DeserializedDescriptorUniqIdAware
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
class JsDescriptorReferenceDeserializer(
|
class JsDescriptorReferenceDeserializer(
|
||||||
currentModule: ModuleDescriptor,
|
currentModule: ModuleDescriptor,
|
||||||
mangler: KotlinMangler,
|
mangler: KotlinMangler,
|
||||||
builtIns: IrBuiltIns
|
builtIns: IrBuiltIns
|
||||||
) : DescriptorReferenceDeserializer(currentModule, mangler, builtIns, mutableMapOf()),
|
) : DescriptorReferenceDeserializer(currentModule, mangler, builtIns, mutableMapOf()),
|
||||||
DescriptorUniqIdAware by JsDescriptorUniqIdAware
|
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware
|
||||||
|
|||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.ir
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.tryGetExtension
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataProtoBuf
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
|
||||||
|
|
||||||
object JsDescriptorUniqIdAware: DescriptorUniqIdAware {
|
|
||||||
override fun DeclarationDescriptor.getUniqId(): Long? = when (this) {
|
|
||||||
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(JsKlibMetadataProtoBuf.classUniqId)
|
|
||||||
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.functionUniqId)
|
|
||||||
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.propertyUniqId)
|
|
||||||
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.constructorUniqId)
|
|
||||||
is DeserializedTypeParameterDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.typeParamUniqId)
|
|
||||||
is DeserializedTypeAliasDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.typeAliasUniqId)
|
|
||||||
else -> null
|
|
||||||
}?.index
|
|
||||||
}
|
|
||||||
|
|
||||||
fun newJsDescriptorUniqId(index: Long): JsKlibMetadataProtoBuf.DescriptorUniqId =
|
|
||||||
JsKlibMetadataProtoBuf.DescriptorUniqId.newBuilder().setIndex(index).build()
|
|
||||||
+2
-2
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.backend.js.kotlinLibrary
|
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||||
@@ -23,7 +23,7 @@ class JsIrLinker(
|
|||||||
builtIns: IrBuiltIns,
|
builtIns: IrBuiltIns,
|
||||||
symbolTable: SymbolTable
|
symbolTable: SymbolTable
|
||||||
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE),
|
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE),
|
||||||
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
|
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware {
|
||||||
|
|
||||||
override val descriptorReferenceDeserializer =
|
override val descriptorReferenceDeserializer =
|
||||||
JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns)
|
JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns)
|
||||||
|
|||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.metadata
|
|
||||||
|
|
||||||
|
|
||||||
class JsKlibMetadataFileRegistry {
|
|
||||||
private val fileIdsImpl = mutableMapOf<JsKlibFileMetadata, Int>()
|
|
||||||
|
|
||||||
fun lookup(file: JsKlibFileMetadata) = fileIdsImpl.getOrPut(file) { fileIdsImpl.size }
|
|
||||||
|
|
||||||
val fileIds: Map<JsKlibFileMetadata, Int>
|
|
||||||
get() = fileIdsImpl
|
|
||||||
}
|
|
||||||
-86
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.metadata
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.contracts.ContractDeserializerImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.parentOrNull
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
fun createJsKlibMetadataPackageFragmentProvider(
|
|
||||||
storageManager: StorageManager,
|
|
||||||
module: ModuleDescriptor,
|
|
||||||
header: JsKlibMetadataProtoBuf.Header,
|
|
||||||
packageFragmentProtos: List<ProtoBuf.PackageFragment>,
|
|
||||||
metadataVersion: JsKlibMetadataVersion,
|
|
||||||
configuration: DeserializationConfiguration,
|
|
||||||
lookupTracker: LookupTracker
|
|
||||||
): PackageFragmentProvider {
|
|
||||||
val packageFragments: MutableList<PackageFragmentDescriptor> = packageFragmentProtos.mapNotNullTo(mutableListOf()) { proto ->
|
|
||||||
proto.fqName?.let { fqName ->
|
|
||||||
JsKlibMetadataPackageFragment(fqName, storageManager, module, proto, header, metadataVersion, configuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate empty PackageFragmentDescriptor instances for packages that aren't mentioned in compilation units directly.
|
|
||||||
// For example, if there's `package foo.bar` directive, we'll get only PackageFragmentDescriptor for `foo.bar`, but
|
|
||||||
// none for `foo`. Various descriptor/scope code relies on presence of such package fragments, and currently we
|
|
||||||
// don't know if it's possible to fix this.
|
|
||||||
// TODO: think about fixing issues in descriptors/scopes
|
|
||||||
val packageFqNames = packageFragmentProtos.mapNotNullTo(mutableSetOf()) { it.fqName }
|
|
||||||
for (packageFqName in packageFqNames.mapNotNull { it.parentOrNull() }) {
|
|
||||||
var ancestorFqName = packageFqName
|
|
||||||
while (!ancestorFqName.isRoot && packageFqNames.add(ancestorFqName)) {
|
|
||||||
packageFragments += EmptyPackageFragmentDescriptor(module, ancestorFqName)
|
|
||||||
ancestorFqName = ancestorFqName.parent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val provider = PackageFragmentProviderImpl(packageFragments)
|
|
||||||
|
|
||||||
val notFoundClasses = NotFoundClasses(storageManager, module)
|
|
||||||
|
|
||||||
val components = DeserializationComponents(
|
|
||||||
storageManager,
|
|
||||||
module,
|
|
||||||
configuration,
|
|
||||||
DeserializedClassDataFinder(provider),
|
|
||||||
AnnotationAndConstantLoaderImpl(module, notFoundClasses, JsKlibMetadataSerializerProtocol),
|
|
||||||
provider,
|
|
||||||
LocalClassifierTypeSettings.Default,
|
|
||||||
ErrorReporter.DO_NOTHING,
|
|
||||||
lookupTracker,
|
|
||||||
DynamicTypeDeserializer,
|
|
||||||
emptyList(),
|
|
||||||
notFoundClasses,
|
|
||||||
ContractDeserializerImpl(configuration, storageManager),
|
|
||||||
platformDependentDeclarationFilter = PlatformDependentDeclarationFilter.All,
|
|
||||||
extensionRegistryLite = JsKlibMetadataSerializerProtocol.extensionRegistry
|
|
||||||
)
|
|
||||||
|
|
||||||
for (packageFragment in packageFragments.filterIsInstance<JsKlibMetadataPackageFragment>()) {
|
|
||||||
packageFragment.initialize(components)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
|
||||||
}
|
|
||||||
|
|
||||||
private val ProtoBuf.PackageFragment.fqName: FqName?
|
|
||||||
get() {
|
|
||||||
val nameResolver = NameResolverImpl(strings, qualifiedNames)
|
|
||||||
return when {
|
|
||||||
hasPackage() -> FqName(nameResolver.getPackageFqName(`package`.getExtension(JsKlibMetadataProtoBuf.packageFqName)))
|
|
||||||
class_Count > 0 -> nameResolver.getClassId(class_OrBuilderList.first().fqName).packageFqName
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-3
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.SourceFile
|
import org.jetbrains.kotlin.descriptors.SourceFile
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -22,14 +23,14 @@ class JsKlibMetadataPackageFragment(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
proto: ProtoBuf.PackageFragment,
|
proto: ProtoBuf.PackageFragment,
|
||||||
header: JsKlibMetadataProtoBuf.Header,
|
header: KlibMetadataProtoBuf.Header,
|
||||||
metadataVersion: JsKlibMetadataVersion,
|
metadataVersion: JsKlibMetadataVersion,
|
||||||
configuration: DeserializationConfiguration
|
configuration: DeserializationConfiguration
|
||||||
) : DeserializedPackageFragmentImpl(
|
) : DeserializedPackageFragmentImpl(
|
||||||
fqName, storageManager, module, proto, metadataVersion, JsContainerSource(fqName, header, configuration)
|
fqName, storageManager, module, proto, metadataVersion, JsContainerSource(fqName, header, configuration)
|
||||||
) {
|
) {
|
||||||
val fileMap: Map<Int, FileHolder> =
|
val fileMap: Map<Int, FileHolder> =
|
||||||
proto.getExtension(JsKlibMetadataProtoBuf.packageFragmentFiles).fileList.withIndex().associate { (index, file) ->
|
proto.getExtension(KlibMetadataProtoBuf.packageFragmentFiles).fileList.withIndex().associate { (index, file) ->
|
||||||
(if (file.hasId()) file.id else index) to FileHolder(file.annotationList)
|
(if (file.hasId()) file.id else index) to FileHolder(file.annotationList)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ class JsKlibMetadataPackageFragment(
|
|||||||
|
|
||||||
class JsContainerSource(
|
class JsContainerSource(
|
||||||
private val fqName: FqName,
|
private val fqName: FqName,
|
||||||
header: JsKlibMetadataProtoBuf.Header,
|
header: KlibMetadataProtoBuf.Header,
|
||||||
configuration: DeserializationConfiguration
|
configuration: DeserializationConfiguration
|
||||||
) : DeserializedContainerSource {
|
) : DeserializedContainerSource {
|
||||||
val annotations: List<ClassId> =
|
val annotations: List<ClassId> =
|
||||||
|
|||||||
-220
@@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.metadata
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|
||||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.filterOutSourceAnnotations
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.serialization.AnnotationSerializer
|
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
|
||||||
import org.jetbrains.kotlin.serialization.StringTableImpl
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.OutputStream
|
|
||||||
|
|
||||||
object JsKlibMetadataSerializationUtil {
|
|
||||||
|
|
||||||
fun serializedMetadata(
|
|
||||||
module: ModuleDescriptor,
|
|
||||||
settings: LanguageVersionSettings,
|
|
||||||
importedModules: List<String>,
|
|
||||||
fragments: Map<String, List<ByteArray>>
|
|
||||||
): SerializedMetadata {
|
|
||||||
val fragmentNames = mutableListOf<String>()
|
|
||||||
val fragmentParts = mutableListOf<List<ByteArray>>()
|
|
||||||
|
|
||||||
for ((fqName, fragment) in fragments.entries.sortedBy { it.key }) {
|
|
||||||
fragmentNames += fqName
|
|
||||||
fragmentParts += fragment
|
|
||||||
}
|
|
||||||
|
|
||||||
val stream = ByteArrayOutputStream()
|
|
||||||
|
|
||||||
serializeHeader(module, null, settings).writeDelimitedTo(stream)
|
|
||||||
asLibrary().writeTo(stream)
|
|
||||||
stream.appendPackageFragments(fragments)
|
|
||||||
importedModules.forEach {
|
|
||||||
stream.writeProto(JsKlibMetadataProtoBuf.Library.IMPORTED_MODULE_FIELD_NUMBER, it.toByteArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
val moduleLibrary = stream.toByteArray()
|
|
||||||
|
|
||||||
return SerializedMetadata(moduleLibrary, fragmentParts, fragmentNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun asLibrary(): JsKlibMetadataProtoBuf.Library {
|
|
||||||
return JsKlibMetadataProtoBuf.Library.newBuilder().build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun OutputStream.writeProto(fieldNumber: Int, content: ByteArray) {
|
|
||||||
// Message header
|
|
||||||
write((fieldNumber shl 3) or 2)
|
|
||||||
// Size varint
|
|
||||||
var size = content.size
|
|
||||||
while (size > 0x7F) {
|
|
||||||
write(0x80 or (size and 0x7F))
|
|
||||||
size = size ushr 7
|
|
||||||
}
|
|
||||||
write(size)
|
|
||||||
// Fragment itself
|
|
||||||
write(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun OutputStream.appendPackageFragments(serializedFragments: Map<String, List<ByteArray>>) {
|
|
||||||
for ((_, fragments) in serializedFragments.entries.sortedBy { it.key }) {
|
|
||||||
for (fragment in fragments) {
|
|
||||||
writeProto(JsKlibMetadataProtoBuf.Library.PACKAGE_FRAGMENT_FIELD_NUMBER, fragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun serializeHeader(
|
|
||||||
module: ModuleDescriptor, packageFqName: FqName?, languageVersionSettings: LanguageVersionSettings
|
|
||||||
): JsKlibMetadataProtoBuf.Header {
|
|
||||||
val header = JsKlibMetadataProtoBuf.Header.newBuilder()
|
|
||||||
|
|
||||||
if (packageFqName != null) {
|
|
||||||
header.packageFqName = packageFqName.asString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (languageVersionSettings.isPreRelease()) {
|
|
||||||
header.flags = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
val experimentalAnnotationFqNames = languageVersionSettings.getFlag(AnalysisFlags.experimental)
|
|
||||||
if (experimentalAnnotationFqNames.isNotEmpty()) {
|
|
||||||
val stringTable = StringTableImpl()
|
|
||||||
for (fqName in experimentalAnnotationFqNames) {
|
|
||||||
val descriptor = module.resolveClassByFqName(FqName(fqName), NoLookupLocation.FOR_ALREADY_TRACKED) ?: continue
|
|
||||||
header.addAnnotation(ProtoBuf.Annotation.newBuilder().apply {
|
|
||||||
id = stringTable.getFqNameIndex(descriptor)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
val (strings, qualifiedNames) = stringTable.buildProto()
|
|
||||||
header.strings = strings
|
|
||||||
header.qualifiedNames = qualifiedNames
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: write JS code binary version
|
|
||||||
|
|
||||||
return header.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun serializeDescriptors(
|
|
||||||
bindingContext: BindingContext,
|
|
||||||
module: ModuleDescriptor,
|
|
||||||
scope: Collection<DeclarationDescriptor>,
|
|
||||||
fqName: FqName,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
metadataVersion: BinaryVersion,
|
|
||||||
declarationTableHandler: ((DeclarationDescriptor) -> JsKlibMetadataProtoBuf.DescriptorUniqId?)
|
|
||||||
): ProtoBuf.PackageFragment {
|
|
||||||
val builder = ProtoBuf.PackageFragment.newBuilder()
|
|
||||||
|
|
||||||
val skip = fun(descriptor: DeclarationDescriptor): Boolean {
|
|
||||||
// TODO: ModuleDescriptor should be able to return the package only with the contents of that module, without dependencies
|
|
||||||
if (descriptor.module != module) return true
|
|
||||||
|
|
||||||
if (descriptor is MemberDescriptor && descriptor.isExpect) {
|
|
||||||
return !(descriptor is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(descriptor))
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val fileRegistry = JsKlibMetadataFileRegistry()
|
|
||||||
val extension = JsKlibMetadataSerializerExtension(fileRegistry, languageVersionSettings, metadataVersion, declarationTableHandler)
|
|
||||||
|
|
||||||
val classDescriptors = scope.filterIsInstance<ClassDescriptor>().sortedBy { it.fqNameSafe.asString() }
|
|
||||||
|
|
||||||
fun serializeClasses(descriptors: Collection<DeclarationDescriptor>, parentSerializer: DescriptorSerializer) {
|
|
||||||
for (descriptor in descriptors) {
|
|
||||||
if (descriptor !is ClassDescriptor || skip(descriptor)) continue
|
|
||||||
|
|
||||||
val serializer = DescriptorSerializer.create(descriptor, extension, parentSerializer)
|
|
||||||
serializeClasses(descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors(), serializer)
|
|
||||||
val classProto = serializer.classProto(descriptor).build() ?: error("Class not serialized: $descriptor")
|
|
||||||
builder.addClass_(classProto)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val serializer = DescriptorSerializer.createTopLevel(extension)
|
|
||||||
serializeClasses(classDescriptors, serializer)
|
|
||||||
|
|
||||||
val stringTable = extension.stringTable
|
|
||||||
|
|
||||||
val members = scope.filterNot(skip)
|
|
||||||
builder.`package` = serializer.packagePartProto(fqName, members).build()
|
|
||||||
|
|
||||||
builder.setExtension(
|
|
||||||
JsKlibMetadataProtoBuf.packageFragmentFiles,
|
|
||||||
serializeFiles(fileRegistry, bindingContext, AnnotationSerializer(stringTable))
|
|
||||||
)
|
|
||||||
|
|
||||||
val (strings, qualifiedNames) = stringTable.buildProto()
|
|
||||||
builder.strings = strings
|
|
||||||
builder.qualifiedNames = qualifiedNames
|
|
||||||
|
|
||||||
return builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun serializeFiles(
|
|
||||||
fileRegistry: JsKlibMetadataFileRegistry,
|
|
||||||
bindingContext: BindingContext,
|
|
||||||
serializer: AnnotationSerializer
|
|
||||||
): JsKlibMetadataProtoBuf.Files {
|
|
||||||
val filesProto = JsKlibMetadataProtoBuf.Files.newBuilder()
|
|
||||||
for ((file, id) in fileRegistry.fileIds.entries.sortedBy { it.value }) {
|
|
||||||
val fileProto = JsKlibMetadataProtoBuf.File.newBuilder()
|
|
||||||
if (id != filesProto.fileCount) {
|
|
||||||
fileProto.id = id
|
|
||||||
}
|
|
||||||
val annotations = when (file) {
|
|
||||||
is KotlinPsiFileMetadata -> file.ktFile.annotationEntries.map { bindingContext[BindingContext.ANNOTATION, it]!! }
|
|
||||||
is KotlinDeserializedFileMetadata -> file.packageFragment.fileMap[file.fileId]!!.annotations
|
|
||||||
}
|
|
||||||
for (annotation in annotations.filterOutSourceAnnotations()) {
|
|
||||||
fileProto.addAnnotation(serializer.serializeAnnotation(annotation))
|
|
||||||
}
|
|
||||||
filesProto.addFile(fileProto)
|
|
||||||
}
|
|
||||||
return filesProto.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun readModuleAsProto(metadata: ByteArray): JsKlibMetadataParts {
|
|
||||||
val inputStream = ByteArrayInputStream(metadata)
|
|
||||||
val header = JsKlibMetadataProtoBuf.Header.parseDelimitedFrom(inputStream, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
|
||||||
val content = JsKlibMetadataProtoBuf.Library.parseFrom(inputStream, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
|
||||||
return JsKlibMetadataParts(header, content.packageFragmentList, content.importedModuleList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class JsKlibMetadataParts(
|
|
||||||
val header: JsKlibMetadataProtoBuf.Header,
|
|
||||||
val body: List<ProtoBuf.PackageFragment>,
|
|
||||||
val importedModules: List<String>
|
|
||||||
)
|
|
||||||
|
|
||||||
internal fun DeclarationDescriptor.extractFileId(): Int? = when (this) {
|
|
||||||
is DeserializedClassDescriptor -> classProto.getExtension(JsKlibMetadataProtoBuf.classContainingFileId)
|
|
||||||
is DeserializedSimpleFunctionDescriptor -> proto.getExtension(JsKlibMetadataProtoBuf.functionContainingFileId)
|
|
||||||
is DeserializedPropertyDescriptor -> proto.getExtension(JsKlibMetadataProtoBuf.propertyContainingFileId)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.metadata
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
|
||||||
|
|
||||||
object JsKlibMetadataSerializerProtocol : SerializerExtensionProtocol(
|
|
||||||
ExtensionRegistryLite.newInstance().apply(JsKlibMetadataProtoBuf::registerAllExtensions),
|
|
||||||
JsKlibMetadataProtoBuf.packageFqName,
|
|
||||||
JsKlibMetadataProtoBuf.constructorAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.classAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.functionAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.propertyAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.propertyGetterAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.propertySetterAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.enumEntryAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.compileTimeValue,
|
|
||||||
JsKlibMetadataProtoBuf.parameterAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.typeAnnotation,
|
|
||||||
JsKlibMetadataProtoBuf.typeParameterAnnotation
|
|
||||||
)
|
|
||||||
@@ -14,6 +14,10 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrarySearchPathResolver
|
||||||
|
import org.jetbrains.kotlin.library.UnresolvedLibrary
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
|
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
@@ -59,7 +63,7 @@ fun buildKLib(
|
|||||||
moduleName: String,
|
moduleName: String,
|
||||||
sources: List<String>,
|
sources: List<String>,
|
||||||
outputPath: String,
|
outputPath: String,
|
||||||
dependencies: List<KotlinLibrary>,
|
allDependencies: KotlinLibraryResolveResult,
|
||||||
commonSources: List<String>
|
commonSources: List<String>
|
||||||
) {
|
) {
|
||||||
generateKLib(
|
generateKLib(
|
||||||
@@ -72,7 +76,7 @@ fun buildKLib(
|
|||||||
file
|
file
|
||||||
},
|
},
|
||||||
configuration = buildConfiguration(environment, moduleName),
|
configuration = buildConfiguration(environment, moduleName),
|
||||||
allDependencies = dependencies,
|
allDependencies = allDependencies,
|
||||||
friendDependencies = emptyList(),
|
friendDependencies = emptyList(),
|
||||||
outputKlibPath = outputPath,
|
outputKlibPath = outputPath,
|
||||||
nopack = true
|
nopack = true
|
||||||
@@ -113,12 +117,18 @@ fun main(args: Array<String>) {
|
|||||||
error("Please set path to .klm file: `-o some/dir/module-name.klm`")
|
error("Please set path to .klm file: `-o some/dir/module-name.klm`")
|
||||||
}
|
}
|
||||||
|
|
||||||
val name = outputPath.takeLastWhile { it != '/' }
|
val dependencyAbsolutePaths = dependencies.map{ File(it).absolutePath }
|
||||||
|
val unresolvedLibraries = dependencies.map { UnresolvedLibrary(it, null) }
|
||||||
|
// Configure the resolver to only understand absolute path libraries.
|
||||||
|
val libraryResolver = KotlinLibrarySearchPathResolver<KotlinLibrary>(
|
||||||
|
repositories = emptyList(),
|
||||||
|
directLibs = dependencyAbsolutePaths,
|
||||||
|
distributionKlib = null,
|
||||||
|
localKotlinDir = null,
|
||||||
|
skipCurrentDir = true
|
||||||
|
// TODO: pass logger attached to message collector here.
|
||||||
|
).libraryResolver()
|
||||||
|
val resolvedLibraries = libraryResolver.resolveWithDependencies(unresolvedLibraries, true, true, true)
|
||||||
|
|
||||||
val dependencyKLibs = dependencies.map {
|
buildKLib(File(outputPath).absolutePath, listOfKtFilesFrom(inputFiles), outputPath, resolvedLibraries, listOfKtFilesFrom(commonSources))
|
||||||
val file = File(it)
|
|
||||||
loadKlib(file.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
buildKLib(name.dropLast(4), listOfKtFilesFrom(inputFiles), outputPath, dependencyKLibs, listOfKtFilesFrom(commonSources))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.konan.file
|
package org.jetbrains.kotlin.konan.file
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
|
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.io.RandomAccessFile
|
import java.io.RandomAccessFile
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.net.URI
|
|
||||||
import java.nio.MappedByteBuffer
|
import java.nio.MappedByteBuffer
|
||||||
import java.nio.channels.FileChannel
|
import java.nio.channels.FileChannel
|
||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.konan.properties
|
package org.jetbrains.kotlin.konan.properties
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
import org.jetbrains.kotlin.konan.util.parseSpaceSeparatedArgs
|
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
typealias Properties = java.util.Properties
|
typealias Properties = java.util.Properties
|
||||||
|
|||||||
+3
-2
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.konan.util
|
package org.jetbrains.kotlin.util
|
||||||
|
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
@@ -20,7 +20,8 @@ fun <T> printMillisec(message: String, body: () -> T): T {
|
|||||||
|
|
||||||
fun profile(message: String, body: () -> Unit) = profileIf(
|
fun profile(message: String, body: () -> Unit) = profileIf(
|
||||||
System.getProperty("konan.profile")?.equals("true") ?: false,
|
System.getProperty("konan.profile")?.equals("true") ?: false,
|
||||||
message, body)
|
message, body
|
||||||
|
)
|
||||||
|
|
||||||
fun profileIf(condition: Boolean, message: String, body: () -> Unit) =
|
fun profileIf(condition: Boolean, message: String, body: () -> Unit) =
|
||||||
if (condition) printMillisec(message, body) else body()
|
if (condition) printMillisec(message, body) else body()
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.kotlin.util
|
||||||
|
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
interface Logger {
|
||||||
|
fun log(message: String)
|
||||||
|
fun error(message: String)
|
||||||
|
fun warning(message: String)
|
||||||
|
fun fatal(message: String): Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WithLogger {
|
||||||
|
val logger: Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
object DummyLogger : Logger {
|
||||||
|
override fun log(message: String) = println(message)
|
||||||
|
override fun error(message: String) = println("e: $message")
|
||||||
|
override fun warning(message: String) = println("w: $message")
|
||||||
|
override fun fatal(message: String): Nothing {
|
||||||
|
println("e: $message")
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
id("jps-compatible")
|
||||||
|
}
|
||||||
|
|
||||||
|
description = "Common klib metadata reader and writer"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile(kotlinStdlib())
|
||||||
|
compile(project(":compiler:frontend"))
|
||||||
|
compile(project(":core:deserialization"))
|
||||||
|
compile(project(":compiler:serialization"))
|
||||||
|
compile(project(":kotlin-util-io"))
|
||||||
|
compile(project(":kotlin-util-klib"))
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
"main" { projectDefault() }
|
||||||
|
"test" { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
publish()
|
||||||
|
|
||||||
|
standardPublicJars()
|
||||||
+42
-54
@@ -14,37 +14,38 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata;
|
package org.jetbrains.kotlin.library.metadata;
|
||||||
|
|
||||||
import "core/metadata/src/metadata.proto";
|
import "core/metadata/src/metadata.proto";
|
||||||
|
|
||||||
option java_outer_classname = "JsKlibMetadataProtoBuf";
|
option java_outer_classname = "KlibMetadataProtoBuf";
|
||||||
option optimize_for = LITE_RUNTIME;
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
|
||||||
message Header {
|
message Header {
|
||||||
|
required string module_name = 1;
|
||||||
/*
|
/*
|
||||||
preRelease
|
0x1 = preRelease
|
||||||
*/
|
*/
|
||||||
optional int32 flags = 1;
|
optional int32 flags = 2;
|
||||||
|
|
||||||
// (patch << 16) + (minor << 8) + major
|
|
||||||
optional int32 js_code_binary_version = 2 [default = 1];
|
|
||||||
|
|
||||||
optional string package_fq_name = 3;
|
|
||||||
|
|
||||||
optional org.jetbrains.kotlin.metadata.StringTable strings = 4;
|
optional org.jetbrains.kotlin.metadata.StringTable strings = 4;
|
||||||
|
|
||||||
optional org.jetbrains.kotlin.metadata.QualifiedNameTable qualified_names = 5;
|
optional org.jetbrains.kotlin.metadata.QualifiedNameTable qualified_names = 5;
|
||||||
|
|
||||||
// Annotations on the whole module
|
// Annotations on the whole module
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation annotation = 6;
|
repeated org.jetbrains.kotlin.metadata.Annotation annotation = 6;
|
||||||
|
repeated string package_fragment_name = 7;
|
||||||
|
repeated string empty_package = 8;
|
||||||
|
|
||||||
|
// TODO: Unused.
|
||||||
|
// TODO: We need to have backend specific extension for versionings.
|
||||||
|
// (patch << 16) + (minor << 8) + major
|
||||||
|
// optional int32 js_code_binary_version = 3 [default = 1];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message File {
|
message File {
|
||||||
// If absent, id is the index of the file in the Files.file list
|
// If absent, id is the index of the file in the Files.file list
|
||||||
optional int32 id = 1;
|
optional int32 id = 1;
|
||||||
|
required string name = 2;
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation annotation = 2;
|
repeated org.jetbrains.kotlin.metadata.Annotation annotation = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Files {
|
message Files {
|
||||||
@@ -55,73 +56,60 @@ message DescriptorUniqId {
|
|||||||
required int64 index = 1;
|
required int64 index = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Package {
|
extend org.jetbrains.kotlin.metadata.Package {
|
||||||
optional int32 package_fq_name = 131;
|
optional int32 package_fq_name = 171;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Class {
|
extend org.jetbrains.kotlin.metadata.Class {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation class_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation class_annotation = 170;
|
||||||
optional int32 class_containing_file_id = 135;
|
optional int32 class_file = 175;
|
||||||
optional DescriptorUniqId class_uniq_id = 136;
|
optional DescriptorUniqId class_uniq_id = 171;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Constructor {
|
extend org.jetbrains.kotlin.metadata.Constructor {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation constructor_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation constructor_annotation = 170;
|
||||||
optional DescriptorUniqId constructor_uniq_id = 131;
|
optional DescriptorUniqId constructor_uniq_id = 172;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Function {
|
extend org.jetbrains.kotlin.metadata.Function {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation function_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation function_annotation = 170;
|
||||||
optional int32 function_containing_file_id = 135;
|
optional int32 function_file = 172;
|
||||||
optional DescriptorUniqId function_uniq_id = 136;
|
optional DescriptorUniqId function_uniq_id = 173;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Property {
|
extend org.jetbrains.kotlin.metadata.Property {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation property_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation property_annotation = 170;
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation property_getter_annotation = 132;
|
repeated org.jetbrains.kotlin.metadata.Annotation property_getter_annotation = 177;
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation property_setter_annotation = 133;
|
repeated org.jetbrains.kotlin.metadata.Annotation property_setter_annotation = 178;
|
||||||
optional org.jetbrains.kotlin.metadata.Annotation.Argument.Value compile_time_value = 131;
|
optional org.jetbrains.kotlin.metadata.Annotation.Argument.Value compile_time_value = 173;
|
||||||
optional int32 property_containing_file_id = 135;
|
optional int32 property_file = 176;
|
||||||
optional DescriptorUniqId property_uniq_id = 136;
|
optional DescriptorUniqId property_uniq_id = 179;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.EnumEntry {
|
extend org.jetbrains.kotlin.metadata.EnumEntry {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation enum_entry_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation enum_entry_annotation = 170;
|
||||||
optional DescriptorUniqId enum_entry_uniq_id = 131;
|
optional int32 enum_entry_ordinal = 171;
|
||||||
}
|
optional DescriptorUniqId enum_entry_uniq_id = 172;
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.ValueParameter {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation parameter_annotation = 130;
|
|
||||||
optional DescriptorUniqId value_param_uniq_id = 131;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.Type {
|
extend org.jetbrains.kotlin.metadata.Type {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation type_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation type_annotation = 170;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.TypeParameter {
|
extend org.jetbrains.kotlin.metadata.TypeParameter {
|
||||||
repeated org.jetbrains.kotlin.metadata.Annotation type_parameter_annotation = 130;
|
repeated org.jetbrains.kotlin.metadata.Annotation type_parameter_annotation = 170;
|
||||||
optional DescriptorUniqId type_param_uniq_id = 131;
|
optional DescriptorUniqId type_param_uniq_id = 171;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.PackageFragment {
|
extend org.jetbrains.kotlin.metadata.PackageFragment {
|
||||||
optional Files package_fragment_files = 130;
|
optional Files package_fragment_files = 170;
|
||||||
|
optional bool is_empty = 172;
|
||||||
|
optional string fq_name = 173;
|
||||||
|
// id in StringTable
|
||||||
|
repeated int32 class_name = 174 [packed = true];
|
||||||
}
|
}
|
||||||
|
|
||||||
extend org.jetbrains.kotlin.metadata.TypeAlias {
|
extend org.jetbrains.kotlin.metadata.TypeAlias {
|
||||||
// TODO repeated org.jetbrains.kotlin.metadata.Annotation type_alias_annotation = 130;
|
// TODO repeated org.jetbrains.kotlin.metadata.Annotation type_alias_annotation = 130;
|
||||||
optional DescriptorUniqId type_alias_uniq_id = 131;
|
optional DescriptorUniqId type_alias_uniq_id = 131;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Classes {
|
|
||||||
// id in StringTable
|
|
||||||
repeated int32 class_name = 1 [packed = true];
|
|
||||||
}
|
|
||||||
|
|
||||||
message Library {
|
|
||||||
repeated org.jetbrains.kotlin.metadata.PackageFragment package_fragment = 2;
|
|
||||||
|
|
||||||
repeated string imported_module = 3;
|
|
||||||
}
|
|
||||||
+8
-8
@@ -3,33 +3,33 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.serialization.konan
|
package org.jetbrains.kotlin.library.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||||
|
|
||||||
class KonanClassDataFinder(
|
class KlibMetadataClassDataFinder(
|
||||||
private val fragment: KonanProtoBuf.LinkDataPackageFragment,
|
private val fragment: org.jetbrains.kotlin.metadata.ProtoBuf.PackageFragment,
|
||||||
private val nameResolver: NameResolver
|
private val nameResolver: NameResolver
|
||||||
) : ClassDataFinder {
|
) : ClassDataFinder {
|
||||||
|
val nameList = fragment.getExtension(KlibMetadataProtoBuf.className).orEmpty()
|
||||||
|
|
||||||
override fun findClassData(classId: ClassId): ClassData? {
|
override fun findClassData(classId: ClassId): ClassData? {
|
||||||
val proto = fragment.classes
|
|
||||||
val nameList = proto.classNameList
|
|
||||||
|
|
||||||
val index = nameList.indexOfFirst { nameResolver.getClassId(it) == classId }
|
val index = nameList.indexOfFirst { nameResolver.getClassId(it) == classId }
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val foundClass = proto.getClasses(index) ?: error("Could not find data for serialized class $classId")
|
val foundClass = fragment.getClass_(index) ?: error("Could not find data for serialized class $classId")
|
||||||
|
|
||||||
/* TODO: binary version supposed to be read from protobuf. */
|
/* TODO: binary version supposed to be read from protobuf. */
|
||||||
return ClassData(nameResolver, foundClass, KonanMetadataVersion.INSTANCE, SourceElement.NO_SOURCE)
|
return ClassData(nameResolver, foundClass, KlibMetadataVersion.INSTANCE, SourceElement.NO_SOURCE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 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.library.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
|
||||||
|
fun parsePackageFragment(packageMetadata: ByteArray): ProtoBuf.PackageFragment =
|
||||||
|
ProtoBuf.PackageFragment.parseFrom(packageMetadata, KlibMetadataSerializerProtocol.extensionRegistry)
|
||||||
|
|
||||||
|
fun parseModuleHeader(libraryMetadata: ByteArray): KlibMetadataProtoBuf.Header =
|
||||||
|
KlibMetadataProtoBuf.Header.parseFrom(libraryMetadata, KlibMetadataSerializerProtocol.extensionRegistry)
|
||||||
|
|
||||||
|
interface PackageAccessHandler {
|
||||||
|
fun loadModuleHeader(
|
||||||
|
library: KotlinLibrary
|
||||||
|
): KlibMetadataProtoBuf.Header = parseModuleHeader(library.moduleHeaderData)
|
||||||
|
|
||||||
|
fun loadPackageFragment(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
packageFqName: String,
|
||||||
|
partName: String
|
||||||
|
): ProtoBuf.PackageFragment = parsePackageFragment(library.packageMetadata(packageFqName, partName))
|
||||||
|
}
|
||||||
|
|
||||||
|
object SimplePackageAccessHandler : PackageAccessHandler
|
||||||
|
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
interface KlibMetadataDeserializedPackageFragmentsFactory {
|
||||||
|
fun createDeserializedPackageFragments(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
packageFragmentNames: List<String>,
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
packageAccessedHandler: PackageAccessHandler?,
|
||||||
|
storageManager: StorageManager
|
||||||
|
): List<KlibMetadataPackageFragment>
|
||||||
|
|
||||||
|
fun createSyntheticPackageFragments(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
deserializedPackageFragments: List<KlibMetadataPackageFragment>,
|
||||||
|
moduleDescriptor: ModuleDescriptor
|
||||||
|
): List<PackageFragmentDescriptor>
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 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.konan.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataDeserializedPackageFragmentsFactory
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataModuleDescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.KlibMetadataDeserializedPackageFragmentsFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleDescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.impl.KlibModuleDescriptorFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.KlibResolvedModuleDescriptorsFactory
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default Kotlin/Native factories.
|
||||||
|
*/
|
||||||
|
open class KlibMetadataFactories(
|
||||||
|
createBuiltIns:(StorageManager) -> KotlinBuiltIns,
|
||||||
|
val flexibleTypeDeserializer: FlexibleTypeDeserializer
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default [KlibModuleDescriptorFactory] factory instance.
|
||||||
|
*/
|
||||||
|
val DefaultDescriptorFactory: KlibModuleDescriptorFactory = KlibModuleDescriptorFactoryImpl(createBuiltIns)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default [KlibMetadataDeserializedPackageFragmentsFactory] factory instance.
|
||||||
|
*/
|
||||||
|
val DefaultPackageFragmentsFactory: KlibMetadataDeserializedPackageFragmentsFactory =
|
||||||
|
KlibMetadataDeserializedPackageFragmentsFactoryImpl()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default [KlibMetadataModuleDescriptorFactory] factory instance.
|
||||||
|
*/
|
||||||
|
val DefaultDeserializedDescriptorFactory: KlibMetadataModuleDescriptorFactory =
|
||||||
|
createDefaultKonanDeserializedModuleDescriptorFactory(
|
||||||
|
DefaultDescriptorFactory, DefaultPackageFragmentsFactory
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default [KlibResolvedModuleDescriptorsFactory] factory instance.
|
||||||
|
*/
|
||||||
|
val DefaultResolvedDescriptorsFactory: KlibResolvedModuleDescriptorsFactory =
|
||||||
|
createDefaultKonanResolvedModuleDescriptorsFactory(DefaultDeserializedDescriptorFactory)
|
||||||
|
|
||||||
|
fun createDefaultKonanDeserializedModuleDescriptorFactory(
|
||||||
|
descriptorFactory: KlibModuleDescriptorFactory,
|
||||||
|
packageFragmentsFactory: KlibMetadataDeserializedPackageFragmentsFactory
|
||||||
|
): KlibMetadataModuleDescriptorFactory =
|
||||||
|
KlibMetadataModuleDescriptorFactoryImpl(descriptorFactory, packageFragmentsFactory, flexibleTypeDeserializer)
|
||||||
|
|
||||||
|
fun createDefaultKonanResolvedModuleDescriptorsFactory(
|
||||||
|
moduleDescriptorFactory: KlibMetadataModuleDescriptorFactory
|
||||||
|
): KlibResolvedModuleDescriptorsFactory = KlibResolvedModuleDescriptorsFactoryImpl(moduleDescriptorFactory)
|
||||||
|
}
|
||||||
+4
-4
@@ -3,19 +3,19 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.serialization.konan
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
|
|
||||||
class KonanMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
|
class KlibMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
|
||||||
|
|
||||||
override fun isCompatible(): Boolean = this.major == 1 && this.minor == 0
|
override fun isCompatible(): Boolean = this.major == 1 && this.minor == 0
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val INSTANCE = KonanMetadataVersion(1, 0, 0)
|
val INSTANCE = KlibMetadataVersion(1, 0, 0)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val INVALID_VERSION = KonanMetadataVersion()
|
val INVALID_VERSION = KlibMetadataVersion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleDescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
interface KlibMetadataModuleDescriptorFactory {
|
||||||
|
|
||||||
|
val descriptorFactory: KlibModuleDescriptorFactory
|
||||||
|
val packageFragmentsFactory: KlibMetadataDeserializedPackageFragmentsFactory
|
||||||
|
val flexibleTypeDeserializer: FlexibleTypeDeserializer
|
||||||
|
|
||||||
|
fun createDescriptor(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns,
|
||||||
|
packageAccessHandler: PackageAccessHandler?
|
||||||
|
) = createDescriptorOptionalBuiltIns(
|
||||||
|
library,
|
||||||
|
languageVersionSettings,
|
||||||
|
storageManager,
|
||||||
|
builtIns,
|
||||||
|
packageAccessHandler
|
||||||
|
)
|
||||||
|
|
||||||
|
fun createDescriptorAndNewBuiltIns(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
packageAccessHandler: PackageAccessHandler?
|
||||||
|
) = createDescriptorOptionalBuiltIns(library, languageVersionSettings, storageManager, null, packageAccessHandler)
|
||||||
|
|
||||||
|
fun createDescriptorOptionalBuiltIns(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
packageAccessHandler: PackageAccessHandler?
|
||||||
|
): ModuleDescriptorImpl
|
||||||
|
|
||||||
|
fun createPackageFragmentProvider(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
packageAccessHandler: PackageAccessHandler?,
|
||||||
|
packageFragmentNames: List<String>,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
configuration: DeserializationConfiguration,
|
||||||
|
compositePackageFragmentAddend: PackageFragmentProvider?
|
||||||
|
): PackageFragmentProvider
|
||||||
|
}
|
||||||
+22
-17
@@ -3,13 +3,13 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.serialization.konan
|
package org.jetbrains.kotlin.library.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||||
@@ -19,13 +19,13 @@ import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
class KonanPackageFragment(
|
class KlibMetadataPackageFragment(
|
||||||
fqName: FqName,
|
fqName: FqName,
|
||||||
private val library: KonanLibrary,
|
private val library: KotlinLibrary,
|
||||||
private val packageAccessedHandler: PackageAccessedHandler?,
|
private val packageAccessHandler: PackageAccessHandler?,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
partName: String
|
private val partName: String
|
||||||
) : DeserializedPackageFragment(fqName, storageManager, module) {
|
) : DeserializedPackageFragment(fqName, storageManager, module) {
|
||||||
|
|
||||||
lateinit var components: DeserializationComponents
|
lateinit var components: DeserializationComponents
|
||||||
@@ -36,17 +36,20 @@ class KonanPackageFragment(
|
|||||||
|
|
||||||
// The proto field is lazy so that we can load only needed
|
// The proto field is lazy so that we can load only needed
|
||||||
// packages from the library.
|
// packages from the library.
|
||||||
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString(), partName) }
|
private val protoForNames: ProtoBuf.PackageFragment by lazy {
|
||||||
|
(packageAccessHandler ?: SimplePackageAccessHandler).loadPackageFragment(library, fqName.asString(), partName)
|
||||||
|
}
|
||||||
|
|
||||||
val proto: KonanProtoBuf.LinkDataPackageFragment
|
// TODO: Do we really need both 'protoForNames' and 'proto' today?
|
||||||
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName) }
|
val proto: ProtoBuf.PackageFragment
|
||||||
|
get() = protoForNames
|
||||||
|
|
||||||
private val nameResolver by lazy {
|
private val nameResolver by lazy {
|
||||||
NameResolverImpl(protoForNames.stringTable, protoForNames.nameTable)
|
NameResolverImpl(protoForNames.strings, protoForNames.qualifiedNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val classDataFinder by lazy {
|
override val classDataFinder by lazy {
|
||||||
KonanClassDataFinder(proto, nameResolver)
|
KlibMetadataClassDataFinder(proto, nameResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _memberScope by lazy {
|
private val _memberScope by lazy {
|
||||||
@@ -55,10 +58,12 @@ class KonanPackageFragment(
|
|||||||
this,
|
this,
|
||||||
proto.getPackage(),
|
proto.getPackage(),
|
||||||
nameResolver,
|
nameResolver,
|
||||||
KonanMetadataVersion.INSTANCE,
|
KlibMetadataVersion.INSTANCE,
|
||||||
/* containerSource = */ null,
|
/* containerSource = */ null,
|
||||||
components
|
components
|
||||||
) { loadClassNames() }
|
) {
|
||||||
|
loadClassNames()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMemberScope(): DeserializedPackageMemberScope = _memberScope
|
override fun getMemberScope(): DeserializedPackageMemberScope = _memberScope
|
||||||
@@ -74,7 +79,7 @@ class KonanPackageFragment(
|
|||||||
|
|
||||||
private fun loadClassNames(): Collection<Name> {
|
private fun loadClassNames(): Collection<Name> {
|
||||||
|
|
||||||
val classNameList = protoForNames.classes.classNameList
|
val classNameList = protoForNames.getExtension(KlibMetadataProtoBuf.className).orEmpty()
|
||||||
|
|
||||||
val names = classNameList.mapNotNull {
|
val names = classNameList.mapNotNull {
|
||||||
val classId = nameResolver.getClassId(it)
|
val classId = nameResolver.getClassId(it)
|
||||||
@@ -84,4 +89,4 @@ class KonanPackageFragment(
|
|||||||
|
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1100
-1763
File diff suppressed because it is too large
Load Diff
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.library.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
||||||
|
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
||||||
|
|
||||||
|
object KlibMetadataSerializerProtocol : SerializerExtensionProtocol(
|
||||||
|
ExtensionRegistryLite.newInstance().apply(KlibMetadataProtoBuf::registerAllExtensions),
|
||||||
|
KlibMetadataProtoBuf.packageFqName,
|
||||||
|
KlibMetadataProtoBuf.constructorAnnotation,
|
||||||
|
KlibMetadataProtoBuf.classAnnotation,
|
||||||
|
KlibMetadataProtoBuf.functionAnnotation,
|
||||||
|
KlibMetadataProtoBuf.propertyAnnotation,
|
||||||
|
KlibMetadataProtoBuf.propertyGetterAnnotation,
|
||||||
|
KlibMetadataProtoBuf.propertySetterAnnotation,
|
||||||
|
KlibMetadataProtoBuf.enumEntryAnnotation,
|
||||||
|
KlibMetadataProtoBuf.compileTimeValue,
|
||||||
|
KlibMetadataProtoBuf.parameterAnnotation,
|
||||||
|
KlibMetadataProtoBuf.typeAnnotation,
|
||||||
|
KlibMetadataProtoBuf.typeParameterAnnotation
|
||||||
|
)
|
||||||
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.ir.backend.js.lower.serialization.metadata
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||||
import org.jetbrains.kotlin.serialization.StringTableImpl
|
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||||
|
|
||||||
class JsKlibMetadataStringTable : StringTableImpl() {
|
class KlibMetadataStringTable : StringTableImpl() {
|
||||||
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
|
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
|
||||||
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
|
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
|
||||||
val superClassifiers = descriptor.getAllSuperClassifiers()
|
val superClassifiers = descriptor.getAllSuperClassifiers()
|
||||||
+3
-3
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
interface KonanModuleDescriptorFactory {
|
interface KlibModuleDescriptorFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base method for creation of any Kotlin/Native [ModuleDescriptor].
|
* Base method for creation of any Kotlin/Native [ModuleDescriptor].
|
||||||
@@ -20,7 +20,7 @@ interface KonanModuleDescriptorFactory {
|
|||||||
name: Name,
|
name: Name,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
builtIns: KotlinBuiltIns,
|
builtIns: KotlinBuiltIns,
|
||||||
origin: KonanModuleOrigin,
|
origin: KlibModuleOrigin,
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
||||||
): ModuleDescriptorImpl
|
): ModuleDescriptorImpl
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ interface KonanModuleDescriptorFactory {
|
|||||||
fun createDescriptorAndNewBuiltIns(
|
fun createDescriptorAndNewBuiltIns(
|
||||||
name: Name,
|
name: Name,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
origin: KonanModuleOrigin,
|
origin: KlibModuleOrigin,
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
||||||
): ModuleDescriptorImpl
|
): ModuleDescriptorImpl
|
||||||
}
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 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.descriptors.konan
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.isInterop
|
||||||
|
|
||||||
|
sealed class KlibModuleOrigin {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val CAPABILITY = ModuleDescriptor.Capability<KlibModuleOrigin>("KlibModuleOrigin")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class CompiledKlibModuleOrigin: KlibModuleOrigin()
|
||||||
|
|
||||||
|
class DeserializedKlibModuleOrigin(val library: KotlinLibrary) : CompiledKlibModuleOrigin()
|
||||||
|
|
||||||
|
object CurrentKlibModuleOrigin: CompiledKlibModuleOrigin()
|
||||||
|
|
||||||
|
object SyntheticModulesOrigin : KlibModuleOrigin()
|
||||||
|
|
||||||
|
internal fun KlibModuleOrigin.isInteropLibrary(): Boolean = when (this) {
|
||||||
|
is DeserializedKlibModuleOrigin -> this.library.isInterop
|
||||||
|
CurrentKlibModuleOrigin, SyntheticModulesOrigin -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val ModuleDescriptor.klibModuleOrigin get() = this.getCapability(KlibModuleOrigin.CAPABILITY)!!
|
||||||
|
|
||||||
|
val ModuleDescriptor.kotlinLibrary get() =
|
||||||
|
(this.klibModuleOrigin as DeserializedKlibModuleOrigin)
|
||||||
|
.library
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
package org.jetbrains.kotlin.serialization.konan
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataModuleDescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
interface KlibResolvedModuleDescriptorsFactory {
|
||||||
|
|
||||||
|
val moduleDescriptorFactory: KlibMetadataModuleDescriptorFactory
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the [resolvedLibraries] creates the list of [ModuleDescriptorImpl]s with properly installed
|
||||||
|
* inter-dependencies. The result of this method is returned in a form of [KlibResolvedModuleDescriptors] instance.
|
||||||
|
*
|
||||||
|
* Please use this method with care: Unless this method accepts `null` for [builtIns], it is not recommended to
|
||||||
|
* invoke it this way. If you are compiling a source module, please supply the non-null [builtIns] from the
|
||||||
|
* source module, so that all modules created in your compilation session will share the same built-ins instance.
|
||||||
|
*
|
||||||
|
* Otherwise (if `null` was supplied), a new instance of [KotlinBuiltIns] will be created. The created built-ins
|
||||||
|
* instance will be shared by all modules created in this method. But this instance will have no connection
|
||||||
|
* with probably existing built-ins instance of your source module(s).
|
||||||
|
*/
|
||||||
|
fun createResolved(
|
||||||
|
resolvedLibraries: KotlinLibraryResolveResult,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
customAction: ((KotlinLibrary, ModuleDescriptorImpl) -> Unit)? = null
|
||||||
|
): KotlinResolvedModuleDescriptors
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinResolvedModuleDescriptors(
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of modules each representing an individual Kotlin/Native library. All modules
|
||||||
|
* in this list have properly installed dependencies, i.e. module has all necessary dependencies
|
||||||
|
* on other modules plus a dependency on the [forwardDeclarationsModule].
|
||||||
|
*/
|
||||||
|
val resolvedDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a module which "contains" forward declarations.
|
||||||
|
* Note: this module should be unique per compilation and should always be the last dependency of any module.
|
||||||
|
*/
|
||||||
|
val forwardDeclarationsModule: ModuleDescriptorImpl
|
||||||
|
)
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.SourceFile
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
|
||||||
|
private class DeserializedSourceFile(
|
||||||
|
val name_: String, val index: Int, val library: KotlinLibrary) : SourceFile {
|
||||||
|
override fun getName(): String? = name_
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return other is DeserializedSourceFile && library == other.library && index == other.index
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return library.hashCode() xor index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SourceFileMap {
|
||||||
|
private val sourceToIndex = mutableMapOf<SourceFile, Int>()
|
||||||
|
private val indexToSource = mutableMapOf<Int, SourceFile>()
|
||||||
|
|
||||||
|
fun assign(file: SourceFile): Int {
|
||||||
|
return sourceToIndex.getOrPut(file) {
|
||||||
|
sourceToIndex.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun provide(fileName: String, index: Int, library: KotlinLibrary) {
|
||||||
|
assert(indexToSource[index] == null)
|
||||||
|
indexToSource[index] =
|
||||||
|
DeserializedSourceFile(fileName, index, library)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sourceFile(index: Int): SourceFile =
|
||||||
|
indexToSource[index] ?: throw Error("Unknown file for $index")
|
||||||
|
|
||||||
|
fun filesAndClear() =
|
||||||
|
sourceToIndex.keys.sortedBy {
|
||||||
|
sourceToIndex[it]
|
||||||
|
}.also{
|
||||||
|
clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
sourceToIndex.clear()
|
||||||
|
indexToSource.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
-110
@@ -1,32 +1,20 @@
|
|||||||
/*
|
package org.jetbrains.kotlin.backend.common.serialization.metadata.impl
|
||||||
* Copyright 2010-2018 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.serialization.konan.impl
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataDeserializedPackageFragmentsFactory
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.contracts.ContractDeserializerImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.konan.library.*
|
import org.jetbrains.kotlin.library.*
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedPackageFragmentsFactory
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
|
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.storage.getValue
|
import org.jetbrains.kotlin.storage.getValue
|
||||||
@@ -34,33 +22,34 @@ import org.jetbrains.kotlin.utils.Printer
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
|
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
|
||||||
internal object KonanDeserializedPackageFragmentsFactoryImpl : KonanDeserializedPackageFragmentsFactory {
|
open class KlibMetadataDeserializedPackageFragmentsFactoryImpl: KlibMetadataDeserializedPackageFragmentsFactory {
|
||||||
|
|
||||||
override fun createDeserializedPackageFragments(
|
override fun createDeserializedPackageFragments(
|
||||||
library: KonanLibrary,
|
library: KotlinLibrary,
|
||||||
packageFragmentNames: List<String>,
|
packageFragmentNames: List<String>,
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
packageAccessedHandler: PackageAccessHandler?,
|
||||||
storageManager: StorageManager
|
storageManager: StorageManager
|
||||||
) = packageFragmentNames.flatMap {
|
) = packageFragmentNames.flatMap {
|
||||||
val fqName = FqName(it)
|
val fqName = FqName(it)
|
||||||
val parts = library.packageMetadataParts(it)
|
val parts = library.packageMetadataParts(fqName.asString())
|
||||||
parts.map { partName ->
|
parts.map { partName ->
|
||||||
KonanPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partName)
|
KlibMetadataPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun createSyntheticPackageFragments(
|
override fun createSyntheticPackageFragments(
|
||||||
library: KonanLibrary,
|
library: KotlinLibrary,
|
||||||
deserializedPackageFragments: List<KonanPackageFragment>,
|
deserializedPackageFragments: List<KlibMetadataPackageFragment>,
|
||||||
moduleDescriptor: ModuleDescriptor
|
moduleDescriptor: ModuleDescriptor
|
||||||
): List<PackageFragmentDescriptor> {
|
): List<PackageFragmentDescriptor> {
|
||||||
|
|
||||||
if (!library.isInterop) return emptyList()
|
if (!library.isInterop) return emptyList()
|
||||||
|
|
||||||
val mainPackageFqName = library.packageFqName
|
val mainPackageFqName = library.packageFqName?. let{ FqName(it) }
|
||||||
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
|
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
|
||||||
val exportForwardDeclarations = library.exportForwardDeclarations
|
val exportForwardDeclarations = library.exportForwardDeclarations.map{ FqName(it) }
|
||||||
|
|
||||||
val aliasedPackageFragments = deserializedPackageFragments.filter { it.fqName == mainPackageFqName }
|
val aliasedPackageFragments = deserializedPackageFragments.filter { it.fqName == mainPackageFqName }
|
||||||
|
|
||||||
@@ -78,87 +67,6 @@ internal object KonanDeserializedPackageFragmentsFactoryImpl : KonanDeserialized
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPackageFragmentProvider(
|
|
||||||
library: KonanLibrary,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
packageFragmentNames: List<String>,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
moduleDescriptor: ModuleDescriptor,
|
|
||||||
configuration: DeserializationConfiguration
|
|
||||||
): PackageFragmentProvider {
|
|
||||||
|
|
||||||
val deserializedPackageFragments = createDeserializedPackageFragments(
|
|
||||||
library, packageFragmentNames, moduleDescriptor, packageAccessedHandler, storageManager
|
|
||||||
)
|
|
||||||
|
|
||||||
val syntheticPackageFragments = createSyntheticPackageFragments(
|
|
||||||
library, deserializedPackageFragments, moduleDescriptor
|
|
||||||
)
|
|
||||||
|
|
||||||
val packageFragmentProvider = PackageFragmentProviderImpl(deserializedPackageFragments + syntheticPackageFragments)
|
|
||||||
|
|
||||||
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
|
|
||||||
|
|
||||||
val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(
|
|
||||||
moduleDescriptor,
|
|
||||||
notFoundClasses,
|
|
||||||
KonanSerializerProtocol
|
|
||||||
)
|
|
||||||
|
|
||||||
val components = DeserializationComponents(
|
|
||||||
storageManager,
|
|
||||||
moduleDescriptor,
|
|
||||||
configuration,
|
|
||||||
DeserializedClassDataFinder(packageFragmentProvider),
|
|
||||||
annotationAndConstantLoader,
|
|
||||||
packageFragmentProvider,
|
|
||||||
LocalClassifierTypeSettings.Default,
|
|
||||||
ErrorReporter.DO_NOTHING,
|
|
||||||
LookupTracker.DO_NOTHING,
|
|
||||||
NullFlexibleTypeDeserializer,
|
|
||||||
emptyList(),
|
|
||||||
notFoundClasses,
|
|
||||||
ContractDeserializerImpl(configuration, storageManager),
|
|
||||||
extensionRegistryLite = KonanSerializerProtocol.extensionRegistry
|
|
||||||
)
|
|
||||||
|
|
||||||
for (packageFragment in deserializedPackageFragments) {
|
|
||||||
packageFragment.initialize(components)
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (library.uniqueName == KONAN_STDLIB_NAME)
|
|
||||||
CompositePackageFragmentProvider(
|
|
||||||
listOf(
|
|
||||||
packageFragmentProvider,
|
|
||||||
functionInterfacePackageFragmentProvider(storageManager, moduleDescriptor)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else
|
|
||||||
packageFragmentProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createForwardDeclarationHackPackagePartProvider(
|
|
||||||
storageManager: StorageManager,
|
|
||||||
module: ModuleDescriptorImpl
|
|
||||||
): PackageFragmentProviderImpl {
|
|
||||||
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
|
|
||||||
ForwardDeclarationsPackageFragmentDescriptor(
|
|
||||||
storageManager,
|
|
||||||
module,
|
|
||||||
fqName,
|
|
||||||
Name.identifier(supertypeName),
|
|
||||||
classKind
|
|
||||||
)
|
|
||||||
|
|
||||||
val packageFragmentProvider = PackageFragmentProviderImpl(
|
|
||||||
listOf(
|
|
||||||
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
|
|
||||||
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
|
|
||||||
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return packageFragmentProvider
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,7 +109,7 @@ class ExportedForwardDeclarationsPackageFragmentDescriptor(
|
|||||||
* The package fragment that redirects all requests for classifier lookup to its targets.
|
* The package fragment that redirects all requests for classifier lookup to its targets.
|
||||||
*/
|
*/
|
||||||
class ClassifierAliasingPackageFragmentDescriptor(
|
class ClassifierAliasingPackageFragmentDescriptor(
|
||||||
targets: List<KonanPackageFragment>,
|
targets: List<KlibMetadataPackageFragment>,
|
||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
fqName: FqName
|
fqName: FqName
|
||||||
) : PackageFragmentDescriptorImpl(module, fqName) {
|
) : PackageFragmentDescriptorImpl(module, fqName) {
|
||||||
@@ -278,4 +186,5 @@ private class ForwardDeclarationsPackageFragmentDescriptor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getMemberScope(): MemberScope = memberScope
|
override fun getMemberScope(): MemberScope = memberScope
|
||||||
}
|
}
|
||||||
|
|
||||||
+155
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 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.serialization.konan.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.*
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.contracts.ContractDeserializerImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleDescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||||
|
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
val ModuleDescriptorImpl.isStdlibModule
|
||||||
|
get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)
|
||||||
|
?.library?.unresolvedDependencies?.isEmpty() ?: false
|
||||||
|
|
||||||
|
class KlibMetadataModuleDescriptorFactoryImpl(
|
||||||
|
override val descriptorFactory: KlibModuleDescriptorFactory,
|
||||||
|
override val packageFragmentsFactory: KlibMetadataDeserializedPackageFragmentsFactory,
|
||||||
|
override val flexibleTypeDeserializer: FlexibleTypeDeserializer
|
||||||
|
): KlibMetadataModuleDescriptorFactory {
|
||||||
|
|
||||||
|
override fun createDescriptorOptionalBuiltIns(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
packageAccessHandler: PackageAccessHandler?
|
||||||
|
): ModuleDescriptorImpl {
|
||||||
|
|
||||||
|
val libraryProto = parseModuleHeader(library.moduleHeaderData)
|
||||||
|
|
||||||
|
val moduleName = Name.special(libraryProto.moduleName)
|
||||||
|
val moduleOrigin = DeserializedKlibModuleOrigin(library)
|
||||||
|
|
||||||
|
val moduleDescriptor = if (builtIns != null )
|
||||||
|
descriptorFactory.createDescriptor(moduleName, storageManager, builtIns, moduleOrigin)
|
||||||
|
else
|
||||||
|
descriptorFactory.createDescriptorAndNewBuiltIns(moduleName, storageManager, moduleOrigin)
|
||||||
|
|
||||||
|
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
|
||||||
|
|
||||||
|
val compositePackageFragmentAddend =
|
||||||
|
if (moduleDescriptor.isStdlibModule) {
|
||||||
|
functionInterfacePackageFragmentProvider(storageManager, moduleDescriptor)
|
||||||
|
} else null
|
||||||
|
|
||||||
|
val provider = createPackageFragmentProvider(
|
||||||
|
library,
|
||||||
|
packageAccessHandler,
|
||||||
|
libraryProto.packageFragmentNameList,
|
||||||
|
storageManager,
|
||||||
|
moduleDescriptor,
|
||||||
|
deserializationConfiguration,
|
||||||
|
compositePackageFragmentAddend
|
||||||
|
)
|
||||||
|
|
||||||
|
moduleDescriptor.initialize(provider)
|
||||||
|
|
||||||
|
return moduleDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createPackageFragmentProvider(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
packageAccessHandler: PackageAccessHandler?,
|
||||||
|
packageFragmentNames: List<String>,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
configuration: DeserializationConfiguration,
|
||||||
|
compositePackageFragmentAddend: PackageFragmentProvider?
|
||||||
|
): PackageFragmentProvider {
|
||||||
|
|
||||||
|
val deserializedPackageFragments = packageFragmentsFactory.createDeserializedPackageFragments(
|
||||||
|
library, packageFragmentNames, moduleDescriptor, packageAccessHandler, storageManager)
|
||||||
|
|
||||||
|
// TODO: this is native specific. Move to a child class.
|
||||||
|
val syntheticPackageFragments = packageFragmentsFactory.createSyntheticPackageFragments(
|
||||||
|
library, deserializedPackageFragments, moduleDescriptor)
|
||||||
|
|
||||||
|
val provider = PackageFragmentProviderImpl(deserializedPackageFragments + syntheticPackageFragments)
|
||||||
|
|
||||||
|
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
|
||||||
|
|
||||||
|
val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(
|
||||||
|
moduleDescriptor,
|
||||||
|
notFoundClasses,
|
||||||
|
KlibMetadataSerializerProtocol
|
||||||
|
)
|
||||||
|
|
||||||
|
val components = DeserializationComponents(
|
||||||
|
storageManager,
|
||||||
|
moduleDescriptor,
|
||||||
|
configuration,
|
||||||
|
DeserializedClassDataFinder(provider),
|
||||||
|
annotationAndConstantLoader,
|
||||||
|
provider,
|
||||||
|
LocalClassifierTypeSettings.Default,
|
||||||
|
ErrorReporter.DO_NOTHING,
|
||||||
|
LookupTracker.DO_NOTHING,
|
||||||
|
flexibleTypeDeserializer,
|
||||||
|
emptyList(),
|
||||||
|
notFoundClasses,
|
||||||
|
ContractDeserializerImpl(configuration, storageManager),
|
||||||
|
extensionRegistryLite = KlibMetadataSerializerProtocol.extensionRegistry)
|
||||||
|
|
||||||
|
for (packageFragment in deserializedPackageFragments) {
|
||||||
|
packageFragment.initialize(components)
|
||||||
|
}
|
||||||
|
|
||||||
|
return compositePackageFragmentAddend ?.let {
|
||||||
|
CompositePackageFragmentProvider(listOf(it, provider))
|
||||||
|
} ?: provider
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createForwardDeclarationHackPackagePartProvider(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
module: ModuleDescriptorImpl
|
||||||
|
): PackageFragmentProviderImpl {
|
||||||
|
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
|
||||||
|
ForwardDeclarationsPackageFragmentDescriptor(
|
||||||
|
storageManager,
|
||||||
|
module,
|
||||||
|
fqName,
|
||||||
|
Name.identifier(supertypeName),
|
||||||
|
classKind
|
||||||
|
)
|
||||||
|
|
||||||
|
val packageFragmentProvider = PackageFragmentProviderImpl(
|
||||||
|
listOf(
|
||||||
|
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
|
||||||
|
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
|
||||||
|
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return packageFragmentProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-8
@@ -6,30 +6,28 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.konan.impl
|
package org.jetbrains.kotlin.descriptors.konan.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
import org.jetbrains.kotlin.descriptors.konan.*
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleOrigin
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isInteropLibrary
|
import org.jetbrains.kotlin.descriptors.konan.isInteropLibrary
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
|
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal object KonanModuleDescriptorFactoryImpl : KonanModuleDescriptorFactory {
|
internal class KlibModuleDescriptorFactoryImpl(val createBuiltIns: (StorageManager) -> KotlinBuiltIns) : KlibModuleDescriptorFactory {
|
||||||
|
|
||||||
override fun createDescriptor(
|
override fun createDescriptor(
|
||||||
name: Name,
|
name: Name,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
builtIns: KotlinBuiltIns,
|
builtIns: KotlinBuiltIns,
|
||||||
origin: KonanModuleOrigin,
|
origin: KlibModuleOrigin,
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||||
) = ModuleDescriptorImpl(
|
) = ModuleDescriptorImpl(
|
||||||
name,
|
name,
|
||||||
storageManager,
|
storageManager,
|
||||||
builtIns,
|
builtIns,
|
||||||
capabilities = customCapabilities + mapOf(
|
capabilities = customCapabilities + mapOf(
|
||||||
KonanModuleOrigin.CAPABILITY to origin,
|
KlibModuleOrigin.CAPABILITY to origin,
|
||||||
ImplicitIntegerCoercion.MODULE_CAPABILITY to origin.isInteropLibrary()
|
ImplicitIntegerCoercion.MODULE_CAPABILITY to origin.isInteropLibrary()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -37,11 +35,11 @@ internal object KonanModuleDescriptorFactoryImpl : KonanModuleDescriptorFactory
|
|||||||
override fun createDescriptorAndNewBuiltIns(
|
override fun createDescriptorAndNewBuiltIns(
|
||||||
name: Name,
|
name: Name,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
origin: KonanModuleOrigin,
|
origin: KlibModuleOrigin,
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||||
): ModuleDescriptorImpl {
|
): ModuleDescriptorImpl {
|
||||||
|
|
||||||
val builtIns = KonanBuiltIns(storageManager)
|
val builtIns = createBuiltIns(storageManager)
|
||||||
|
|
||||||
val moduleDescriptor = createDescriptor(name, storageManager, builtIns, origin, customCapabilities)
|
val moduleDescriptor = createDescriptor(name, storageManager, builtIns, origin, customCapabilities)
|
||||||
builtIns.builtInsModule = moduleDescriptor
|
builtIns.builtInsModule = moduleDescriptor
|
||||||
+183
@@ -0,0 +1,183 @@
|
|||||||
|
package org.jetbrains.kotlin.serialization.konan.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataModuleDescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.util.profile
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.KlibResolvedModuleDescriptorsFactory
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.KotlinResolvedModuleDescriptors
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import org.jetbrains.kotlin.storage.getValue
|
||||||
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
|
|
||||||
|
// TODO: eliminate Native specifics.
|
||||||
|
class KlibResolvedModuleDescriptorsFactoryImpl(
|
||||||
|
override val moduleDescriptorFactory: KlibMetadataModuleDescriptorFactory
|
||||||
|
): KlibResolvedModuleDescriptorsFactory {
|
||||||
|
|
||||||
|
override fun createResolved(
|
||||||
|
resolvedLibraries: KotlinLibraryResolveResult,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
customAction: ((KotlinLibrary, ModuleDescriptorImpl) -> Unit)?
|
||||||
|
): KotlinResolvedModuleDescriptors {
|
||||||
|
|
||||||
|
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
var builtIns = builtIns
|
||||||
|
|
||||||
|
// Build module descriptors.
|
||||||
|
resolvedLibraries.forEach { library, packageAccessHandler ->
|
||||||
|
profile("Loading ${library.libraryName}") {
|
||||||
|
|
||||||
|
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
|
||||||
|
val moduleDescriptor = createDescriptorOptionalBuiltsIns(
|
||||||
|
library, languageVersionSettings, storageManager, builtIns, packageAccessHandler
|
||||||
|
)
|
||||||
|
builtIns = moduleDescriptor.builtIns
|
||||||
|
moduleDescriptors.add(moduleDescriptor)
|
||||||
|
|
||||||
|
customAction?.invoke(library, moduleDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val forwardDeclarationsModule = createForwardDeclarationsModule(builtIns, storageManager)
|
||||||
|
|
||||||
|
// Set inter-dependencies between module descriptors, add forwarding declarations module.
|
||||||
|
for (module in moduleDescriptors) {
|
||||||
|
// Yes, just to all of them.
|
||||||
|
module.setDependencies(moduleDescriptors + forwardDeclarationsModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
return KotlinResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createForwardDeclarationsModule(
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
storageManager: StorageManager): ModuleDescriptorImpl {
|
||||||
|
|
||||||
|
val name = Name.special("<forward declarations>")
|
||||||
|
val module = createDescriptorOptionalBuiltsIns(name, storageManager, builtIns, SyntheticModulesOrigin)
|
||||||
|
|
||||||
|
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
|
||||||
|
ForwardDeclarationsPackageFragmentDescriptor(
|
||||||
|
storageManager,
|
||||||
|
module,
|
||||||
|
fqName,
|
||||||
|
Name.identifier(supertypeName),
|
||||||
|
classKind)
|
||||||
|
|
||||||
|
val packageFragmentProvider = PackageFragmentProviderImpl(
|
||||||
|
listOf(
|
||||||
|
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
|
||||||
|
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
|
||||||
|
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
module.initialize(packageFragmentProvider)
|
||||||
|
module.setDependencies(module)
|
||||||
|
|
||||||
|
return module
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDescriptorOptionalBuiltsIns(
|
||||||
|
name: Name,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
moduleOrigin: KlibModuleOrigin
|
||||||
|
) = if (builtIns != null)
|
||||||
|
moduleDescriptorFactory.descriptorFactory.createDescriptor(name, storageManager, builtIns, moduleOrigin)
|
||||||
|
else
|
||||||
|
moduleDescriptorFactory.descriptorFactory.createDescriptorAndNewBuiltIns(name, storageManager, moduleOrigin)
|
||||||
|
|
||||||
|
private fun createDescriptorOptionalBuiltsIns(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
storageManager: StorageManager,
|
||||||
|
builtIns: KotlinBuiltIns?,
|
||||||
|
packageAccessHandler: PackageAccessHandler?
|
||||||
|
) = if (builtIns != null)
|
||||||
|
moduleDescriptorFactory.createDescriptor(library, languageVersionSettings, storageManager, builtIns, packageAccessHandler)
|
||||||
|
else
|
||||||
|
moduleDescriptorFactory.createDescriptorAndNewBuiltIns(library, languageVersionSettings, storageManager, packageAccessHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package fragment which creates descriptors for forward declarations on demand.
|
||||||
|
*/
|
||||||
|
class ForwardDeclarationsPackageFragmentDescriptor(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
module: ModuleDescriptor,
|
||||||
|
fqName: FqName,
|
||||||
|
supertypeName: Name,
|
||||||
|
classKind: ClassKind
|
||||||
|
) : PackageFragmentDescriptorImpl(module, fqName) {
|
||||||
|
|
||||||
|
private val memberScope = object : MemberScopeImpl() {
|
||||||
|
|
||||||
|
private val declarations = storageManager.createMemoizedFunction(this::createDeclaration)
|
||||||
|
|
||||||
|
private val supertype by storageManager.createLazyValue {
|
||||||
|
val descriptor = builtIns.builtInsModule.getPackage(ForwardDeclarationsFqNames.packageName)
|
||||||
|
.memberScope
|
||||||
|
.getContributedClassifier(supertypeName, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||||
|
|
||||||
|
descriptor.defaultType
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDeclaration(name: Name): ClassDescriptor {
|
||||||
|
return ClassDescriptorImpl(
|
||||||
|
this@ForwardDeclarationsPackageFragmentDescriptor,
|
||||||
|
name,
|
||||||
|
Modality.FINAL,
|
||||||
|
classKind,
|
||||||
|
listOf(supertype),
|
||||||
|
SourceElement.NO_SOURCE,
|
||||||
|
false,
|
||||||
|
LockBasedStorageManager.NO_LOCKS
|
||||||
|
).apply {
|
||||||
|
this.initialize(MemberScope.Empty, emptySet(), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getContributedClassifier(name: Name, location: LookupLocation) = declarations(name)
|
||||||
|
|
||||||
|
override fun printScopeStructure(p: Printer) {
|
||||||
|
p.println(this::class.java.simpleName, "{}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMemberScope(): MemberScope = memberScope
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
|
||||||
|
internal object ForwardDeclarationsFqNames {
|
||||||
|
|
||||||
|
val packageName = FqName("kotlinx.cinterop")
|
||||||
|
|
||||||
|
val cNames = FqName("cnames")
|
||||||
|
val cNamesStructs = cNames.child(Name.identifier("structs"))
|
||||||
|
|
||||||
|
val objCNames = FqName("objcnames")
|
||||||
|
val objCNamesClasses = objCNames.child(Name.identifier("classes"))
|
||||||
|
val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
package org.jetbrains.kotlin.library.resolver
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.*
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
|
||||||
|
interface KotlinLibraryResolver<L: KotlinLibrary> {
|
||||||
|
|
||||||
|
val searchPathResolver: SearchPathResolver<L>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the list of Kotlin/Native library names, ABI version and other parameters
|
||||||
|
* resolves libraries and evaluates dependencies between them.
|
||||||
|
*/
|
||||||
|
fun resolveWithDependencies(
|
||||||
|
unresolvedLibraries: List<UnresolvedLibrary>,
|
||||||
|
noStdLib: Boolean = false,
|
||||||
|
noDefaultLibs: Boolean = false,
|
||||||
|
noEndorsedLibs: Boolean = false
|
||||||
|
): KotlinLibraryResolveResult
|
||||||
|
}
|
||||||
|
|
||||||
|
interface KotlinLibraryResolveResult {
|
||||||
|
|
||||||
|
fun filterRoots(predicate: (KotlinResolvedLibrary) -> Boolean): KotlinLibraryResolveResult
|
||||||
|
|
||||||
|
fun getFullList(order: LibraryOrder? = null): List<KotlinLibrary>
|
||||||
|
|
||||||
|
fun forEach(action: (KotlinLibrary, PackageAccessHandler) -> Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typealias LibraryOrder = (Iterable<KotlinResolvedLibrary>) -> List<KotlinResolvedLibrary>
|
||||||
|
|
||||||
|
val TopologicalLibraryOrder: LibraryOrder = { input ->
|
||||||
|
val sorted = mutableListOf<KotlinResolvedLibrary>()
|
||||||
|
val visited = mutableSetOf<KotlinResolvedLibrary>()
|
||||||
|
val tempMarks = mutableSetOf<KotlinResolvedLibrary>()
|
||||||
|
|
||||||
|
fun visit(node: KotlinResolvedLibrary, result: MutableList<KotlinResolvedLibrary>) {
|
||||||
|
if (visited.contains(node)) return
|
||||||
|
if (tempMarks.contains(node)) error("Cyclic dependency in library graph for: ${node.library.libraryName}")
|
||||||
|
tempMarks.add(node)
|
||||||
|
node.resolvedDependencies.forEach {
|
||||||
|
visit(it, result)
|
||||||
|
}
|
||||||
|
visited.add(node)
|
||||||
|
result += node
|
||||||
|
}
|
||||||
|
|
||||||
|
input.forEach next@{
|
||||||
|
if (visited.contains(it)) return@next
|
||||||
|
visit(it, sorted)
|
||||||
|
}
|
||||||
|
|
||||||
|
sorted
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package org.jetbrains.kotlin.library.resolver
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [KotlinLibrary] wrapper that is used for resolving library's dependencies.
|
||||||
|
*/
|
||||||
|
interface KotlinResolvedLibrary: PackageAccessHandler {
|
||||||
|
|
||||||
|
// The library itself.
|
||||||
|
val library: KotlinLibrary
|
||||||
|
|
||||||
|
// Dependencies on other libraries.
|
||||||
|
val resolvedDependencies: List<KotlinResolvedLibrary>
|
||||||
|
|
||||||
|
// Any package fragment within this library has beed visited during frontend resolve phase.
|
||||||
|
// You need to utilize PackageAccessHandler to make it work for you.
|
||||||
|
val isNeededForLink: Boolean
|
||||||
|
|
||||||
|
// Is provided by the distribution?
|
||||||
|
val isDefault: Boolean
|
||||||
|
}
|
||||||
+156
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.library.resolver.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
import org.jetbrains.kotlin.library.*
|
||||||
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolver
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||||
|
import org.jetbrains.kotlin.library.resolver.LibraryOrder
|
||||||
|
import org.jetbrains.kotlin.util.WithLogger
|
||||||
|
|
||||||
|
fun <L: KotlinLibrary> SearchPathResolver<L>.libraryResolver()
|
||||||
|
= KotlinLibraryResolverImpl<L>(this)
|
||||||
|
|
||||||
|
class KotlinLibraryResolverImpl<L: KotlinLibrary>(
|
||||||
|
override val searchPathResolver: SearchPathResolver<L>
|
||||||
|
): KotlinLibraryResolver<L>, WithLogger by searchPathResolver {
|
||||||
|
|
||||||
|
override fun resolveWithDependencies(
|
||||||
|
unresolvedLibraries: List<UnresolvedLibrary>,
|
||||||
|
noStdLib: Boolean,
|
||||||
|
noDefaultLibs: Boolean,
|
||||||
|
noEndorsedLibs: Boolean
|
||||||
|
) = findLibraries(unresolvedLibraries, noStdLib, noDefaultLibs, noEndorsedLibs)
|
||||||
|
.leaveDistinct()
|
||||||
|
.resolveDependencies()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of libraries based on [libraryNames], [noStdLib], [noDefaultLibs] and [noEndorsedLibs] criteria.
|
||||||
|
*
|
||||||
|
* This method does not return any libraries that might be available via transitive dependencies
|
||||||
|
* from the original library set (root set).
|
||||||
|
*/
|
||||||
|
private fun findLibraries(
|
||||||
|
unresolvedLibraries: List<UnresolvedLibrary>,
|
||||||
|
noStdLib: Boolean,
|
||||||
|
noDefaultLibs: Boolean,
|
||||||
|
noEndorsedLibs: Boolean
|
||||||
|
): List<KotlinLibrary> {
|
||||||
|
|
||||||
|
val userProvidedLibraries = unresolvedLibraries.asSequence()
|
||||||
|
.map { searchPathResolver.resolve(it) }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
val defaultLibraries = searchPathResolver.defaultLinks(noStdLib, noDefaultLibs, noEndorsedLibs)
|
||||||
|
|
||||||
|
// Make sure the user provided ones appear first, so that
|
||||||
|
// they have precedence over defaults when duplicates are eliminated.
|
||||||
|
return userProvidedLibraries + defaultLibraries
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaves only distinct libraries (by absolute path), warns on duplicated paths.
|
||||||
|
*/
|
||||||
|
private fun List<KotlinLibrary>.leaveDistinct() =
|
||||||
|
this.groupBy { it.libraryFile.absolutePath }.let { groupedByAbsolutePath ->
|
||||||
|
warnOnLibraryDuplicates(groupedByAbsolutePath.filter { it.value.size > 1 }.keys)
|
||||||
|
groupedByAbsolutePath.map { it.value.first() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun warnOnLibraryDuplicates(duplicatedPaths: Iterable<String>) {
|
||||||
|
duplicatedPaths.forEach { logger.warning("library included more than once: $it") }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the list of root libraries does the following:
|
||||||
|
*
|
||||||
|
* 1. Evaluates other libraries that are available via transitive dependencies.
|
||||||
|
* 2. Wraps each [KotlinLibrary] into a [KotlinResolvedLibrary] with information about dependencies on other libraries.
|
||||||
|
* 3. Creates resulting [KotlinLibraryResolveResult] object.
|
||||||
|
*/
|
||||||
|
private fun List<KotlinLibrary>.resolveDependencies(): KotlinLibraryResolveResult {
|
||||||
|
|
||||||
|
val rootLibraries = this.map { KotlinResolvedLibraryImpl(it) }
|
||||||
|
|
||||||
|
// As far as the list of root libraries is known from the very beginning, the result can be
|
||||||
|
// constructed from the very beginning as well.
|
||||||
|
val result = KotlinLibraryResolverResultImpl(rootLibraries)
|
||||||
|
|
||||||
|
val cache = mutableMapOf<File, KotlinResolvedLibrary>()
|
||||||
|
cache.putAll(rootLibraries.map { it.library.libraryFile.absoluteFile to it })
|
||||||
|
|
||||||
|
var newDependencies = rootLibraries
|
||||||
|
do {
|
||||||
|
newDependencies = newDependencies.map { library: KotlinResolvedLibraryImpl ->
|
||||||
|
library.library.unresolvedDependencies.asSequence()
|
||||||
|
|
||||||
|
.map { KotlinResolvedLibraryImpl(searchPathResolver.resolve(it)) }
|
||||||
|
.map { resolved ->
|
||||||
|
val absoluteFile = resolved.library.libraryFile.absoluteFile
|
||||||
|
if (absoluteFile in cache) {
|
||||||
|
library.addDependency(cache[absoluteFile]!!)
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
cache.put(absoluteFile, resolved)
|
||||||
|
library.addDependency(resolved)
|
||||||
|
resolved
|
||||||
|
}
|
||||||
|
|
||||||
|
}.filterNotNull()
|
||||||
|
.toList()
|
||||||
|
}.flatten()
|
||||||
|
} while (newDependencies.isNotEmpty())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinLibraryResolverResultImpl(
|
||||||
|
private val roots: List<KotlinResolvedLibrary>
|
||||||
|
): KotlinLibraryResolveResult {
|
||||||
|
|
||||||
|
private val all: List<KotlinResolvedLibrary> by lazy {
|
||||||
|
val result = mutableSetOf<KotlinResolvedLibrary>().also { it.addAll(roots) }
|
||||||
|
|
||||||
|
var newDependencies = result.toList()
|
||||||
|
do {
|
||||||
|
newDependencies = newDependencies
|
||||||
|
.map { it -> it.resolvedDependencies }.flatten()
|
||||||
|
.filter { it !in result }
|
||||||
|
result.addAll(newDependencies)
|
||||||
|
} while (newDependencies.isNotEmpty())
|
||||||
|
|
||||||
|
result.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun filterRoots(predicate: (KotlinResolvedLibrary) -> Boolean) =
|
||||||
|
KotlinLibraryResolverResultImpl(roots.filter(predicate))
|
||||||
|
|
||||||
|
override fun getFullList(order: LibraryOrder?) = (order?.invoke(all) ?: all).asPlain()
|
||||||
|
|
||||||
|
override fun forEach(action: (KotlinLibrary, PackageAccessHandler) -> Unit) {
|
||||||
|
all.forEach { action(it.library, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<KotlinResolvedLibrary>.asPlain() = map { it.library }
|
||||||
|
|
||||||
|
override fun toString() = "roots=$roots, all=$all"
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package org.jetbrains.kotlin.library.resolver.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||||
|
import org.jetbrains.kotlin.library.metadata.parsePackageFragment
|
||||||
|
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
|
||||||
|
class KotlinResolvedLibraryImpl(override val library: KotlinLibrary): KotlinResolvedLibrary {
|
||||||
|
|
||||||
|
private val _resolvedDependencies = mutableListOf<KotlinResolvedLibrary>()
|
||||||
|
private val _emptyPackages by lazy { parseModuleHeader(library.moduleHeaderData).emptyPackageList }
|
||||||
|
|
||||||
|
override val resolvedDependencies: List<KotlinResolvedLibrary>
|
||||||
|
get() = _resolvedDependencies
|
||||||
|
|
||||||
|
internal fun addDependency(resolvedLibrary: KotlinResolvedLibrary) = _resolvedDependencies.add(resolvedLibrary)
|
||||||
|
|
||||||
|
override var isNeededForLink: Boolean = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
override val isDefault: Boolean
|
||||||
|
get() = library.isDefault
|
||||||
|
|
||||||
|
override fun loadPackageFragment(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
packageFqName: String,
|
||||||
|
partName: String
|
||||||
|
): ProtoBuf.PackageFragment {
|
||||||
|
if (!isNeededForLink // fast path
|
||||||
|
&& !_emptyPackages.contains(packageFqName)) {
|
||||||
|
isNeededForLink = true
|
||||||
|
}
|
||||||
|
return parsePackageFragment(library.packageMetadata(packageFqName, partName))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString() = "library=$library, dependsOn=${_resolvedDependencies.joinToString { it.library.toString() }}"
|
||||||
|
}
|
||||||
@@ -11,6 +11,9 @@ const val KLIB_PROPERTY_LIBRARY_VERSION = "library_version"
|
|||||||
const val KLIB_PROPERTY_UNIQUE_NAME = "unique_name"
|
const val KLIB_PROPERTY_UNIQUE_NAME = "unique_name"
|
||||||
const val KLIB_PROPERTY_DEPENDS = "depends"
|
const val KLIB_PROPERTY_DEPENDS = "depends"
|
||||||
const val KLIB_PROPERTY_PACKAGE = "package"
|
const val KLIB_PROPERTY_PACKAGE = "package"
|
||||||
|
const val KLIB_PROPERTY_INTEROP = "interop"
|
||||||
|
const val KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS = "exportForwardDeclarations"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstractions for getting access to the information stored inside of Kotlin/Native library.
|
* Abstractions for getting access to the information stored inside of Kotlin/Native library.
|
||||||
*/
|
*/
|
||||||
@@ -51,3 +54,17 @@ val BaseKotlinLibrary.unresolvedDependencies: List<UnresolvedLibrary>
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface KotlinLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary
|
interface KotlinLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary
|
||||||
|
|
||||||
|
// TODO: should we move the below ones to Native?
|
||||||
|
val KotlinLibrary.isInterop
|
||||||
|
get() = manifestProperties.getProperty(KLIB_PROPERTY_INTEROP) == "true"
|
||||||
|
|
||||||
|
val KotlinLibrary.packageFqName: String?
|
||||||
|
get() = manifestProperties.getProperty(org.jetbrains.kotlin.library.KLIB_PROPERTY_PACKAGE)
|
||||||
|
|
||||||
|
val KotlinLibrary.exportForwardDeclarations
|
||||||
|
get() = manifestProperties.propertyList(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS, escapeInQuotes = true)
|
||||||
|
.asSequence()
|
||||||
|
.map { it.trim() }
|
||||||
|
.filter { it.isNotEmpty() }
|
||||||
|
.toList()
|
||||||
@@ -36,4 +36,4 @@ val List<String>.toUnresolvedLibraries
|
|||||||
.let { if (it.isEmpty()) null else it }
|
.let { if (it.isEmpty()) null else it }
|
||||||
val name = it.substringBeforeLast('@')
|
val name = it.substringBeforeLast('@')
|
||||||
UnresolvedLibrary(name, version)
|
UnresolvedLibrary(name, version)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package org.jetbrains.kotlin.library
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.KonanVersion
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.util.*
|
||||||
|
|
||||||
|
const val KOTLIN_STDLIB_NAME = "stdlib"
|
||||||
|
|
||||||
|
interface SearchPathResolver<out L: KotlinLibrary> : WithLogger {
|
||||||
|
val searchRoots: List<File>
|
||||||
|
fun resolutionSequence(givenPath: String): Sequence<File>
|
||||||
|
fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean = false): L
|
||||||
|
fun resolve(givenPath: String): L
|
||||||
|
fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean, noEndorsedLibs: Boolean): List<L>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchPathResolverWithAttributes<out L: KotlinLibrary>: SearchPathResolver<L> {
|
||||||
|
val knownAbiVersions: List<KotlinAbiVersion>?
|
||||||
|
val knownCompilerVersions: List<KonanVersion>?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolverByName(
|
||||||
|
repositories: List<String>,
|
||||||
|
directLibs: List<String> = emptyList(),
|
||||||
|
distributionKlib: String? = null,
|
||||||
|
localKotlinDir: String? = null,
|
||||||
|
skipCurrentDir: Boolean = false,
|
||||||
|
logger: Logger = DummyLogger
|
||||||
|
): SearchPathResolver<KotlinLibrary> = KotlinLibrarySearchPathResolver(repositories, directLibs, distributionKlib, localKotlinDir, skipCurrentDir, logger)
|
||||||
|
|
||||||
|
open class KotlinLibrarySearchPathResolver<out L: KotlinLibrary>(
|
||||||
|
repositories: List<String>,
|
||||||
|
directLibs: List<String>,
|
||||||
|
val distributionKlib: String?,
|
||||||
|
val localKotlinDir: String?,
|
||||||
|
val skipCurrentDir: Boolean,
|
||||||
|
override val logger: Logger = DummyLogger
|
||||||
|
) : SearchPathResolver<L> {
|
||||||
|
|
||||||
|
val localHead: File?
|
||||||
|
get() = localKotlinDir?.File()?.klib
|
||||||
|
|
||||||
|
val distHead: File?
|
||||||
|
get() = distributionKlib?.File()?.child("common")
|
||||||
|
|
||||||
|
open val distPlatformHead: File? = null
|
||||||
|
|
||||||
|
val currentDirHead: File?
|
||||||
|
get() = if (!skipCurrentDir) File.userDir else null
|
||||||
|
|
||||||
|
private val repoRoots: List<File> by lazy { repositories.map { File(it) } }
|
||||||
|
|
||||||
|
private val directLibraries: List<KotlinLibrary> by lazy {
|
||||||
|
directLibs.mapNotNull { found(File(it)) }.map { createKotlinLibrary(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the place where we specify the order of library search.
|
||||||
|
override val searchRoots: List<File> by lazy {
|
||||||
|
(listOf(currentDirHead) + repoRoots + listOf(localHead, distHead, distPlatformHead)).filterNotNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun found(candidate: File): File? {
|
||||||
|
fun check(file: File): Boolean =
|
||||||
|
file.exists && (file.isFile || File(file, "manifest").exists)
|
||||||
|
|
||||||
|
val noSuffix = File(candidate.path.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT))
|
||||||
|
val withSuffix = File(candidate.path.suffixIfNot(KLIB_FILE_EXTENSION_WITH_DOT))
|
||||||
|
return when {
|
||||||
|
check(withSuffix) -> withSuffix
|
||||||
|
check(noSuffix) -> noSuffix
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolutionSequence(givenPath: String): Sequence<File> {
|
||||||
|
val given = File(givenPath)
|
||||||
|
val sequence = if (given.isAbsolute) {
|
||||||
|
sequenceOf(found(given))
|
||||||
|
} else {
|
||||||
|
// Search among user-provided libraries by unique name.
|
||||||
|
// It's a workaround for maven publication. When a library is published without Gradle metadata,
|
||||||
|
// it has a complex file name (e.g. foo-macos_x64-1.0.klib). But a dependency on this lib in manifests
|
||||||
|
// of other libs uses its unique name written in the manifest (i.e just 'foo'). So we cannot resolve this
|
||||||
|
// library by its filename. But we have this library's file (we've downloaded it using maven dependency
|
||||||
|
// resolution) so we can pass it to the compiler directly. This code takes this into account and looks for
|
||||||
|
// a library dependencies also in libs passed to the compiler as files (passed to the resolver as the
|
||||||
|
// 'directLibraries' property).
|
||||||
|
val directLibs = directLibraries.asSequence().filter {
|
||||||
|
it.uniqueName == givenPath
|
||||||
|
}.map {
|
||||||
|
it.libraryFile
|
||||||
|
}
|
||||||
|
// Search among libraries in repositoreis by library filename.
|
||||||
|
val repoLibs = searchRoots.asSequence().map {
|
||||||
|
found(File(it, givenPath))
|
||||||
|
}
|
||||||
|
directLibs + repoLibs
|
||||||
|
}
|
||||||
|
return sequence.filterNotNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean): L {
|
||||||
|
val givenPath = unresolved.path
|
||||||
|
return resolutionSequence(givenPath).firstOrNull() ?. let {
|
||||||
|
createKotlinLibrary(it, isDefaultLink) as L
|
||||||
|
} ?: run {
|
||||||
|
logger.fatal("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resolve(givenPath: String) = resolve(UnresolvedLibrary(givenPath, null), false)
|
||||||
|
|
||||||
|
|
||||||
|
private val File.klib
|
||||||
|
get() = File(this, "klib")
|
||||||
|
|
||||||
|
// The libraries from the default root are linked automatically.
|
||||||
|
val defaultRoots: List<File>
|
||||||
|
get() = listOfNotNull(distHead, distPlatformHead).filter { it.exists }
|
||||||
|
|
||||||
|
private fun getDefaultLibrariesFromDir(directory: File) =
|
||||||
|
if (directory.exists) {
|
||||||
|
directory.listFiles
|
||||||
|
.asSequence()
|
||||||
|
.filterNot { it.name.startsWith('.') }
|
||||||
|
.filterNot { it.name.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT) == KOTLIN_STDLIB_NAME }
|
||||||
|
.map { UnresolvedLibrary(it.absolutePath, null) }
|
||||||
|
.map { resolve(it, isDefaultLink = true) }
|
||||||
|
} else emptySequence()
|
||||||
|
|
||||||
|
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean, noEndorsedLibs: Boolean): List<L> {
|
||||||
|
|
||||||
|
val result = mutableListOf<L>()
|
||||||
|
|
||||||
|
if (!noStdLib) {
|
||||||
|
result.add(resolve(UnresolvedLibrary(KOTLIN_STDLIB_NAME, null), true))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endorsed libraries in distHead.
|
||||||
|
if (!noEndorsedLibs) {
|
||||||
|
distHead?.let {
|
||||||
|
result.addAll(getDefaultLibrariesFromDir(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Platform libraries resolve.
|
||||||
|
if (!noDefaultLibs) {
|
||||||
|
distPlatformHead?.let {
|
||||||
|
result.addAll(getDefaultLibrariesFromDir(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KonanVersion.compatible(other: KonanVersion) =
|
||||||
|
this.major == other.major
|
||||||
|
&& this.minor == other.minor
|
||||||
|
&& this.maintenance == other.maintenance
|
||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.konan.properties.Properties
|
|||||||
import org.jetbrains.kotlin.konan.properties.loadProperties
|
import org.jetbrains.kotlin.konan.properties.loadProperties
|
||||||
|
|
||||||
open class BaseKotlinLibraryImpl(
|
open class BaseKotlinLibraryImpl(
|
||||||
private val access: BaseLibraryAccess<KotlinLibraryLayout>,
|
val access: BaseLibraryAccess<KotlinLibraryLayout>,
|
||||||
override val isDefault: Boolean
|
override val isDefault: Boolean
|
||||||
) : BaseKotlinLibrary {
|
) : BaseKotlinLibrary {
|
||||||
override val libraryFile get() = access.klib
|
override val libraryFile get() = access.klib
|
||||||
@@ -40,7 +40,7 @@ open class BaseKotlinLibraryImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class MetadataLibraryImpl(
|
open class MetadataLibraryImpl(
|
||||||
private val access: MetadataLibraryAccess<MetadataKotlinLibraryLayout>
|
val access: MetadataLibraryAccess<MetadataKotlinLibraryLayout>
|
||||||
) : MetadataLibrary {
|
) : MetadataLibrary {
|
||||||
|
|
||||||
override val moduleHeaderData: ByteArray by lazy {
|
override val moduleHeaderData: ByteArray by lazy {
|
||||||
@@ -72,7 +72,7 @@ open class MetadataLibraryImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class IrLibraryImpl(
|
abstract class IrLibraryImpl(
|
||||||
protected val access: IrLibraryAccess<IrKotlinLibraryLayout>
|
val access: IrLibraryAccess<IrKotlinLibraryLayout>
|
||||||
) : IrLibrary {
|
) : IrLibrary {
|
||||||
override val dataFlowGraph by lazy {
|
override val dataFlowGraph by lazy {
|
||||||
access.inPlace { it: IrKotlinLibraryLayout ->
|
access.inPlace { it: IrKotlinLibraryLayout ->
|
||||||
@@ -211,9 +211,9 @@ class IrPerFileLibraryImpl(_access: IrLibraryAccess<IrKotlinLibraryLayout>) : Ir
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinLibraryImpl(
|
open class KotlinLibraryImpl(
|
||||||
base: BaseKotlinLibraryImpl,
|
val base: BaseKotlinLibraryImpl,
|
||||||
metadata: MetadataLibraryImpl,
|
val metadata: MetadataLibraryImpl,
|
||||||
ir: IrLibraryImpl
|
val ir: IrLibraryImpl
|
||||||
) : KotlinLibrary,
|
) : KotlinLibrary,
|
||||||
BaseKotlinLibrary by base,
|
BaseKotlinLibrary by base,
|
||||||
MetadataLibrary by metadata,
|
MetadataLibrary by metadata,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import org.jetbrains.kotlin.konan.file.File
|
|||||||
import org.jetbrains.kotlin.konan.file.file
|
import org.jetbrains.kotlin.konan.file.file
|
||||||
import org.jetbrains.kotlin.konan.file.withZipFileSystem
|
import org.jetbrains.kotlin.konan.file.withZipFileSystem
|
||||||
import org.jetbrains.kotlin.library.*
|
import org.jetbrains.kotlin.library.*
|
||||||
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
|
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||||
import java.nio.file.FileSystem
|
import java.nio.file.FileSystem
|
||||||
|
|
||||||
open class KotlinLibraryLayoutImpl(val klib: File) : KotlinLibraryLayout {
|
open class KotlinLibraryLayoutImpl(val klib: File) : KotlinLibraryLayout {
|
||||||
|
|||||||
@@ -55,15 +55,10 @@ val PROTO_PATHS: List<ProtoPath> = listOf(
|
|||||||
ProtoPath("core/metadata/src/builtins.proto"),
|
ProtoPath("core/metadata/src/builtins.proto"),
|
||||||
ProtoPath("js/js.serializer/src/js.proto"),
|
ProtoPath("js/js.serializer/src/js.proto"),
|
||||||
ProtoPath("js/js.serializer/src/js-ast.proto", false),
|
ProtoPath("js/js.serializer/src/js-ast.proto", false),
|
||||||
ProtoPath("konan/library-reader/src/konan.proto"),
|
|
||||||
ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"),
|
ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"),
|
||||||
ProtoPath("core/metadata.jvm/src/jvm_module.proto"),
|
ProtoPath("core/metadata.jvm/src/jvm_module.proto"),
|
||||||
ProtoPath("build-common/src/java_descriptors.proto"),
|
ProtoPath("build-common/src/java_descriptors.proto"),
|
||||||
|
ProtoPath("compiler/util-klib-metadata/src/KlibMetadataProtoBuf.proto", false),
|
||||||
// TODO drop this scheme, 'compiler/ir/serialization.js/src/js.proto' is the actual one
|
|
||||||
ProtoPath("compiler/ir/backend.js/src/js.proto", false),
|
|
||||||
|
|
||||||
ProtoPath("compiler/ir/serialization.js/src/js.proto", false),
|
|
||||||
ProtoPath("compiler/ir/serialization.common/src/KotlinIr.proto", false)
|
ProtoPath("compiler/ir/serialization.common/src/KotlinIr.proto", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
|||||||
import org.jetbrains.kotlin.gradle.*
|
import org.jetbrains.kotlin.gradle.*
|
||||||
import org.jetbrains.kotlin.idea.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_NOT_IMPORTED_COMMON_SOURCE_SETS_SETTING
|
import org.jetbrains.kotlin.idea.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_NOT_IMPORTED_COMMON_SOURCE_SETS_SETTING
|
||||||
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
|
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
|
||||||
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
|
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import org.jetbrains.plugins.gradle.model.*
|
import org.jetbrains.plugins.gradle.model.*
|
||||||
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
||||||
|
|||||||
@@ -14,28 +14,18 @@ import com.intellij.psi.SingleRootFileViewProvider
|
|||||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||||
import com.intellij.psi.stubs.PsiFileStub
|
import com.intellij.psi.stubs.PsiFileStub
|
||||||
import com.intellij.testFramework.LightVirtualFile
|
import com.intellij.testFramework.LightVirtualFile
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeLoadingMetadataCache
|
import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeLoadingMetadataCache
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
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.idea.decompiler.textBuilder.LoggingErrorReporter
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultPackageFragmentsFactory
|
import org.jetbrains.kotlin.library.impl.BaseKotlinLibraryImpl
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
import org.jetbrains.kotlin.library.impl.MetadataLibraryImpl
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryDir
|
import org.jetbrains.kotlin.library.metadata.PackageAccessHandler
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryFile
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.konan.library.MetadataReader
|
|
||||||
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
const val KOTLIN_NATIVE_CURRENT_ABI_VERSION = 1
|
|
||||||
|
|
||||||
fun createFileStub(project: Project, text: String): PsiFileStub<*> {
|
fun createFileStub(project: Project, text: String): PsiFileStub<*> {
|
||||||
val virtualFile = LightVirtualFile("dummy.kt", KotlinFileType.INSTANCE, text)
|
val virtualFile = LightVirtualFile("dummy.kt", KotlinFileType.INSTANCE, text)
|
||||||
@@ -49,62 +39,48 @@ fun createFileStub(project: Project, text: String): PsiFileStub<*> {
|
|||||||
|
|
||||||
fun createLoggingErrorReporter(log: Logger) = LoggingErrorReporter(log)
|
fun createLoggingErrorReporter(log: Logger) = LoggingErrorReporter(log)
|
||||||
|
|
||||||
fun KonanLibrary.createPackageFragmentProvider(
|
internal object CachingIdeKonanLibraryMetadataLoader : PackageAccessHandler {
|
||||||
storageManager: StorageManager,
|
override fun loadModuleHeader(
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
library: KotlinLibrary
|
||||||
moduleDescriptor: ModuleDescriptor
|
): KlibMetadataProtoBuf.Header {
|
||||||
): PackageFragmentProvider {
|
val virtualFile = getVirtualFile(library, library.moduleHeaderFile)
|
||||||
|
return cache.getCachedModuleHeader(virtualFile)
|
||||||
val library = this
|
|
||||||
|
|
||||||
val libraryProto = library.moduleHeaderData
|
|
||||||
|
|
||||||
//TODO: Is it required somehow?
|
|
||||||
//val moduleName = Name.special(libraryProto.moduleName)
|
|
||||||
//val moduleOrigin = DeserializedKonanModuleOrigin(library)
|
|
||||||
|
|
||||||
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
|
|
||||||
|
|
||||||
return DefaultPackageFragmentsFactory.createPackageFragmentProvider(
|
|
||||||
library,
|
|
||||||
null,
|
|
||||||
libraryProto.packageFragmentNameList,
|
|
||||||
storageManager,
|
|
||||||
moduleDescriptor,
|
|
||||||
deserializationConfiguration
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object CachingIdeMetadataReaderImpl : MetadataReader {
|
|
||||||
|
|
||||||
override fun loadSerializedModule(libraryLayout: KonanLibraryLayout): KonanProtoBuf.LinkDataLibrary =
|
|
||||||
cache.getCachedModuleHeader(libraryLayout.getVirtualFile(libraryLayout.moduleHeaderFile))
|
|
||||||
|
|
||||||
override fun loadSerializedPackageFragment(
|
|
||||||
libraryLayout: KonanLibraryLayout,
|
|
||||||
packageFqName: String,
|
|
||||||
partName: String
|
|
||||||
): KonanProtoBuf.LinkDataPackageFragment =
|
|
||||||
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName, partName)))
|
|
||||||
|
|
||||||
private fun KonanLibraryLayout.getVirtualFile(file: File): VirtualFile {
|
|
||||||
val source = this.source
|
|
||||||
return when (source) {
|
|
||||||
is KonanLibraryFile -> asJarFileSystemFile(source.klibFile, file)
|
|
||||||
is KonanLibraryDir -> asLocalFile(file)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun asJarFileSystemFile(jarFile: File, localFile: File): VirtualFile {
|
override fun loadPackageFragment(
|
||||||
|
library: KotlinLibrary,
|
||||||
|
packageFqName: String,
|
||||||
|
partName: String
|
||||||
|
): ProtoBuf.PackageFragment {
|
||||||
|
val virtualFile = getVirtualFile(library, library.packageFragmentFile(packageFqName, partName))
|
||||||
|
return cache.getCachedPackageFragment(virtualFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVirtualFile(library: KotlinLibrary, file: KFile): VirtualFile =
|
||||||
|
if (library.isZipped) asJarFileSystemFile(library.libraryFile, file) else asLocalFile(file)
|
||||||
|
|
||||||
|
private fun asJarFileSystemFile(jarFile: KFile, localFile: KFile): VirtualFile {
|
||||||
val fullPath = jarFile.absolutePath + "!" + localFile.absolutePath
|
val fullPath = jarFile.absolutePath + "!" + localFile.absolutePath
|
||||||
return StandardFileSystems.jar().findFileByPath(fullPath) ?: error("File not found: $fullPath")
|
return StandardFileSystems.jar().findFileByPath(fullPath) ?: error("File not found: $fullPath")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun asLocalFile(localFile: File): VirtualFile {
|
private fun asLocalFile(localFile: KFile): VirtualFile {
|
||||||
val fullPath = localFile.absolutePath
|
val fullPath = localFile.absolutePath
|
||||||
return StandardFileSystems.local().findFileByPath(fullPath) ?: error("File not found: $fullPath")
|
return StandardFileSystems.local().findFileByPath(fullPath) ?: error("File not found: $fullPath")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val cache
|
private val cache
|
||||||
get() = KotlinNativeLoadingMetadataCache.getInstance()
|
get() = KotlinNativeLoadingMetadataCache.getInstance()
|
||||||
|
|
||||||
|
|
||||||
|
private val KotlinLibrary.moduleHeaderFile get() =
|
||||||
|
(this as MetadataLibraryImpl).access.layout.moduleHeaderFile
|
||||||
|
|
||||||
|
private fun KotlinLibrary.packageFragmentFile(packageFqName: String, partName: String) =
|
||||||
|
(this as MetadataLibraryImpl).access.layout.packageFragmentFile(packageFqName, partName)
|
||||||
|
|
||||||
|
private val KotlinLibrary.isZipped get() =
|
||||||
|
(this as BaseKotlinLibraryImpl).access.layout.isZipped
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+50
-19
@@ -24,7 +24,8 @@ import org.jetbrains.kotlin.context.ProjectContext
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
|
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
||||||
import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory
|
import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory
|
||||||
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
|
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.project.lazyClosure
|
import org.jetbrains.kotlin.idea.caches.project.lazyClosure
|
||||||
@@ -32,15 +33,47 @@ import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
|
|||||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.library.*
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
import org.jetbrains.kotlin.konan.util.KonanFactories
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.isInterop
|
||||||
|
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
|
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
|
||||||
import org.jetbrains.kotlin.platform.konan.KonanPlatforms
|
import org.jetbrains.kotlin.platform.konan.KonanPlatforms
|
||||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||||
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
|
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
|
||||||
import org.jetbrains.kotlin.resolve.TargetEnvironment
|
import org.jetbrains.kotlin.resolve.TargetEnvironment
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
fun KotlinLibrary.createPackageFragmentProvider(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
moduleDescriptor: ModuleDescriptor
|
||||||
|
): PackageFragmentProvider {
|
||||||
|
|
||||||
|
val library = this
|
||||||
|
|
||||||
|
val libraryProto = parseModuleHeader(library.moduleHeaderData)
|
||||||
|
|
||||||
|
//TODO: Is it required somehow?
|
||||||
|
//val moduleName = Name.special(libraryProto.moduleName)
|
||||||
|
//val moduleOrigin = DeserializedKonanModuleOrigin(library)
|
||||||
|
|
||||||
|
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
|
||||||
|
|
||||||
|
return KonanFactories.DefaultDeserializedDescriptorFactory.createPackageFragmentProvider(
|
||||||
|
library,
|
||||||
|
null,
|
||||||
|
libraryProto.packageFragmentNameList,
|
||||||
|
storageManager,
|
||||||
|
moduleDescriptor,
|
||||||
|
deserializationConfiguration,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
class NativePlatformKindResolution : IdePlatformKindResolution {
|
class NativePlatformKindResolution : IdePlatformKindResolution {
|
||||||
|
|
||||||
override fun createLibraryInfo(project: Project, library: Library): List<LibraryInfo> {
|
override fun createLibraryInfo(project: Project, library: Library): List<LibraryInfo> {
|
||||||
@@ -116,32 +149,34 @@ private fun createKotlinNativeBuiltIns(moduleInfo: ModuleInfo, projectContext: P
|
|||||||
val builtInsModule = KonanFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
|
val builtInsModule = KonanFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
|
||||||
KotlinBuiltIns.BUILTINS_MODULE_NAME,
|
KotlinBuiltIns.BUILTINS_MODULE_NAME,
|
||||||
storageManager,
|
storageManager,
|
||||||
DeserializedKonanModuleOrigin(konanLibrary),
|
DeserializedKlibModuleOrigin(konanLibrary),
|
||||||
stdlibInfo.capabilities
|
stdlibInfo.capabilities
|
||||||
)
|
)
|
||||||
|
|
||||||
val languageSettings = IDELanguageSettingsProvider.getLanguageVersionSettings(stdlibInfo, project, isReleaseCoroutines = false)
|
val languageSettings = IDELanguageSettingsProvider.getLanguageVersionSettings(stdlibInfo, project, isReleaseCoroutines = false)
|
||||||
val deserializationConfiguration = CompilerDeserializationConfiguration(languageSettings)
|
val deserializationConfiguration = CompilerDeserializationConfiguration(languageSettings)
|
||||||
|
|
||||||
val libraryProto = konanLibrary.moduleHeaderData
|
val libraryProto = parseModuleHeader(konanLibrary.moduleHeaderData)
|
||||||
|
|
||||||
val stdlibFragmentProvider = KonanFactories.DefaultPackageFragmentsFactory.createPackageFragmentProvider(
|
val stdlibFragmentProvider = KonanFactories.DefaultDeserializedDescriptorFactory.createPackageFragmentProvider(
|
||||||
konanLibrary,
|
konanLibrary,
|
||||||
null,
|
CachingIdeKonanLibraryMetadataLoader,
|
||||||
libraryProto.packageFragmentNameList,
|
libraryProto.packageFragmentNameList,
|
||||||
storageManager,
|
storageManager,
|
||||||
builtInsModule,
|
builtInsModule,
|
||||||
deserializationConfiguration
|
deserializationConfiguration,
|
||||||
|
null
|
||||||
)
|
)
|
||||||
|
|
||||||
builtInsModule.initialize(
|
builtInsModule.initialize(
|
||||||
CompositePackageFragmentProvider(
|
CompositePackageFragmentProvider(
|
||||||
listOf(
|
listOf(
|
||||||
stdlibFragmentProvider,
|
stdlibFragmentProvider,
|
||||||
KonanFactories.DefaultPackageFragmentsFactory.createForwardDeclarationHackPackagePartProvider(
|
(KonanFactories.DefaultDeserializedDescriptorFactory as KlibMetadataModuleDescriptorFactoryImpl)
|
||||||
storageManager,
|
.createForwardDeclarationHackPackagePartProvider(
|
||||||
builtInsModule
|
storageManager,
|
||||||
)
|
builtInsModule
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -158,11 +193,7 @@ private fun ModuleInfo.findNativeStdlib(project: Project): NativeLibraryInfo? =
|
|||||||
|
|
||||||
class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) {
|
class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) {
|
||||||
|
|
||||||
private val nativeLibrary = createKonanLibrary(
|
private val nativeLibrary = createKotlinLibrary(root)
|
||||||
root,
|
|
||||||
KOTLIN_NATIVE_CURRENT_ABI_VERSION,
|
|
||||||
metadataReader = CachingIdeMetadataReaderImpl
|
|
||||||
)
|
|
||||||
|
|
||||||
private val roots = listOf(root.absolutePath)
|
private val roots = listOf(root.absolutePath)
|
||||||
|
|
||||||
@@ -173,8 +204,8 @@ class NativeLibraryInfo(project: Project, library: Library, root: File) : Librar
|
|||||||
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||||
get() = super.capabilities +
|
get() = super.capabilities +
|
||||||
mapOf(
|
mapOf(
|
||||||
ImplicitIntegerCoercion.MODULE_CAPABILITY to nativeLibrary.isInterop,
|
KlibModuleOrigin.CAPABILITY to this,
|
||||||
NATIVE_LIBRARY_CAPABILITY to nativeLibrary
|
ImplicitIntegerCoercion.MODULE_CAPABILITY to nativeLibrary.isInterop
|
||||||
)
|
)
|
||||||
|
|
||||||
override val platform: TargetPlatform
|
override val platform: TargetPlatform
|
||||||
@@ -183,6 +214,6 @@ class NativeLibraryInfo(project: Project, library: Library, root: File) : Librar
|
|||||||
override fun toString() = "Native" + super.toString()
|
override fun toString() = "Native" + super.toString()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KonanLibrary>("KonanLibrary")
|
val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KotlinLibrary>("KotlinLibrary")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-7
@@ -11,9 +11,10 @@ import com.intellij.openapi.vfs.VirtualFile
|
|||||||
import com.intellij.util.containers.ContainerUtil.createConcurrentWeakValueMap
|
import com.intellij.util.containers.ContainerUtil.createConcurrentWeakValueMap
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_MODULE_METADATA_FILE_NAME
|
import org.jetbrains.kotlin.konan.library.KLIB_MODULE_METADATA_FILE_NAME
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
|
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||||
import org.jetbrains.kotlin.serialization.konan.parsePackageFragment
|
import org.jetbrains.kotlin.library.metadata.parsePackageFragment
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
|
||||||
class KotlinNativeLoadingMetadataCache : BaseComponent {
|
class KotlinNativeLoadingMetadataCache : BaseComponent {
|
||||||
|
|
||||||
@@ -32,15 +33,15 @@ class KotlinNativeLoadingMetadataCache : BaseComponent {
|
|||||||
constructor(virtualFile: VirtualFile) : this(virtualFile.url, virtualFile.modificationStamp)
|
constructor(virtualFile: VirtualFile) : this(virtualFile.url, virtualFile.modificationStamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val packageFragmentCache = createConcurrentWeakValueMap<CacheKey, KonanProtoBuf.LinkDataPackageFragment>()
|
private val packageFragmentCache = createConcurrentWeakValueMap<CacheKey, ProtoBuf.PackageFragment>()
|
||||||
private val moduleHeaderCache = createConcurrentWeakValueMap<CacheKey, KonanProtoBuf.LinkDataLibrary>()
|
private val moduleHeaderCache = createConcurrentWeakValueMap<CacheKey, KlibMetadataProtoBuf.Header>()
|
||||||
|
|
||||||
fun getCachedPackageFragment(virtualFile: VirtualFile): KonanProtoBuf.LinkDataPackageFragment =
|
fun getCachedPackageFragment(virtualFile: VirtualFile): ProtoBuf.PackageFragment =
|
||||||
packageFragmentCache.computeIfAbsent(CacheKey(virtualFile.ensurePackageMetadataFile)) {
|
packageFragmentCache.computeIfAbsent(CacheKey(virtualFile.ensurePackageMetadataFile)) {
|
||||||
virtualFile.createPackageFragmentCacheEntry
|
virtualFile.createPackageFragmentCacheEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCachedModuleHeader(virtualFile: VirtualFile): KonanProtoBuf.LinkDataLibrary =
|
fun getCachedModuleHeader(virtualFile: VirtualFile): KlibMetadataProtoBuf.Header =
|
||||||
moduleHeaderCache.computeIfAbsent(CacheKey(virtualFile.ensureModuleHeaderFile)) {
|
moduleHeaderCache.computeIfAbsent(CacheKey(virtualFile.ensureModuleHeaderFile)) {
|
||||||
virtualFile.createModuleHeaderCacheEntry
|
virtualFile.createModuleHeaderCacheEntry
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -10,12 +10,12 @@ import com.intellij.openapi.fileTypes.FileTypeConsumer
|
|||||||
import com.intellij.openapi.fileTypes.FileTypeFactory
|
import com.intellij.openapi.fileTypes.FileTypeFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
|
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
|
||||||
|
|
||||||
class KotlinNativeMetadataDecompiler : KotlinNativeMetadataDecompilerBase<KotlinNativeMetadataVersion>(
|
class KotlinNativeMetadataDecompiler : KotlinNativeMetadataDecompilerBase<KotlinNativeMetadataVersion>(
|
||||||
KotlinNativeMetaFileType, { KonanSerializerProtocol }, NullFlexibleTypeDeserializer,
|
KotlinNativeMetaFileType, { KlibMetadataSerializerProtocol }, NullFlexibleTypeDeserializer,
|
||||||
{ KotlinNativeMetadataVersion.DEFAULT_INSTANCE },
|
{ KotlinNativeMetadataVersion.DEFAULT_INSTANCE },
|
||||||
{ KotlinNativeMetadataVersion.INVALID_VERSION },
|
{ KotlinNativeMetadataVersion.INVALID_VERSION },
|
||||||
KotlinNativeMetaFileType.STUB_VERSION
|
KotlinNativeMetaFileType.STUB_VERSION
|
||||||
@@ -23,7 +23,7 @@ class KotlinNativeMetadataDecompiler : KotlinNativeMetadataDecompilerBase<Kotlin
|
|||||||
|
|
||||||
override fun doReadFile(file: VirtualFile): FileWithMetadata? {
|
override fun doReadFile(file: VirtualFile): FileWithMetadata? {
|
||||||
val proto = KotlinNativeLoadingMetadataCache.getInstance().getCachedPackageFragment(file)
|
val proto = KotlinNativeLoadingMetadataCache.getInstance().getCachedPackageFragment(file)
|
||||||
return FileWithMetadata.Compatible(proto, KonanSerializerProtocol) //todo: check version compatibility
|
return FileWithMetadata.Compatible(proto, KlibMetadataSerializerProtocol) //todo: check version compatibility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -15,10 +15,10 @@ import org.jetbrains.kotlin.idea.decompiler.common.createIncompatibleAbiVersionD
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.defaultDecompilerRendererOptions
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.defaultDecompilerRendererOptions
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
||||||
@@ -99,14 +99,14 @@ sealed class FileWithMetadata {
|
|||||||
class Incompatible(val version: BinaryVersion) : FileWithMetadata()
|
class Incompatible(val version: BinaryVersion) : FileWithMetadata()
|
||||||
|
|
||||||
open class Compatible(
|
open class Compatible(
|
||||||
val proto: KonanProtoBuf.LinkDataPackageFragment,
|
val proto: ProtoBuf.PackageFragment,
|
||||||
serializerProtocol: SerializerExtensionProtocol // TODO: Is it required?
|
serializerProtocol: SerializerExtensionProtocol // TODO: Is it required?
|
||||||
) : FileWithMetadata() {
|
) : FileWithMetadata() {
|
||||||
val nameResolver = NameResolverImpl(proto.stringTable, proto.nameTable)
|
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
|
||||||
val packageFqName = FqName(proto.fqName)
|
val packageFqName = FqName(proto.getExtension(KlibMetadataProtoBuf.fqName))
|
||||||
|
|
||||||
open val classesToDecompile: List<ProtoBuf.Class> =
|
open val classesToDecompile: List<ProtoBuf.Class> =
|
||||||
proto.classes.classesList.filter { proto ->
|
proto.class_List.filter { proto ->
|
||||||
val classId = nameResolver.getClassId(proto.fqName)
|
val classId = nameResolver.getClassId(proto.fqName)
|
||||||
!classId.isNestedClass && classId !in ClassDeserializer.BLACK_LIST
|
!classId.isNestedClass && classId !in ClassDeserializer.BLACK_LIST
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.ide.konan.createLoggingErrorReporter
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||||
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
|||||||
|
|
||||||
class KotlinNativeMetadataDeserializerForDecompiler(
|
class KotlinNativeMetadataDeserializerForDecompiler(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
private val proto: KonanProtoBuf.LinkDataPackageFragment,
|
private val proto: ProtoBuf.PackageFragment,
|
||||||
private val nameResolver: NameResolver,
|
private val nameResolver: NameResolver,
|
||||||
serializerProtocol: SerializerExtensionProtocol,
|
serializerProtocol: SerializerExtensionProtocol,
|
||||||
flexibleTypeDeserializer: FlexibleTypeDeserializer
|
flexibleTypeDeserializer: FlexibleTypeDeserializer
|
||||||
|
|||||||
+3
-3
@@ -6,20 +6,20 @@
|
|||||||
package org.jetbrains.kotlin.ide.konan.decompiler
|
package org.jetbrains.kotlin.ide.konan.decompiler
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||||
|
|
||||||
class KotlinNativeProtoBasedClassDataFinder(
|
class KotlinNativeProtoBasedClassDataFinder(
|
||||||
proto: KonanProtoBuf.LinkDataPackageFragment,
|
proto: ProtoBuf.PackageFragment,
|
||||||
private val nameResolver: NameResolver,
|
private val nameResolver: NameResolver,
|
||||||
private val classSource: (ClassId) -> SourceElement = { SourceElement.NO_SOURCE }
|
private val classSource: (ClassId) -> SourceElement = { SourceElement.NO_SOURCE }
|
||||||
) : ClassDataFinder {
|
) : ClassDataFinder {
|
||||||
private val classIdToProto =
|
private val classIdToProto =
|
||||||
proto.classes.classesList.associateBy { klass ->
|
proto.class_List.associateBy { klass ->
|
||||||
nameResolver.getClassId(klass.fqName)
|
nameResolver.getClassId(klass.fqName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -9,6 +9,7 @@ import com.intellij.util.indexing.FileBasedIndex
|
|||||||
import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeLoadingMetadataCache
|
import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeLoadingMetadataCache
|
||||||
import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeMetaFileType
|
import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeMetaFileType
|
||||||
import org.jetbrains.kotlin.idea.vfilefinder.KotlinFileIndexBase
|
import org.jetbrains.kotlin.idea.vfilefinder.KotlinFileIndexBase
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
object KotlinNativeMetaFileIndex : KotlinFileIndexBase<KotlinNativeMetaFileIndex>(KotlinNativeMetaFileIndex::class.java) {
|
object KotlinNativeMetaFileIndex : KotlinFileIndexBase<KotlinNativeMetaFileIndex>(KotlinNativeMetaFileIndex::class.java) {
|
||||||
@@ -27,6 +28,6 @@ object KotlinNativeMetaFileIndex : KotlinFileIndexBase<KotlinNativeMetaFileIndex
|
|||||||
/*todo: check version?!*/
|
/*todo: check version?!*/
|
||||||
private val INDEXER = indexer { fileContent ->
|
private val INDEXER = indexer { fileContent ->
|
||||||
val fragment = KotlinNativeLoadingMetadataCache.getInstance().getCachedPackageFragment(fileContent.file)
|
val fragment = KotlinNativeLoadingMetadataCache.getInstance().getCachedPackageFragment(fileContent.file)
|
||||||
FqName(fragment.fqName)
|
FqName(fragment.getExtension(KlibMetadataProtoBuf.fqName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.js.test
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
||||||
import org.jetbrains.kotlin.ir.backend.js.loadKlib
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||||
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||||
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
||||||
@@ -15,15 +14,20 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.js.config.JsConfig
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||||
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrarySearchPathResolver
|
||||||
|
import org.jetbrains.kotlin.library.UnresolvedLibrary
|
||||||
|
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||||
|
import org.jetbrains.kotlin.library.toUnresolvedLibraries
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
|
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.Boolean.getBoolean
|
import java.lang.Boolean.getBoolean
|
||||||
|
|
||||||
private val fullRuntimeKlib = loadKlib("compiler/ir/serialization.js/build/fullRuntime/klib")
|
private val fullRuntimeKlib = "compiler/ir/serialization.js/build/fullRuntime/klib"
|
||||||
private val defaultRuntimeKlib = loadKlib("compiler/ir/serialization.js/build/reducedRuntime/klib")
|
private val defaultRuntimeKlib = "compiler/ir/serialization.js/build/reducedRuntime/klib"
|
||||||
private val kotlinTestKLib = loadKlib("compiler/ir/serialization.js/build/kotlin.test/klib")
|
private val kotlinTestKLib = "compiler/ir/serialization.js/build/kotlin.test/klib"
|
||||||
|
|
||||||
abstract class BasicIrBoxTest(
|
abstract class BasicIrBoxTest(
|
||||||
pathToTestDir: String,
|
pathToTestDir: String,
|
||||||
@@ -80,9 +84,27 @@ abstract class BasicIrBoxTest(
|
|||||||
|
|
||||||
val transitiveLibraries = config.configuration[JSConfigurationKeys.TRANSITIVE_LIBRARIES]!!.map { File(it).name }
|
val transitiveLibraries = config.configuration[JSConfigurationKeys.TRANSITIVE_LIBRARIES]!!.map { File(it).name }
|
||||||
|
|
||||||
val allDependencies = runtimeKlibs + transitiveLibraries.map {
|
val allKlibPaths = (runtimeKlibs + transitiveLibraries.map {
|
||||||
loadKlib(compilationCache[it] ?: error("Can't find compiled module for dependency $it"))
|
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||||
}
|
}).map { File(it).absolutePath }
|
||||||
|
val unresolvedLibraries = allKlibPaths.toUnresolvedLibraries
|
||||||
|
|
||||||
|
// Configure the resolver to only work with absolute paths for now.
|
||||||
|
val libraryResolver = KotlinLibrarySearchPathResolver<KotlinLibrary>(
|
||||||
|
repositories = emptyList(),
|
||||||
|
directLibs = allKlibPaths,
|
||||||
|
distributionKlib = null,
|
||||||
|
localKotlinDir = null,
|
||||||
|
skipCurrentDir = true
|
||||||
|
// TODO: pass logger attached to message collector here.
|
||||||
|
).libraryResolver()
|
||||||
|
val resolvedLibraries =
|
||||||
|
libraryResolver.resolveWithDependencies(
|
||||||
|
unresolvedLibraries = unresolvedLibraries,
|
||||||
|
noStdLib = true,
|
||||||
|
noDefaultLibs = true,
|
||||||
|
noEndorsedLibs = true
|
||||||
|
)
|
||||||
|
|
||||||
val actualOutputFile = outputFile.absolutePath.let {
|
val actualOutputFile = outputFile.absolutePath.let {
|
||||||
if (!isMainModule) it.replace("_v5.js", "/") else it
|
if (!isMainModule) it.replace("_v5.js", "/") else it
|
||||||
@@ -111,7 +133,7 @@ abstract class BasicIrBoxTest(
|
|||||||
files = filesToCompile,
|
files = filesToCompile,
|
||||||
configuration = config.configuration,
|
configuration = config.configuration,
|
||||||
phaseConfig = phaseConfig,
|
phaseConfig = phaseConfig,
|
||||||
allDependencies = allDependencies,
|
allDependencies = resolvedLibraries,
|
||||||
friendDependencies = emptyList(),
|
friendDependencies = emptyList(),
|
||||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
||||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction)))
|
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction)))
|
||||||
@@ -130,7 +152,7 @@ abstract class BasicIrBoxTest(
|
|||||||
project = config.project,
|
project = config.project,
|
||||||
files = filesToCompile,
|
files = filesToCompile,
|
||||||
configuration = config.configuration,
|
configuration = config.configuration,
|
||||||
allDependencies = allDependencies,
|
allDependencies = resolvedLibraries,
|
||||||
friendDependencies = emptyList(),
|
friendDependencies = emptyList(),
|
||||||
outputKlibPath = actualOutputFile,
|
outputKlibPath = actualOutputFile,
|
||||||
nopack = true
|
nopack = true
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.ir.backend.js.loadKlib
|
|||||||
import org.jetbrains.kotlin.js.config.JsConfig
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||||
import org.jetbrains.kotlin.js.test.engines.SpiderMonkeyEngine
|
import org.jetbrains.kotlin.js.test.engines.SpiderMonkeyEngine
|
||||||
|
import org.jetbrains.kotlin.library.resolver.impl.KotlinLibraryResolverResultImpl
|
||||||
|
import org.jetbrains.kotlin.library.resolver.impl.KotlinResolvedLibraryImpl
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
@@ -111,7 +113,8 @@ abstract class BasicWasmBoxTest(
|
|||||||
files = filesToCompile,
|
files = filesToCompile,
|
||||||
configuration = config.configuration,
|
configuration = config.configuration,
|
||||||
phaseConfig = phaseConfig,
|
phaseConfig = phaseConfig,
|
||||||
allDependencies = listOf(wasmRuntimeKlib),
|
// TODO: Bypass the resolver fow wasm.
|
||||||
|
allDependencies = KotlinLibraryResolverResultImpl(listOf(KotlinResolvedLibraryImpl(wasmRuntimeKlib))),
|
||||||
friendDependencies = emptyList(),
|
friendDependencies = emptyList(),
|
||||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction)))
|
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction)))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ dependencies {
|
|||||||
mavenCompileScope(project(":kotlin-compiler"))
|
mavenCompileScope(project(":kotlin-compiler"))
|
||||||
|
|
||||||
compile(project(":kotlin-native:kotlin-native-utils"))
|
compile(project(":kotlin-native:kotlin-native-utils"))
|
||||||
|
compile(project(":kotlin-util-io"))
|
||||||
|
compile(project(":kotlin-util-klib"))
|
||||||
|
compile(project(":kotlin-util-klib-metadata"))
|
||||||
|
|
||||||
testCompile(commonDep("junit:junit"))
|
testCompile(commonDep("junit:junit"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
syntax = "proto2";
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.metadata.konan;
|
|
||||||
|
|
||||||
import "core/metadata/src/metadata.proto";
|
|
||||||
|
|
||||||
option java_outer_classname = "KonanProtoBuf";
|
|
||||||
option optimize_for = LITE_RUNTIME;
|
|
||||||
|
|
||||||
// Konan extensions to the "descriptors" protobuf.
|
|
||||||
|
|
||||||
extend Package {
|
|
||||||
optional int32 package_fq_name = 171;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend Class {
|
|
||||||
repeated Annotation class_annotation = 170;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend Constructor {
|
|
||||||
repeated Annotation constructor_annotation = 170;
|
|
||||||
optional InlineIrBody inline_constructor_ir_body = 171;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend Function {
|
|
||||||
repeated Annotation function_annotation = 170;
|
|
||||||
optional InlineIrBody inline_ir_body = 171;
|
|
||||||
optional int32 function_file = 172;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend Property {
|
|
||||||
repeated Annotation property_annotation = 170;
|
|
||||||
repeated Annotation property_getter_annotation = 177;
|
|
||||||
repeated Annotation property_setter_annotation = 178;
|
|
||||||
optional bool has_backing_field = 171;
|
|
||||||
optional bool used_as_variable = 172;
|
|
||||||
optional Annotation.Argument.Value compile_time_value = 173;
|
|
||||||
optional InlineIrBody inline_getter_ir_body = 174;
|
|
||||||
optional InlineIrBody inline_setter_ir_body = 175;
|
|
||||||
optional int32 property_file = 176;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend EnumEntry {
|
|
||||||
repeated Annotation enum_entry_annotation = 170;
|
|
||||||
optional int32 enum_entry_ordinal = 171;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend ValueParameter {
|
|
||||||
repeated Annotation parameter_annotation = 170;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend Type {
|
|
||||||
repeated Annotation type_annotation = 170;
|
|
||||||
optional string type_text = 172; // TODO: remove me
|
|
||||||
}
|
|
||||||
|
|
||||||
extend TypeParameter {
|
|
||||||
repeated Annotation type_parameter_annotation = 170;
|
|
||||||
}
|
|
||||||
|
|
||||||
message InlineIrBody {
|
|
||||||
// We need to refer from descriptors to ir inline body.
|
|
||||||
// And in ir we need to refer local declaration descriptors
|
|
||||||
// That requires mutual import of KonanIr and KonanLinkData.
|
|
||||||
// I break the circle here by storing encoded IR.
|
|
||||||
// May be we need to merge KonanIr into KonanLinkData.
|
|
||||||
// That'd allow mutually recursive messages.
|
|
||||||
required string encoded_ir = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Konan Binary Linkdata structures.
|
|
||||||
|
|
||||||
message LinkDataPackageFragment {
|
|
||||||
// Make if an index?
|
|
||||||
required string fq_name = 1;
|
|
||||||
required Package package = 4;
|
|
||||||
required LinkDataClasses classes = 5;
|
|
||||||
required bool is_empty = 6;
|
|
||||||
|
|
||||||
// To construct name resolver
|
|
||||||
required QualifiedNameTable name_table = 2;
|
|
||||||
required StringTable string_table = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message LinkDataClasses {
|
|
||||||
// Index in the QualifiedNameIndex table.
|
|
||||||
repeated int32 class_name = 1;
|
|
||||||
repeated Class classes = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message LinkDataLibrary {
|
|
||||||
required string module_name = 1;
|
|
||||||
repeated string package_fragment_name = 2;
|
|
||||||
repeated string empty_package = 3;
|
|
||||||
repeated string file = 4;
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.descriptors.konan
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.isInterop
|
|
||||||
|
|
||||||
sealed class KonanModuleOrigin {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val CAPABILITY = ModuleDescriptor.Capability<KonanModuleOrigin>("KonanModuleOrigin")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class CompiledKonanModuleOrigin: KonanModuleOrigin()
|
|
||||||
|
|
||||||
class DeserializedKonanModuleOrigin(val library: KonanLibrary) : CompiledKonanModuleOrigin()
|
|
||||||
|
|
||||||
object CurrentKonanModuleOrigin: CompiledKonanModuleOrigin()
|
|
||||||
|
|
||||||
object SyntheticModulesOrigin : KonanModuleOrigin()
|
|
||||||
|
|
||||||
internal fun KonanModuleOrigin.isInteropLibrary(): Boolean = when (this) {
|
|
||||||
is DeserializedKonanModuleOrigin -> this.library.isInterop
|
|
||||||
CurrentKonanModuleOrigin, SyntheticModulesOrigin -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
val ModuleDescriptor.konanModuleOrigin get() = this.getCapability(KonanModuleOrigin.CAPABILITY)!!
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.konan.library
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||||
|
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||||
|
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
fun createKonanBuiltIns(storageManager: StorageManager) = KonanBuiltIns(storageManager)
|
||||||
|
/**
|
||||||
|
* The default Kotlin/Native factories.
|
||||||
|
*/
|
||||||
|
object KonanFactories : KlibMetadataFactories(::createKonanBuiltIns, NullFlexibleTypeDeserializer)
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.properties.Properties
|
|
||||||
import org.jetbrains.kotlin.konan.properties.propertyList
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
const val KLIB_PROPERTY_ABI_VERSION = "abi_version"
|
|
||||||
const val KLIB_PROPERTY_UNIQUE_NAME = "unique_name"
|
|
||||||
const val KLIB_PROPERTY_COMPILER_VERSION = "compiler_version"
|
|
||||||
const val KLIB_PROPERTY_LINKED_OPTS = "linkerOpts"
|
|
||||||
const val KLIB_PROPERTY_DEPENDS = "depends"
|
|
||||||
const val KLIB_PROPERTY_INTEROP = "interop"
|
|
||||||
const val KLIB_PROPERTY_PACKAGE = "package"
|
|
||||||
const val KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS = "exportForwardDeclarations"
|
|
||||||
const val KLIB_PROPERTY_INCLUDED_HEADERS = "includedHeaders"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstraction for getting access to the information stored inside of Kotlin/Native library.
|
|
||||||
*/
|
|
||||||
interface KonanLibrary {
|
|
||||||
|
|
||||||
val libraryName: String
|
|
||||||
val libraryFile: File
|
|
||||||
|
|
||||||
// Whether this library is default (provided by Kotlin/Native distribution)?
|
|
||||||
val isDefault: Boolean
|
|
||||||
|
|
||||||
// Properties:
|
|
||||||
val manifestProperties: Properties
|
|
||||||
val abiVersion: String
|
|
||||||
val linkerOpts: List<String>
|
|
||||||
|
|
||||||
// Paths:
|
|
||||||
val bitcodePaths: List<String>
|
|
||||||
val includedPaths: List<String>
|
|
||||||
|
|
||||||
val targetList: List<String>
|
|
||||||
|
|
||||||
val dataFlowGraph: ByteArray?
|
|
||||||
val moduleHeaderData: KonanProtoBuf.LinkDataLibrary
|
|
||||||
fun packageMetadataParts(fqName: String): Set<String>
|
|
||||||
fun packageMetadata(packageFqName: String, partName: String): KonanProtoBuf.LinkDataPackageFragment
|
|
||||||
}
|
|
||||||
|
|
||||||
val KonanLibrary.uniqueName
|
|
||||||
get() = manifestProperties.getProperty(KLIB_PROPERTY_UNIQUE_NAME)!!
|
|
||||||
|
|
||||||
val KonanLibrary.unresolvedDependencies: List<String>
|
|
||||||
get() = manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS)
|
|
||||||
|
|
||||||
val KonanLibrary.isInterop
|
|
||||||
get() = manifestProperties.getProperty(KLIB_PROPERTY_INTEROP) == "true"
|
|
||||||
|
|
||||||
val KonanLibrary.packageFqName
|
|
||||||
get() = manifestProperties.getProperty(KLIB_PROPERTY_PACKAGE)?.let { FqName(it) }
|
|
||||||
|
|
||||||
val KonanLibrary.exportForwardDeclarations
|
|
||||||
get() = manifestProperties.getProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS)
|
|
||||||
.split(' ').asSequence()
|
|
||||||
.map { it.trim() }
|
|
||||||
.filter { it.isNotEmpty() }
|
|
||||||
.map { FqName(it) }
|
|
||||||
.toList()
|
|
||||||
|
|
||||||
val KonanLibrary.includedHeaders
|
|
||||||
get() = manifestProperties.getProperty(KLIB_PROPERTY_INCLUDED_HEADERS).split(' ')
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This scheme describes the Kotlin/Native Library (KLIB) layout.
|
|
||||||
*/
|
|
||||||
interface KonanLibraryLayout {
|
|
||||||
|
|
||||||
val libraryName: String
|
|
||||||
val libDir: File
|
|
||||||
|
|
||||||
val source: KonanLibrarySource
|
|
||||||
|
|
||||||
// This is a default implementation. Can't make it an assignment.
|
|
||||||
val target: KonanTarget? get() = null
|
|
||||||
|
|
||||||
val manifestFile get() = File(libDir, KLIB_MANIFEST_FILE_NAME)
|
|
||||||
val resourcesDir get() = File(libDir, "resources")
|
|
||||||
|
|
||||||
val targetsDir get() = File(libDir, "targets")
|
|
||||||
val targetDir get() = File(targetsDir, target!!.visibleName)
|
|
||||||
|
|
||||||
val kotlinDir get() = File(targetDir, "kotlin")
|
|
||||||
val nativeDir get() = File(targetDir, "native")
|
|
||||||
val includedDir get() = File(targetDir, "included")
|
|
||||||
|
|
||||||
val linkdataDir get() = File(libDir, "linkdata")
|
|
||||||
val moduleHeaderFile get() = File(linkdataDir, KLIB_MODULE_METADATA_FILE_NAME)
|
|
||||||
val dataFlowGraphFile get() = File(linkdataDir, "module_data_flow_graph")
|
|
||||||
|
|
||||||
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 {
|
|
||||||
object KonanLibraryDir : KonanLibrarySource()
|
|
||||||
class KonanLibraryFile(val klibFile: File) : KonanLibrarySource()
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.file.file
|
|
||||||
import org.jetbrains.kotlin.konan.file.withMutableZipFileSystem
|
|
||||||
import org.jetbrains.kotlin.konan.library.impl.DefaultMetadataReaderImpl
|
|
||||||
import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl
|
|
||||||
import org.jetbrains.kotlin.konan.library.impl.zippedKonanLibraryChecks
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolver
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.impl.KonanLibraryResolverImpl
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
|
|
||||||
fun File.unpackZippedKonanLibraryTo(newDir: File) {
|
|
||||||
|
|
||||||
// First, run validity checks for the given KLIB file.
|
|
||||||
zippedKonanLibraryChecks(this)
|
|
||||||
|
|
||||||
if (newDir.exists) {
|
|
||||||
if (newDir.isDirectory)
|
|
||||||
newDir.deleteRecursively()
|
|
||||||
else
|
|
||||||
newDir.delete()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.withMutableZipFileSystem {
|
|
||||||
it.file("/").recursiveCopyTo(newDir)
|
|
||||||
}
|
|
||||||
check(newDir.exists) { "Could not unpack $this as $newDir." }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createKonanLibrary(
|
|
||||||
libraryFile: File,
|
|
||||||
currentAbiVersion: Int,
|
|
||||||
target: KonanTarget? = null,
|
|
||||||
isDefault: Boolean = false,
|
|
||||||
metadataReader: MetadataReader = DefaultMetadataReaderImpl
|
|
||||||
): KonanLibrary = KonanLibraryImpl(libraryFile, currentAbiVersion, target, isDefault, metadataReader)
|
|
||||||
|
|
||||||
fun SearchPathResolverWithTarget.libraryResolver(abiVersion: Int): KonanLibraryResolver =
|
|
||||||
KonanLibraryResolverImpl(this, abiVersion)
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
|
|
||||||
interface MetadataReader {
|
|
||||||
fun loadSerializedModule(libraryLayout: KonanLibraryLayout): KonanProtoBuf.LinkDataLibrary
|
|
||||||
fun loadSerializedPackageFragment(
|
|
||||||
libraryLayout: KonanLibraryLayout,
|
|
||||||
packageFqName: String,
|
|
||||||
partName: String
|
|
||||||
): KonanProtoBuf.LinkDataPackageFragment
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
|
|
||||||
interface SearchPathResolver {
|
|
||||||
val searchRoots: List<File>
|
|
||||||
fun resolve(givenPath: String): File
|
|
||||||
fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean): List<File>
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SearchPathResolverWithTarget : SearchPathResolver {
|
|
||||||
val target: KonanTarget
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
|
||||||
import org.jetbrains.kotlin.konan.library.MetadataReader
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.parsePackageFragment
|
|
||||||
|
|
||||||
object DefaultMetadataReaderImpl : MetadataReader {
|
|
||||||
|
|
||||||
override fun loadSerializedModule(libraryLayout: KonanLibraryLayout): KonanProtoBuf.LinkDataLibrary =
|
|
||||||
parseModuleHeader(libraryLayout.moduleHeaderFile.readBytes())
|
|
||||||
|
|
||||||
override fun loadSerializedPackageFragment(
|
|
||||||
libraryLayout: KonanLibraryLayout,
|
|
||||||
packageFqName: String,
|
|
||||||
partName: String
|
|
||||||
): KonanProtoBuf.LinkDataPackageFragment =
|
|
||||||
parsePackageFragment(
|
|
||||||
libraryLayout.packageFragmentFile(packageFqName, partName).readBytes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
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
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions
|
|
||||||
import org.jetbrains.kotlin.konan.util.substitute
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
|
|
||||||
internal class KonanLibraryImpl(
|
|
||||||
override val libraryFile: File,
|
|
||||||
private val currentAbiVersion: Int,
|
|
||||||
internal val target: KonanTarget?,
|
|
||||||
override val isDefault: Boolean,
|
|
||||||
private val metadataReader: MetadataReader
|
|
||||||
) : KonanLibrary {
|
|
||||||
|
|
||||||
// For the zipped libraries inPlace gives files from zip file system
|
|
||||||
// whereas realFiles extracts them to /tmp.
|
|
||||||
// For unzipped libraries inPlace and realFiles are the same
|
|
||||||
// providing files in the library directory.
|
|
||||||
|
|
||||||
private val layout = createKonanLibraryLayout(libraryFile, target)
|
|
||||||
|
|
||||||
override val libraryName: String by lazy { layout.inPlace { it.libraryName } }
|
|
||||||
|
|
||||||
override val manifestProperties: Properties by lazy {
|
|
||||||
val properties = layout.inPlace { it.manifestFile.loadProperties() }
|
|
||||||
if (target != null) substitute(properties, defaultTargetSubstitutions(target))
|
|
||||||
properties
|
|
||||||
}
|
|
||||||
|
|
||||||
override val abiVersion: String
|
|
||||||
get() {
|
|
||||||
val manifestAbiVersion = manifestProperties.getProperty(KLIB_PROPERTY_ABI_VERSION)
|
|
||||||
check(currentAbiVersion.toString() == manifestAbiVersion) {
|
|
||||||
"ABI version mismatch. Compiler expects: $currentAbiVersion, the library is $manifestAbiVersion"
|
|
||||||
}
|
|
||||||
return manifestAbiVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
override val linkerOpts: List<String>
|
|
||||||
get() = manifestProperties.propertyList(KLIB_PROPERTY_LINKED_OPTS, target!!.visibleName)
|
|
||||||
|
|
||||||
override val bitcodePaths: List<String>
|
|
||||||
get() = layout.realFiles { (it.kotlinDir.listFilesOrEmpty + it.nativeDir.listFilesOrEmpty).map { it.absolutePath } }
|
|
||||||
|
|
||||||
override val includedPaths: List<String>
|
|
||||||
get() = layout.realFiles { it.includedDir.listFilesOrEmpty.map { it.absolutePath } }
|
|
||||||
|
|
||||||
override val targetList by lazy { layout.inPlace { it.targetsDir.listFiles.map { it.name } } }
|
|
||||||
|
|
||||||
override val dataFlowGraph by lazy { layout.inPlace { it.dataFlowGraphFile.let { if (it.exists) it.readBytes() else null } } }
|
|
||||||
|
|
||||||
override val moduleHeaderData: KonanProtoBuf.LinkDataLibrary by lazy { layout.inPlace { metadataReader.loadSerializedModule(it) } }
|
|
||||||
|
|
||||||
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]"
|
|
||||||
}
|
|
||||||
-104
@@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
|
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION_WITH_DOT
|
|
||||||
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.target.KonanTarget
|
|
||||||
import java.nio.file.FileSystem
|
|
||||||
|
|
||||||
interface KonanLibraryLayoutImpl : KonanLibraryLayout {
|
|
||||||
fun <T> inPlace(action: (KonanLibraryLayout) -> T): T
|
|
||||||
fun <T> realFiles(action: (KonanLibraryLayout) -> T): T
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ZippedKonanLibraryLayout(
|
|
||||||
klibFile: File,
|
|
||||||
override val target: KonanTarget?
|
|
||||||
) : KonanLibraryLayoutImpl {
|
|
||||||
|
|
||||||
init {
|
|
||||||
zippedKonanLibraryChecks(klibFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val libraryName = klibFile.path.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT)
|
|
||||||
override val libDir: File = File("/")
|
|
||||||
override val source = KonanLibraryFile(klibFile)
|
|
||||||
|
|
||||||
override fun <T> realFiles(action: (KonanLibraryLayout) -> T) = action(FileExtractor(this))
|
|
||||||
|
|
||||||
override fun <T> inPlace(action: (KonanLibraryLayout) -> T) = source.klibFile.withZipFileSystem { zipFileSystem ->
|
|
||||||
action(DirectFromZip(this, zipFileSystem))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun zippedKonanLibraryChecks(klibFile: File) {
|
|
||||||
check(klibFile.exists) { "Could not find $klibFile." }
|
|
||||||
check(klibFile.isFile) { "Expected $klibFile to be a regular file." }
|
|
||||||
|
|
||||||
val extension = klibFile.extension
|
|
||||||
check(extension.isEmpty() || extension == KLIB_FILE_EXTENSION) { "Unexpected file extension: $extension" }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UnzippedKonanLibraryLayout(
|
|
||||||
override val libDir: File,
|
|
||||||
override val target: KonanTarget?
|
|
||||||
) : KonanLibraryLayoutImpl {
|
|
||||||
|
|
||||||
override val libraryName = libDir.path
|
|
||||||
override val source = KonanLibraryDir
|
|
||||||
|
|
||||||
override fun <T> inPlace(action: (KonanLibraryLayout) -> T) = action(this)
|
|
||||||
override fun <T> realFiles(action: (KonanLibraryLayout) -> T) = inPlace(action)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DirectFromZip(
|
|
||||||
zippedLayout: ZippedKonanLibraryLayout,
|
|
||||||
zipFileSystem: FileSystem
|
|
||||||
) : KonanLibraryLayout {
|
|
||||||
|
|
||||||
override val libraryName = zippedLayout.libraryName
|
|
||||||
override val libDir = zipFileSystem.file(zippedLayout.libDir)
|
|
||||||
override val source = zippedLayout.source
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class automatically extracts pieces of the library on first access. Use it if you need
|
|
||||||
* to pass extracted files to an external tool. Otherwise, stick to [DirectFromZip].
|
|
||||||
*/
|
|
||||||
private class FileExtractor(
|
|
||||||
val zippedLayout: ZippedKonanLibraryLayout
|
|
||||||
) : KonanLibraryLayout by zippedLayout {
|
|
||||||
|
|
||||||
override val manifestFile: File by lazy { extract(super.manifestFile) }
|
|
||||||
override val resourcesDir: File by lazy { extractDir(super.resourcesDir) }
|
|
||||||
override val includedDir: File by lazy { extractDir(super.includedDir) }
|
|
||||||
override val kotlinDir: File by lazy { extractDir(super.kotlinDir) }
|
|
||||||
override val nativeDir: File by lazy { extractDir(super.nativeDir) }
|
|
||||||
override val linkdataDir: File by lazy { extractDir(super.linkdataDir) }
|
|
||||||
|
|
||||||
fun extract(file: File): File = zippedLayout.source.klibFile.withZipFileSystem { zipFileSystem ->
|
|
||||||
val temporary = createTempFile(file.name)
|
|
||||||
zipFileSystem.file(file).copyTo(temporary)
|
|
||||||
temporary.deleteOnExit()
|
|
||||||
temporary
|
|
||||||
}
|
|
||||||
|
|
||||||
fun extractDir(directory: File): File = zippedLayout.source.klibFile.withZipFileSystem { zipFileSystem ->
|
|
||||||
val temporary = createTempDir(directory.name)
|
|
||||||
zipFileSystem.file(directory).recursiveCopyTo(temporary)
|
|
||||||
temporary.deleteOnExitRecursively()
|
|
||||||
temporary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun createKonanLibraryLayout(klib: File, target: KonanTarget? = null) =
|
|
||||||
if (klib.isFile) ZippedKonanLibraryLayout(klib, target) else UnzippedKonanLibraryLayout(klib, target)
|
|
||||||
|
|
||||||
+1
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.konan.library.lite
|
package org.jetbrains.kotlin.konan.library.lite
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.library.*
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
|
import org.jetbrains.kotlin.library.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.resolver
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.SearchPathResolverWithTarget
|
|
||||||
|
|
||||||
typealias DuplicatedLibraryLogger = (String) -> Unit
|
|
||||||
|
|
||||||
interface KonanLibraryResolver {
|
|
||||||
|
|
||||||
val searchPathResolver: SearchPathResolverWithTarget
|
|
||||||
val abiVersion: Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the list of Kotlin/Native library names, ABI version and other parameters
|
|
||||||
* resolves libraries and evaluates dependencies between them.
|
|
||||||
*/
|
|
||||||
fun resolveWithDependencies(
|
|
||||||
libraryNames: List<String>,
|
|
||||||
noStdLib: Boolean = false,
|
|
||||||
noDefaultLibs: Boolean = false,
|
|
||||||
logger: DuplicatedLibraryLogger? = null
|
|
||||||
): KonanLibraryResolveResult
|
|
||||||
}
|
|
||||||
|
|
||||||
interface KonanLibraryResolveResult {
|
|
||||||
|
|
||||||
fun filterRoots(predicate: (KonanResolvedLibrary) -> Boolean): KonanLibraryResolveResult
|
|
||||||
|
|
||||||
fun getFullList(order: LibraryOrder? = null): List<KonanLibrary>
|
|
||||||
|
|
||||||
fun forEach(action: (KonanLibrary, PackageAccessedHandler) -> Unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typealias LibraryOrder = (Iterable<KonanResolvedLibrary>) -> List<KonanResolvedLibrary>
|
|
||||||
|
|
||||||
val TopologicalLibraryOrder: LibraryOrder = { input ->
|
|
||||||
val sorted = mutableListOf<KonanResolvedLibrary>()
|
|
||||||
val visited = mutableSetOf<KonanResolvedLibrary>()
|
|
||||||
val tempMarks = mutableSetOf<KonanResolvedLibrary>()
|
|
||||||
|
|
||||||
fun visit(node: KonanResolvedLibrary, result: MutableList<KonanResolvedLibrary>) {
|
|
||||||
if (visited.contains(node)) return
|
|
||||||
if (tempMarks.contains(node)) error("Cyclic dependency in library graph.")
|
|
||||||
tempMarks.add(node)
|
|
||||||
node.resolvedDependencies.forEach {
|
|
||||||
visit(it, result)
|
|
||||||
}
|
|
||||||
visited.add(node)
|
|
||||||
result += node
|
|
||||||
}
|
|
||||||
|
|
||||||
input.forEach next@{
|
|
||||||
if (visited.contains(it)) return@next
|
|
||||||
visit(it, sorted)
|
|
||||||
}
|
|
||||||
|
|
||||||
sorted
|
|
||||||
}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.resolver
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
interface PackageAccessedHandler {
|
|
||||||
|
|
||||||
fun markPackageAccessed(fqName: FqName)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A [KonanLibrary] wrapper that is used for resolving library's dependencies.
|
|
||||||
*/
|
|
||||||
interface KonanResolvedLibrary: PackageAccessedHandler {
|
|
||||||
|
|
||||||
// The library itself.
|
|
||||||
val library: KonanLibrary
|
|
||||||
|
|
||||||
// Dependencies on other libraries.
|
|
||||||
val resolvedDependencies: List<KonanResolvedLibrary>
|
|
||||||
|
|
||||||
// Whether it is needed to linker.
|
|
||||||
val isNeededForLink: Boolean
|
|
||||||
|
|
||||||
// Is provided by the distribution?
|
|
||||||
val isDefault: Boolean
|
|
||||||
}
|
|
||||||
-142
@@ -1,142 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.resolver.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.SearchPathResolverWithTarget
|
|
||||||
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.*
|
|
||||||
import org.jetbrains.kotlin.konan.library.unresolvedDependencies
|
|
||||||
|
|
||||||
internal class KonanLibraryResolverImpl(
|
|
||||||
override val searchPathResolver: SearchPathResolverWithTarget,
|
|
||||||
override val abiVersion: Int
|
|
||||||
) : KonanLibraryResolver {
|
|
||||||
|
|
||||||
override fun resolveWithDependencies(
|
|
||||||
libraryNames: List<String>,
|
|
||||||
noStdLib: Boolean,
|
|
||||||
noDefaultLibs: Boolean,
|
|
||||||
logger: DuplicatedLibraryLogger?
|
|
||||||
) = findLibraries(libraryNames, noStdLib, noDefaultLibs)
|
|
||||||
.leaveDistinct(logger)
|
|
||||||
.resolveDependencies()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of libraries based on [libraryNames], [noStdLib] and [noDefaultLibs] criteria.
|
|
||||||
*
|
|
||||||
* This method does not return any libraries that might be available via transitive dependencies
|
|
||||||
* from the original library set (root set).
|
|
||||||
*/
|
|
||||||
private fun findLibraries(
|
|
||||||
libraryNames: List<String>,
|
|
||||||
noStdLib: Boolean,
|
|
||||||
noDefaultLibs: Boolean
|
|
||||||
): List<KonanLibrary> {
|
|
||||||
|
|
||||||
val userProvidedLibraries = libraryNames.asSequence()
|
|
||||||
.map { searchPathResolver.resolve(it) }
|
|
||||||
.map { createKonanLibrary(it, abiVersion, searchPathResolver.target) }
|
|
||||||
.toList()
|
|
||||||
|
|
||||||
val defaultLibraries = searchPathResolver.defaultLinks(noStdLib, noDefaultLibs).map {
|
|
||||||
createKonanLibrary(it, abiVersion, searchPathResolver.target, isDefault = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the user provided ones appear first, so that
|
|
||||||
// they have precedence over defaults when duplicates are eliminated.
|
|
||||||
return userProvidedLibraries + defaultLibraries
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Leaves only distinct libraries (by absolute path), warns on duplicated paths.
|
|
||||||
*/
|
|
||||||
private fun List<KonanLibrary>.leaveDistinct(logger: DuplicatedLibraryLogger?) =
|
|
||||||
this.groupBy { it.libraryFile.absolutePath }.let { groupedByAbsolutePath ->
|
|
||||||
warnOnLibraryDuplicates(groupedByAbsolutePath.filter { it.value.size > 1 }.keys, logger)
|
|
||||||
groupedByAbsolutePath.map { it.value.first() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun warnOnLibraryDuplicates(duplicatedPaths: Iterable<String>, logger: DuplicatedLibraryLogger?) {
|
|
||||||
if (logger == null) return
|
|
||||||
duplicatedPaths.forEach { logger("library included more than once: $it") }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the list of root libraries does the following:
|
|
||||||
*
|
|
||||||
* 1. Evaluates other libraries that are available via transitive dependencies.
|
|
||||||
* 2. Wraps each [KonanLibrary] into a [KonanResolvedLibrary] with information about dependencies on other libraries.
|
|
||||||
* 3. Creates resulting [KonanLibraryResolveResult] object.
|
|
||||||
*/
|
|
||||||
private fun List<KonanLibrary>.resolveDependencies(): KonanLibraryResolveResult {
|
|
||||||
|
|
||||||
val rootLibraries = this.map { KonanResolvedLibraryImpl(it) }
|
|
||||||
|
|
||||||
// As far as the list of root libraries is known from the very beginning, the result can be
|
|
||||||
// constructed from the very beginning as well.
|
|
||||||
val result = KonanLibraryResolverResultImpl(rootLibraries)
|
|
||||||
|
|
||||||
val cache = mutableMapOf<File, KonanResolvedLibrary>()
|
|
||||||
cache.putAll(rootLibraries.map { it.library.libraryFile.absoluteFile to it })
|
|
||||||
|
|
||||||
var newDependencies = rootLibraries
|
|
||||||
do {
|
|
||||||
newDependencies = newDependencies.map { library: KonanResolvedLibraryImpl ->
|
|
||||||
library.library.unresolvedDependencies.asSequence()
|
|
||||||
.map { searchPathResolver.resolve(it).absoluteFile }
|
|
||||||
.mapNotNull {
|
|
||||||
if (it in cache) {
|
|
||||||
library.addDependency(cache[it]!!)
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
val newLibrary = KonanResolvedLibraryImpl(createKonanLibrary(it, abiVersion, searchPathResolver.target))
|
|
||||||
cache[it] = newLibrary
|
|
||||||
library.addDependency(newLibrary)
|
|
||||||
newLibrary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.toList()
|
|
||||||
}.flatten()
|
|
||||||
} while (newDependencies.isNotEmpty())
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class KonanLibraryResolverResultImpl(
|
|
||||||
private val roots: List<KonanResolvedLibrary>
|
|
||||||
) : KonanLibraryResolveResult {
|
|
||||||
|
|
||||||
private val all: List<KonanResolvedLibrary> by lazy {
|
|
||||||
val result = mutableSetOf<KonanResolvedLibrary>().also { it.addAll(roots) }
|
|
||||||
|
|
||||||
var newDependencies = result.toList()
|
|
||||||
do {
|
|
||||||
newDependencies = newDependencies
|
|
||||||
.map { it -> it.resolvedDependencies }.flatten()
|
|
||||||
.filter { it !in result }
|
|
||||||
result.addAll(newDependencies)
|
|
||||||
} while (newDependencies.isNotEmpty())
|
|
||||||
|
|
||||||
result.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun filterRoots(predicate: (KonanResolvedLibrary) -> Boolean) =
|
|
||||||
KonanLibraryResolverResultImpl(roots.filter(predicate))
|
|
||||||
|
|
||||||
override fun getFullList(order: LibraryOrder?) = (order?.invoke(all) ?: all).asPlain()
|
|
||||||
|
|
||||||
override fun forEach(action: (KonanLibrary, PackageAccessedHandler) -> Unit) {
|
|
||||||
all.forEach { action(it.library, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun List<KonanResolvedLibrary>.asPlain() = map { it.library }
|
|
||||||
|
|
||||||
override fun toString() = "roots=$roots, all=$all"
|
|
||||||
}
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.library.resolver.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
|
|
||||||
internal class KonanResolvedLibraryImpl(
|
|
||||||
override val library: KonanLibrary
|
|
||||||
) : KonanResolvedLibrary {
|
|
||||||
|
|
||||||
private val _resolvedDependencies = mutableListOf<KonanResolvedLibrary>()
|
|
||||||
private val _emptyPackages by lazy { library.moduleHeaderData.emptyPackageList }
|
|
||||||
|
|
||||||
override val resolvedDependencies: List<KonanResolvedLibrary>
|
|
||||||
get() = _resolvedDependencies
|
|
||||||
|
|
||||||
internal fun addDependency(resolvedLibrary: KonanResolvedLibrary) = _resolvedDependencies.add(resolvedLibrary)
|
|
||||||
|
|
||||||
override var isNeededForLink: Boolean = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
override val isDefault: Boolean
|
|
||||||
get() = library.isDefault
|
|
||||||
|
|
||||||
override fun markPackageAccessed(fqName: FqName) {
|
|
||||||
if (!isNeededForLink // fast path
|
|
||||||
&& !_emptyPackages.contains(fqName.asString())
|
|
||||||
) {
|
|
||||||
isNeededForLink = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString() = "library=$library, dependsOn=${_resolvedDependencies.joinToString { it.library.toString() }}"
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.konan.util
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.impl.KonanModuleDescriptorFactoryImpl
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedModuleDescriptorFactory
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedPackageFragmentsFactory
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptorsFactory
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.impl.KonanDeserializedModuleDescriptorFactoryImpl
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.impl.KonanDeserializedPackageFragmentsFactoryImpl
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.impl.KonanResolvedModuleDescriptorsFactoryImpl
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default Kotlin/Native factories.
|
|
||||||
*/
|
|
||||||
object KonanFactories {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default [KonanModuleDescriptorFactory] factory instance.
|
|
||||||
*/
|
|
||||||
val DefaultDescriptorFactory: KonanModuleDescriptorFactory = KonanModuleDescriptorFactoryImpl
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default [KonanDeserializedPackageFragmentsFactory] factory instance.
|
|
||||||
*/
|
|
||||||
val DefaultPackageFragmentsFactory: KonanDeserializedPackageFragmentsFactory =
|
|
||||||
KonanDeserializedPackageFragmentsFactoryImpl
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default [KonanDeserializedModuleDescriptorFactory] factory instance.
|
|
||||||
*/
|
|
||||||
val DefaultDeserializedDescriptorFactory: KonanDeserializedModuleDescriptorFactory =
|
|
||||||
createDefaultKonanDeserializedModuleDescriptorFactory(
|
|
||||||
DefaultDescriptorFactory, DefaultPackageFragmentsFactory
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default [KonanResolvedModuleDescriptorsFactory] factory instance.
|
|
||||||
*/
|
|
||||||
val DefaultResolvedDescriptorsFactory: KonanResolvedModuleDescriptorsFactory =
|
|
||||||
createDefaultKonanResolvedModuleDescriptorsFactory(DefaultDeserializedDescriptorFactory)
|
|
||||||
|
|
||||||
fun createDefaultKonanDeserializedModuleDescriptorFactory(
|
|
||||||
descriptorFactory: KonanModuleDescriptorFactory,
|
|
||||||
packageFragmentsFactory: KonanDeserializedPackageFragmentsFactory
|
|
||||||
): KonanDeserializedModuleDescriptorFactory =
|
|
||||||
KonanDeserializedModuleDescriptorFactoryImpl(descriptorFactory, packageFragmentsFactory)
|
|
||||||
|
|
||||||
fun createDefaultKonanResolvedModuleDescriptorsFactory(
|
|
||||||
moduleDescriptorFactory: KonanDeserializedModuleDescriptorFactory
|
|
||||||
): KonanResolvedModuleDescriptorsFactory = KonanResolvedModuleDescriptorsFactoryImpl(moduleDescriptorFactory)
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
-14
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
|
|
||||||
fun parsePackageFragment(packageMetadata: ByteArray): KonanProtoBuf.LinkDataPackageFragment =
|
|
||||||
KonanProtoBuf.LinkDataPackageFragment.parseFrom(packageMetadata, KonanSerializerProtocol.extensionRegistry)
|
|
||||||
|
|
||||||
fun parseModuleHeader(libraryMetadata: ByteArray): KonanProtoBuf.LinkDataLibrary =
|
|
||||||
KonanProtoBuf.LinkDataLibrary.parseFrom(libraryMetadata, KonanSerializerProtocol.extensionRegistry)
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
interface KonanDeserializedModuleDescriptorFactory {
|
|
||||||
|
|
||||||
val descriptorFactory: KonanModuleDescriptorFactory
|
|
||||||
val packageFragmentsFactory: KonanDeserializedPackageFragmentsFactory
|
|
||||||
|
|
||||||
fun createDescriptor(
|
|
||||||
library: KonanLibrary,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler? = null,
|
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
|
||||||
): ModuleDescriptorImpl
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Please use this method with care: As far as it creates an instance of [KotlinBuiltIns] it should be
|
|
||||||
* normally used for creation of the very first (e.g. "stdlib") module in the set of created modules.
|
|
||||||
*/
|
|
||||||
fun createDescriptorAndNewBuiltIns(
|
|
||||||
library: KonanLibrary,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler? = null,
|
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
|
||||||
): ModuleDescriptorImpl
|
|
||||||
}
|
|
||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
interface KonanDeserializedPackageFragmentsFactory {
|
|
||||||
|
|
||||||
fun createDeserializedPackageFragments(
|
|
||||||
library: KonanLibrary,
|
|
||||||
packageFragmentNames: List<String>,
|
|
||||||
moduleDescriptor: ModuleDescriptor,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
storageManager: StorageManager
|
|
||||||
): List<KonanPackageFragment>
|
|
||||||
|
|
||||||
fun createSyntheticPackageFragments(
|
|
||||||
library: KonanLibrary,
|
|
||||||
deserializedPackageFragments: List<KonanPackageFragment>,
|
|
||||||
moduleDescriptor: ModuleDescriptor
|
|
||||||
): List<PackageFragmentDescriptor>
|
|
||||||
|
|
||||||
fun createPackageFragmentProvider(
|
|
||||||
library: KonanLibrary,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
packageFragmentNames: List<String>,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
moduleDescriptor: ModuleDescriptor,
|
|
||||||
configuration: DeserializationConfiguration
|
|
||||||
): PackageFragmentProvider
|
|
||||||
|
|
||||||
fun createForwardDeclarationHackPackagePartProvider(
|
|
||||||
storageManager: StorageManager,
|
|
||||||
module: ModuleDescriptorImpl
|
|
||||||
): PackageFragmentProviderImpl
|
|
||||||
}
|
|
||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
interface KonanResolvedModuleDescriptorsFactory {
|
|
||||||
|
|
||||||
val moduleDescriptorFactory: KonanDeserializedModuleDescriptorFactory
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the [resolvedLibraries] creates the list of [ModuleDescriptorImpl]s with properly installed
|
|
||||||
* inter-dependencies. The result of this method is returned in a form of [KonanResolvedModuleDescriptors] instance.
|
|
||||||
*
|
|
||||||
* Please use this method with care: Unless this method accepts `null` for [builtIns], it is not recommended to
|
|
||||||
* invoke it this way. If you are compiling a source module, please supply the non-null [builtIns] from the
|
|
||||||
* source module, so that all modules created in your compilation session will share the same built-ins instance.
|
|
||||||
*
|
|
||||||
* Otherwise (if `null` was supplied), a new instance of [KotlinBuiltIns] will be created. The created built-ins
|
|
||||||
* instance will be shared by all modules created in this method. But this instance will have no connection
|
|
||||||
* with probably existing built-ins instance of your source module(s).
|
|
||||||
*/
|
|
||||||
fun createResolved(
|
|
||||||
resolvedLibraries: KonanLibraryResolveResult,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns?,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
customAction: ((KonanLibrary, ModuleDescriptorImpl) -> Unit)? = null,
|
|
||||||
customCapabilitiesGenerator: ((KonanLibrary) -> Map<ModuleDescriptor.Capability<*>, Any?>)? = null
|
|
||||||
): KonanResolvedModuleDescriptors
|
|
||||||
}
|
|
||||||
|
|
||||||
class KonanResolvedModuleDescriptors(
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of modules each representing an individual Kotlin/Native library. All modules
|
|
||||||
* in this list have properly installed dependencies, i.e. module has all necessary dependencies
|
|
||||||
* on other modules plus a dependency on the [forwardDeclarationsModule].
|
|
||||||
*/
|
|
||||||
val resolvedDescriptors: List<ModuleDescriptorImpl>,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a module which "contains" forward declarations.
|
|
||||||
* Note: this module should be unique per compilation and should always be the last dependency of any module.
|
|
||||||
*/
|
|
||||||
val forwardDeclarationsModule: ModuleDescriptorImpl
|
|
||||||
)
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
|
||||||
|
|
||||||
object KonanSerializerProtocol : SerializerExtensionProtocol(
|
|
||||||
ExtensionRegistryLite.newInstance().apply(KonanProtoBuf::registerAllExtensions),
|
|
||||||
KonanProtoBuf.packageFqName,
|
|
||||||
KonanProtoBuf.constructorAnnotation,
|
|
||||||
KonanProtoBuf.classAnnotation,
|
|
||||||
KonanProtoBuf.functionAnnotation,
|
|
||||||
KonanProtoBuf.propertyAnnotation,
|
|
||||||
KonanProtoBuf.propertyGetterAnnotation,
|
|
||||||
KonanProtoBuf.propertySetterAnnotation,
|
|
||||||
KonanProtoBuf.enumEntryAnnotation,
|
|
||||||
KonanProtoBuf.compileTimeValue,
|
|
||||||
KonanProtoBuf.parameterAnnotation,
|
|
||||||
KonanProtoBuf.typeAnnotation,
|
|
||||||
KonanProtoBuf.typeParameterAnnotation
|
|
||||||
)
|
|
||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedModuleDescriptorFactory
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedPackageFragmentsFactory
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
|
|
||||||
internal class KonanDeserializedModuleDescriptorFactoryImpl(
|
|
||||||
override val descriptorFactory: KonanModuleDescriptorFactory,
|
|
||||||
override val packageFragmentsFactory: KonanDeserializedPackageFragmentsFactory
|
|
||||||
) : KonanDeserializedModuleDescriptorFactory {
|
|
||||||
|
|
||||||
override fun createDescriptor(
|
|
||||||
library: KonanLibrary,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
|
||||||
) = createDescriptorOptionalBuiltIns(
|
|
||||||
library,
|
|
||||||
languageVersionSettings,
|
|
||||||
storageManager,
|
|
||||||
builtIns,
|
|
||||||
packageAccessedHandler,
|
|
||||||
customCapabilities
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun createDescriptorAndNewBuiltIns(
|
|
||||||
library: KonanLibrary,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
|
||||||
) = createDescriptorOptionalBuiltIns(library, languageVersionSettings, storageManager, null, packageAccessedHandler, customCapabilities)
|
|
||||||
|
|
||||||
private fun createDescriptorOptionalBuiltIns(
|
|
||||||
library: KonanLibrary,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns?,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
|
||||||
): ModuleDescriptorImpl {
|
|
||||||
|
|
||||||
val libraryProto = library.moduleHeaderData
|
|
||||||
|
|
||||||
val moduleName = Name.special(libraryProto.moduleName)
|
|
||||||
val moduleOrigin = DeserializedKonanModuleOrigin(library)
|
|
||||||
|
|
||||||
val moduleDescriptor = if (builtIns != null)
|
|
||||||
descriptorFactory.createDescriptor(moduleName, storageManager, builtIns, moduleOrigin, customCapabilities)
|
|
||||||
else
|
|
||||||
descriptorFactory.createDescriptorAndNewBuiltIns(moduleName, storageManager, moduleOrigin, customCapabilities)
|
|
||||||
|
|
||||||
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
|
|
||||||
|
|
||||||
val provider = packageFragmentsFactory.createPackageFragmentProvider(
|
|
||||||
library,
|
|
||||||
packageAccessedHandler,
|
|
||||||
libraryProto.packageFragmentNameList,
|
|
||||||
storageManager,
|
|
||||||
moduleDescriptor,
|
|
||||||
deserializationConfiguration
|
|
||||||
)
|
|
||||||
|
|
||||||
moduleDescriptor.initialize(provider)
|
|
||||||
|
|
||||||
return moduleDescriptor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-144
@@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.serialization.konan.impl
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleOrigin
|
|
||||||
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
|
|
||||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
|
||||||
import org.jetbrains.kotlin.konan.util.profile
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedModuleDescriptorFactory
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptors
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptorsFactory
|
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
import org.jetbrains.kotlin.storage.getValue
|
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
|
||||||
|
|
||||||
class KonanResolvedModuleDescriptorsFactoryImpl(
|
|
||||||
override val moduleDescriptorFactory: KonanDeserializedModuleDescriptorFactory
|
|
||||||
) : KonanResolvedModuleDescriptorsFactory {
|
|
||||||
|
|
||||||
override fun createResolved(
|
|
||||||
resolvedLibraries: KonanLibraryResolveResult,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns?,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
customAction: ((KonanLibrary, ModuleDescriptorImpl) -> Unit)?,
|
|
||||||
customCapabilitiesGenerator: ((KonanLibrary) -> Map<ModuleDescriptor.Capability<*>, Any?>)?
|
|
||||||
): KonanResolvedModuleDescriptors {
|
|
||||||
|
|
||||||
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
|
|
||||||
@Suppress("NAME_SHADOWING")
|
|
||||||
var builtIns = builtIns
|
|
||||||
|
|
||||||
// Build module descriptors.
|
|
||||||
resolvedLibraries.forEach { library, packageAccessedHandler ->
|
|
||||||
profile("Loading ${library.libraryName}") {
|
|
||||||
|
|
||||||
val customCapabilities = customCapabilitiesGenerator?.invoke(library) ?: emptyMap()
|
|
||||||
|
|
||||||
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
|
|
||||||
val moduleDescriptor = createDescriptorOptionalBuiltsIns(
|
|
||||||
library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler, customCapabilities
|
|
||||||
)
|
|
||||||
builtIns = moduleDescriptor.builtIns
|
|
||||||
moduleDescriptors.add(moduleDescriptor)
|
|
||||||
|
|
||||||
customAction?.invoke(library, moduleDescriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val forwardDeclarationsModule = createForwardDeclarationsModule(builtIns, storageManager)
|
|
||||||
|
|
||||||
// Set inter-dependencies between module descriptors, add forwarding declarations module.
|
|
||||||
for (module in moduleDescriptors) {
|
|
||||||
// Yes, just to all of them.
|
|
||||||
module.setDependencies(moduleDescriptors + forwardDeclarationsModule)
|
|
||||||
}
|
|
||||||
|
|
||||||
return KonanResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createForwardDeclarationsModule(
|
|
||||||
builtIns: KotlinBuiltIns?,
|
|
||||||
storageManager: StorageManager
|
|
||||||
): ModuleDescriptorImpl {
|
|
||||||
|
|
||||||
val name = Name.special("<forward declarations>")
|
|
||||||
val module = createDescriptorOptionalBuiltsIns(name, storageManager, builtIns, SyntheticModulesOrigin)
|
|
||||||
|
|
||||||
val packageFragmentProvider =
|
|
||||||
moduleDescriptorFactory.packageFragmentsFactory.createForwardDeclarationHackPackagePartProvider(storageManager, module)
|
|
||||||
|
|
||||||
module.initialize(packageFragmentProvider)
|
|
||||||
module.setDependencies(module)
|
|
||||||
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createDescriptorOptionalBuiltsIns(
|
|
||||||
name: Name,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns?,
|
|
||||||
moduleOrigin: KonanModuleOrigin
|
|
||||||
) = if (builtIns != null)
|
|
||||||
moduleDescriptorFactory.descriptorFactory.createDescriptor(name, storageManager, builtIns, moduleOrigin)
|
|
||||||
else
|
|
||||||
moduleDescriptorFactory.descriptorFactory.createDescriptorAndNewBuiltIns(name, storageManager, moduleOrigin)
|
|
||||||
|
|
||||||
private fun createDescriptorOptionalBuiltsIns(
|
|
||||||
library: KonanLibrary,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
storageManager: StorageManager,
|
|
||||||
builtIns: KotlinBuiltIns?,
|
|
||||||
packageAccessedHandler: PackageAccessedHandler?,
|
|
||||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
|
||||||
) = if (builtIns != null)
|
|
||||||
moduleDescriptorFactory.createDescriptor(
|
|
||||||
library,
|
|
||||||
languageVersionSettings,
|
|
||||||
storageManager,
|
|
||||||
builtIns,
|
|
||||||
packageAccessedHandler,
|
|
||||||
customCapabilities
|
|
||||||
)
|
|
||||||
else
|
|
||||||
moduleDescriptorFactory.createDescriptorAndNewBuiltIns(
|
|
||||||
library,
|
|
||||||
languageVersionSettings,
|
|
||||||
storageManager,
|
|
||||||
packageAccessedHandler,
|
|
||||||
customCapabilities
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
|
|
||||||
internal object ForwardDeclarationsFqNames {
|
|
||||||
|
|
||||||
val packageName = FqName("kotlinx.cinterop")
|
|
||||||
|
|
||||||
val cNames = FqName("cnames")
|
|
||||||
val cNamesStructs = cNames.child(Name.identifier("structs"))
|
|
||||||
|
|
||||||
val objCNames = FqName("objcnames")
|
|
||||||
val objCNamesClasses = objCNames.child(Name.identifier("classes"))
|
|
||||||
val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
|
|
||||||
}
|
|
||||||
@@ -25,6 +25,7 @@ include ":kotlin-build-common",
|
|||||||
":compiler:util",
|
":compiler:util",
|
||||||
":kotlin-util-io",
|
":kotlin-util-io",
|
||||||
":kotlin-util-klib",
|
":kotlin-util-klib",
|
||||||
|
":kotlin-util-klib-metadata",
|
||||||
":daemon-common",
|
":daemon-common",
|
||||||
":daemon-common-new",
|
":daemon-common-new",
|
||||||
":kotlin-daemon",
|
":kotlin-daemon",
|
||||||
@@ -336,6 +337,7 @@ project(':compiler:ir.serialization.common').projectDir = "$rootDir/compiler/ir/
|
|||||||
project(':compiler:ir.serialization.js').projectDir = "$rootDir/compiler/ir/serialization.js" as File
|
project(':compiler:ir.serialization.js').projectDir = "$rootDir/compiler/ir/serialization.js" as File
|
||||||
project(':kotlin-util-io').projectDir = "$rootDir/compiler/util-io" as File
|
project(':kotlin-util-io').projectDir = "$rootDir/compiler/util-io" as File
|
||||||
project(':kotlin-util-klib').projectDir = "$rootDir/compiler/util-klib" as File
|
project(':kotlin-util-klib').projectDir = "$rootDir/compiler/util-klib" as File
|
||||||
|
project(':kotlin-util-klib-metadata').projectDir = "$rootDir/compiler/util-klib-metadata" as File
|
||||||
project(':kotlin-native:kotlin-native-utils').projectDir = "$rootDir/konan/utils" as File
|
project(':kotlin-native:kotlin-native-utils').projectDir = "$rootDir/konan/utils" as File
|
||||||
project(':kotlin-native:kotlin-native-library-reader').projectDir = "$rootDir/konan/library-reader" as File
|
project(':kotlin-native:kotlin-native-library-reader').projectDir = "$rootDir/konan/library-reader" as File
|
||||||
project(':kotlin-native:commonizer').projectDir = "$rootDir/konan/commonizer" as File
|
project(':kotlin-native:commonizer').projectDir = "$rootDir/konan/commonizer" as File
|
||||||
|
|||||||
Reference in New Issue
Block a user