Changed KonanProtoBuf to KlibMetadataProtoBuf

This commit is contained in:
Alexander Gorshenev
2019-09-06 14:12:13 +03:00
committed by alexander-gorshenev
parent d201beaf27
commit 445eedd378
65 changed files with 176 additions and 3861 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.cli.bc
import com.intellij.openapi.Disposable
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
@@ -24,15 +25,14 @@ import org.jetbrains.kotlin.konan.CURRENT
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.util.*
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.util.profile
import org.jetbrains.kotlin.utils.KotlinPaths
import org.jetbrains.kotlin.serialization.konan.KonanMetadataVersion
private class K2NativeCompilerPerformanceManager: CommonCompilerPerformanceManager("Kotlin to Native Compiler")
class K2Native : CLICompiler<K2NativeCompilerArguments>() {
override fun createMetadataVersion(versionArray: IntArray): BinaryVersion = KonanMetadataVersion(*versionArray)
override fun createMetadataVersion(versionArray: IntArray): BinaryVersion = KlibMetadataVersion(*versionArray)
override val performanceManager:CommonCompilerPerformanceManager by lazy {
K2NativeCompilerPerformanceManager()
@@ -67,7 +67,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
/* Set default version of metadata version */
val metadataVersionString = arguments.metadataVersion
if (metadataVersionString == null) {
configuration.put(CommonConfigurationKeys.METADATA_VERSION, KonanMetadataVersion.INSTANCE)
configuration.put(CommonConfigurationKeys.METADATA_VERSION, KlibMetadataVersion.INSTANCE)
}
try {
@@ -222,7 +222,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
companion object {
@JvmStatic fun main(args: Array<String>) {
profile("Total compiler main()") {
CLITool.doMain(K2Native(), args)
doMain(K2Native(), args)
}
}
}
@@ -5,18 +5,15 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
import org.jetbrains.kotlin.descriptors.konan.konanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.*
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.SearchPathResolver
import org.jetbrains.kotlin.konan.library.isInterop
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
import org.jetbrains.kotlin.library.SearchPathResolver
import org.jetbrains.kotlin.library.isInterop
import org.jetbrains.kotlin.library.toUnresolvedLibraries
internal fun Context.getExportedDependencies(): List<ModuleDescriptor> = getDescriptorsFromLibraries((config.exportedLibraries + config.includedLibraries).toSet())
@@ -24,17 +21,17 @@ internal fun Context.getIncludedLibraryDescriptors(): List<ModuleDescriptor> = g
private fun Context.getDescriptorsFromLibraries(libraries: Set<KonanLibrary>) =
moduleDescriptor.allDependencyModules.filter {
when (val origin = it.konanModuleOrigin) {
CurrentKonanModuleOrigin, SyntheticModulesOrigin -> false
is DeserializedKonanModuleOrigin -> origin.library in libraries
when (val origin = it.klibModuleOrigin) {
CurrentKlibModuleOrigin, SyntheticModulesOrigin -> false
is DeserializedKlibModuleOrigin -> origin.library in libraries
}
}
internal fun getExportedLibraries(
configuration: CompilerConfiguration,
resolvedLibraries: KonanLibraryResolveResult,
resolver: SearchPathResolver,
report: Boolean
configuration: CompilerConfiguration,
resolvedLibraries: KotlinLibraryResolveResult,
resolver: SearchPathResolver<KonanLibrary>,
report: Boolean
): List<KonanLibrary> = getFeaturedLibraries(
configuration.getList(KonanConfigKeys.EXPORTED_LIBRARIES),
resolvedLibraries,
@@ -46,7 +43,7 @@ internal fun getExportedLibraries(
internal fun getIncludedLibraries(
includedLibraryFiles: List<File>,
configuration: CompilerConfiguration,
resolvedLibraries: KonanLibraryResolveResult
resolvedLibraries: KotlinLibraryResolveResult
): List<KonanLibrary> = getFeaturedLibraries(
includedLibraryFiles.toSet(),
resolvedLibraries,
@@ -56,8 +53,8 @@ internal fun getIncludedLibraries(
internal fun getCoveredLibraries(
configuration: CompilerConfiguration,
resolvedLibraries: KonanLibraryResolveResult,
resolver: SearchPathResolver
resolvedLibraries: KotlinLibraryResolveResult,
resolver: SearchPathResolver<KonanLibrary>
): List<KonanLibrary> = getFeaturedLibraries(
configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER),
resolvedLibraries,
@@ -147,8 +144,8 @@ private sealed class FeaturedLibrariesReporter {
private fun getFeaturedLibraries(
featuredLibraries: List<String>,
resolvedLibraries: KonanLibraryResolveResult,
resolver: SearchPathResolver,
resolvedLibraries: KotlinLibraryResolveResult,
resolver: SearchPathResolver<KonanLibrary>,
reporter: FeaturedLibrariesReporter,
allowDefaultLibs: Boolean
) = getFeaturedLibraries(
@@ -160,13 +157,13 @@ private fun getFeaturedLibraries(
private fun getFeaturedLibraries(
featuredLibraryFiles: Set<File>,
resolvedLibraries: KonanLibraryResolveResult,
resolvedLibraries: KotlinLibraryResolveResult,
reporter: FeaturedLibrariesReporter,
allowDefaultLibs: Boolean
) : List<KonanLibrary> {
val remainingFeaturedLibraries = featuredLibraryFiles.toMutableSet()
val result = mutableListOf<KonanLibrary>()
val libraries = resolvedLibraries.getFullList(null)
val libraries = resolvedLibraries.getFullList(null) as List<KonanLibrary>
for (library in libraries) {
val libraryFile = library.libraryFile
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.konan
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
@@ -18,15 +19,13 @@ import org.jetbrains.kotlin.konan.*
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.defaultResolver
import org.jetbrains.kotlin.konan.library.libraryResolver
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.konan.util.Logger
import org.jetbrains.kotlin.util.Logger
import kotlin.system.exitProcess
import org.jetbrains.kotlin.library.toUnresolvedLibraries
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.library.isInterop
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
import org.jetbrains.kotlin.library.UnresolvedLibrary
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
@@ -148,7 +147,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.")
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder)
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder) as List<KonanLibrary>
}
internal val runtimeNativeLibraries: List<String> = mutableListOf<String>().apply {
@@ -4,9 +4,9 @@
*/
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.konan.util.prefixBaseNameIfNot
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.konan.util.suffixIfNot
import org.jetbrains.kotlin.util.prefixBaseNameIfNot
import org.jetbrains.kotlin.util.removeSuffixIfPresent
import org.jetbrains.kotlin.util.suffixIfNot
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
@@ -16,18 +17,17 @@ import org.jetbrains.kotlin.context.MutableModuleContextImpl
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
import org.jetbrains.kotlin.konan.utils.KonanFactories
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDescriptorFactory
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptors
import org.jetbrains.kotlin.serialization.konan.KotlinResolvedModuleDescriptors
import org.jetbrains.kotlin.storage.StorageManager
internal object TopDownAnalyzerFacadeForKonan {
@@ -38,8 +38,8 @@ internal object TopDownAnalyzerFacadeForKonan {
val projectContext = ProjectContext(config.project, "TopDownAnalyzer for Konan")
val module = DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
moduleName, projectContext.storageManager, origin = CurrentKonanModuleOrigin)
val module = KonanFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
moduleName, projectContext.storageManager, origin = CurrentKlibModuleOrigin)
val moduleContext = MutableModuleContextImpl(module, projectContext)
val resolvedDependencies = ResolvedDependencies(
@@ -100,21 +100,21 @@ internal object TopDownAnalyzerFacadeForKonan {
}
private class ResolvedDependencies(
resolvedLibraries: KonanLibraryResolveResult,
storageManager: StorageManager,
builtIns: KotlinBuiltIns,
specifics: LanguageVersionSettings,
friendModuleFiles: Set<File>
resolvedLibraries: KotlinLibraryResolveResult,
storageManager: StorageManager,
builtIns: KotlinBuiltIns,
specifics: LanguageVersionSettings,
friendModuleFiles: Set<File>
) {
val moduleDescriptors: KonanResolvedModuleDescriptors
val moduleDescriptors: KotlinResolvedModuleDescriptors
val friends: Set<ModuleDescriptorImpl>
init {
val collectedFriends = mutableListOf<ModuleDescriptorImpl>()
val customAction: (KonanLibrary, ModuleDescriptorImpl) -> Unit = { library, moduleDescriptor ->
val customAction: (KotlinLibrary, ModuleDescriptorImpl) -> Unit = { library, moduleDescriptor ->
if (friendModuleFiles.contains(library.libraryFile)) {
collectedFriends.add(moduleDescriptor)
}
@@ -4,6 +4,7 @@ import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
@@ -16,18 +17,12 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.ir.util.addChild
import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.utils.DFS
@@ -230,9 +225,11 @@ internal val copyDefaultValuesToActualPhase = konanUnitPhase(
internal val serializerPhase = konanUnitPhase(
op = {
val descriptorTable = DescriptorTable()
// val declarationTable = KonanDeclarationTable(irModule!!.irBuiltins)
serializedIr = KonanIrModuleSerializer(this, irModule!!.irBuiltins, descriptorTable).serializedIrModule(irModule!!)
val serializer = KonanSerializationUtil(this, config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!, descriptorTable)
val serializer = KlibMetadataMonolithicSerializer(
this.config.configuration.languageVersionSettings,
config.configuration.get(CommonConfigurationKeys.METADATA_VERSION
)!!, descriptorTable, bindingContext)
serializedMetadata = serializer.serializeModule(moduleDescriptor)
},
name = "Serializer",
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.konan.util.nTabs
import org.jetbrains.kotlin.util.nTabs
import org.jetbrains.kotlin.descriptors.*
class DeepPrintVisitor(worker: DeclarationDescriptorVisitor<Boolean, Int>): DeepVisitor<Int>(worker) {
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.backend.konan.RuntimeNames
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.konanModuleOrigin
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit
@@ -161,23 +160,28 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
val fragment = descriptor.findPackage() as KonanPackageFragment
return fragment.sourceFileMap.sourceFile(index)
}
// TODO: temporary disabling. Need to figure out proper SourceFileMap and FileRegistry commonization.
//private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
// val fragment = descriptor.findPackage() as KonanPackageFragment
// return fragment.sourceFileMap.sourceFile(index)
//}
fun CallableMemberDescriptor.findSourceFile(): SourceFile {
val source = this.source.containingFile
if (source != SourceFile.NO_SOURCE_FILE)
return source
return when {
this is DeserializedSimpleFunctionDescriptor && proto.hasExtension(KonanProtoBuf.functionFile) -> sourceByIndex(
this, proto.getExtension(KonanProtoBuf.functionFile))
this is DeserializedPropertyDescriptor && proto.hasExtension(KonanProtoBuf.propertyFile) ->
sourceByIndex(
this, proto.getExtension(KonanProtoBuf.propertyFile))
// TODO: temporary disabling. Need to figure out proper SourceFileMap and FileRegistry commonization.
this is DeserializedSimpleFunctionDescriptor && proto.hasExtension(KlibMetadataProtoBuf.functionFile) ->
SourceFile.NO_SOURCE_FILE
//sourceByIndex(
// this, proto.getExtension(KlibMetadataProtoBuf.functionFile))
this is DeserializedPropertyDescriptor && proto.hasExtension(KlibMetadataProtoBuf.propertyFile) ->
SourceFile.NO_SOURCE_FILE
//sourceByIndex(
// this, proto.getExtension(KlibMetadataProtoBuf.propertyFile))
else -> TODO()
}
}
val ModuleDescriptor.konanLibrary get() = (this.konanModuleOrigin as? DeserializedKonanModuleOrigin)?.library
val ModuleDescriptor.konanLibrary get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride
import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
internal class CodeGenerator(override val context: Context) : ContextUtils {
@@ -930,7 +930,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
}
}
fun getObjCClass(binaryName: String, llvmSymbolOrigin: CompiledKonanModuleOrigin): LLVMValueRef {
fun getObjCClass(binaryName: String, llvmSymbolOrigin: CompiledKlibModuleOrigin): LLVMValueRef {
context.llvm.imports.add(llvmSymbolOrigin)
return load(codegen.objCDataGenerator!!.genClassRef(binaryName).llvm)
}
@@ -7,21 +7,20 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.*
import llvm.*
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
import org.jetbrains.kotlin.backend.konan.ir.isReal
import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin
import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.ir.util.isReal
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import kotlin.properties.ReadOnlyProperty
@@ -318,10 +317,10 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
}
internal fun externalFunction(
name: String,
type: LLVMTypeRef,
origin: CompiledKonanModuleOrigin,
independent: Boolean = false
name: String,
type: LLVMTypeRef,
origin: CompiledKlibModuleOrigin,
independent: Boolean = false
): LLVMValueRef {
this.imports.add(origin, onlyBitcode = independent)
@@ -352,7 +351,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
}
}
private fun externalNounwindFunction(name: String, type: LLVMTypeRef, origin: CompiledKonanModuleOrigin): LLVMValueRef {
private fun externalNounwindFunction(name: String, type: LLVMTypeRef, origin: CompiledKlibModuleOrigin): LLVMValueRef {
val function = externalFunction(name, type, origin)
setFunctionNoUnwind(function)
return function
@@ -362,15 +361,15 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
class ImportsImpl(private val context: Context) : LlvmImports {
private val usedBitcode = mutableSetOf<KonanLibrary>()
private val usedNativeDependencies = mutableSetOf<KonanLibrary>()
private val usedBitcode = mutableSetOf<KotlinLibrary>()
private val usedNativeDependencies = mutableSetOf<KotlinLibrary>()
private val allLibraries by lazy { context.librariesWithDependencies.toSet() }
override fun add(origin: CompiledKonanModuleOrigin, onlyBitcode: Boolean) {
override fun add(origin: CompiledKlibModuleOrigin, onlyBitcode: Boolean) {
val library = when (origin) {
CurrentKonanModuleOrigin -> return
is DeserializedKonanModuleOrigin -> origin.library
CurrentKlibModuleOrigin -> return
is DeserializedKlibModuleOrigin -> origin.library
}
if (library !in allLibraries) {
@@ -391,13 +390,16 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val nativeDependenciesToLink: List<KonanLibrary> by lazy {
context.config.resolvedLibraries
.getFullList(TopologicalLibraryOrder)
.filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.nativeDependenciesAreUsed(it) }
.filter {
require(it is KonanLibrary)
(!it.isDefault && !context.config.purgeUserLibs) || imports.nativeDependenciesAreUsed(it)
} as List<KonanLibrary>
}
val bitcodeToLink: List<KonanLibrary> by lazy {
context.config.resolvedLibraries
.getFullList(TopologicalLibraryOrder)
(context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder) as List<KonanLibrary>)
.filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(it) }
// TODO: the filter above is incorrect when compiling to multiple LLVM modules.
.filter { context.llvmModuleSpecification.containsLibrary(it) }
@@ -8,28 +8,28 @@ package org.jetbrains.kotlin.backend.konan.llvm
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
import org.jetbrains.kotlin.descriptors.konan.konanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.resolve.descriptorUtil.module
internal interface LlvmImports {
fun add(origin: CompiledKonanModuleOrigin, onlyBitcode: Boolean = false)
fun add(origin: CompiledKlibModuleOrigin, onlyBitcode: Boolean = false)
fun bitcodeIsUsed(library: KonanLibrary): Boolean
fun nativeDependenciesAreUsed(library: KonanLibrary): Boolean
}
internal val DeclarationDescriptor.llvmSymbolOrigin: CompiledKonanModuleOrigin
internal val DeclarationDescriptor.llvmSymbolOrigin: CompiledKlibModuleOrigin
get() {
assert(!this.isExpectMember) { this }
val module = this.module
val moduleOrigin = module.konanModuleOrigin
val moduleOrigin = module.klibModuleOrigin
when (moduleOrigin) {
is CompiledKonanModuleOrigin -> return moduleOrigin
is CompiledKlibModuleOrigin -> return moduleOrigin
SyntheticModulesOrigin -> error("Declaration is synthetic and can't be an origin of LLVM symbol:\n${this}")
}
}
internal val Context.standardLlvmSymbolsOrigin: CompiledKonanModuleOrigin get() = this.stdlibModule.llvmSymbolOrigin
internal val Context.standardLlvmSymbolsOrigin: CompiledKlibModuleOrigin get() = this.stdlibModule.llvmSymbolOrigin
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.*
import llvm.*
import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
internal val LLVMValueRef.type: LLVMTypeRef
get() = LLVMTypeOf(this)!!
@@ -212,7 +212,7 @@ internal fun ContextUtils.addGlobal(name: String, type: LLVMTypeRef, isExported:
return result
}
internal fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef, origin: CompiledKonanModuleOrigin,
internal fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef, origin: CompiledKlibModuleOrigin,
threadLocal: Boolean = false): LLVMValueRef {
context.llvm.imports.add(origin)
@@ -13,9 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.resolve.descriptorUtil.module
/**
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm.objc
import llvm.*
import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
/**
* This class provides methods to generate Objective-C RTTI and other data.
@@ -75,7 +75,7 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) {
// TODO: refactor usages and use [Global] class.
val llvmGlobal = LLVMGetNamedGlobal(context.llvmModule, globalName) ?:
codegen.importGlobal(globalName, classObjectType, CurrentKonanModuleOrigin)
codegen.importGlobal(globalName, classObjectType, CurrentKlibModuleOrigin)
return constPointer(llvmGlobal)
}
@@ -84,7 +84,7 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) {
codegen.importGlobal(
"_objc_empty_cache",
codegen.runtime.getStructType("_objc_cache"),
CurrentKonanModuleOrigin
CurrentKlibModuleOrigin
)
)
@@ -9,7 +9,7 @@ import llvm.*
import org.jetbrains.kotlin.backend.common.ir.simpleFunctions
import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.backend.konan.objcexport.BlockPointerBridge
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -274,7 +274,7 @@ internal class BlockAdapterToFunctionGenerator(val objCExportCodeGenerator: ObjC
val isa = codegen.importGlobal(
"_NSConcreteStackBlock",
int8TypePtr,
CurrentKonanModuleOrigin
CurrentKlibModuleOrigin
)
val flags = Int32((1 shl 25) or (1 shl 30) or (1 shl 31)).llvm
@@ -301,7 +301,7 @@ internal class BlockAdapterToFunctionGenerator(val objCExportCodeGenerator: ObjC
val autoreleaseReturnValue = context.llvm.externalFunction(
"objc_autoreleaseReturnValue",
functionType(int8TypePtr, false, int8TypePtr),
CurrentKonanModuleOrigin
CurrentKlibModuleOrigin
)
ret(callFromBridge(autoreleaseReturnValue, listOf(copiedBlock)))
@@ -314,5 +314,5 @@ internal class BlockAdapterToFunctionGenerator(val objCExportCodeGenerator: ObjC
private val ObjCExportCodeGenerator.retainBlock get() = context.llvm.externalFunction(
"objc_retainBlock",
functionType(int8TypePtr, false, int8TypePtr),
CurrentKonanModuleOrigin
CurrentKlibModuleOrigin
)
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.backend.konan.llvm.objc.ObjCDataGenerator
import org.jetbrains.kotlin.backend.konan.objcexport.*
import org.jetbrains.kotlin.backend.konan.serialization.resolveFakeOverrideMaybeAbstract
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.*
@@ -52,7 +52,7 @@ internal class ObjCExportCodeGenerator(
context.llvm.externalFunction(
"objc_terminate",
functionType(voidType, false),
CurrentKonanModuleOrigin
CurrentKlibModuleOrigin
).also {
setFunctionNoUnwind(it)
}
@@ -839,7 +839,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
val function = expression.symbol.owner
if (descriptor == interop.nativePointedRawPtrGetter ||
OverridingUtil.overrides(descriptor, interop.nativePointedRawPtrGetter)) {
OverridingUtil.overrides(descriptor, interop.nativePointedRawPtrGetter, false)) {
// Replace by the intrinsic call to be handled by code generator:
return builder.irCall(symbols.interopNativePointedGetRawPointer).apply {
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.konan.optimizations
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDeserializedDescriptorFactory
import org.jetbrains.kotlin.konan.utils.KonanFactories
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import sun.misc.Unsafe
import kotlin.reflect.KClass
@@ -993,7 +993,7 @@ internal object DFGSerializer {
if (libraryDataFlowGraph != null) {
val module = DataFlowIR.Module(
DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, specifics, storageManager))
KonanFactories.DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, specifics, storageManager, null))
val reader = ArraySlice(libraryDataFlowGraph)
val dataLayoutHash = reader.readLong()
val expectedHash = computeDataLayoutHash(Module::class)
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
class KonanDescriptorReferenceDeserializer(
@@ -10,4 +10,4 @@ class KonanDescriptorReferenceDeserializer(
builtIns: IrBuiltIns,
resolvedForwardDeclarations: MutableMap<UniqId, UniqId>
): DescriptorReferenceDeserializer(currentModule, mangler, builtIns, resolvedForwardDeclarations),
DescriptorUniqIdAware by KonanDescriptorUniqIdAware
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware
@@ -34,7 +34,7 @@ class KonanIrLinker(
forwardModuleDescriptor: ModuleDescriptor?,
exportedDependencies: List<ModuleDescriptor>
) : KotlinIrLinker(logger, builtIns, symbolTable, exportedDependencies, forwardModuleDescriptor, 0L),
DescriptorUniqIdAware by KonanDescriptorUniqIdAware {
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware {
override val descriptorReferenceDeserializer =
KonanDescriptorReferenceDeserializer(currentModule, KonanMangler, builtIns, resolvedForwardDeclarations)
@@ -73,4 +73,4 @@ class KonanIrLinker(
this.put(it.key.konanLibrary!!.libraryName, it.value.module)
}
}
}
}
@@ -1,240 +0,0 @@
/*
* 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.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
import org.jetbrains.kotlin.backend.konan.descriptors.isSerializableExpectClass
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.library.SerializedMetadata
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter.Companion.CALLABLES
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter.Companion.CLASSIFIERS
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.serialization.konan.SourceFileMap
/*
* This is Konan specific part of public descriptor
* tree serialization and deserialization.
*
* It takes care of module and package fragment serializations.
* The lower level (classes and members) serializations are delegated
* to the DescriptorSerializer class.
* The lower level deserializations are performed by the frontend
* with MemberDeserializer class.
*/
internal class KonanSerializationUtil(val context: Context, val metadataVersion: BinaryVersion, val descriptorTable: DescriptorTable) {
lateinit var serializerContext: SerializerContext
val sourceFileMap = SourceFileMap()
data class SerializerContext(
val serializerExtension: KonanSerializerExtension,
val topSerializer: DescriptorSerializer,
var classSerializer: DescriptorSerializer = topSerializer
)
private fun createNewContext(): SerializerContext {
val extension = KonanSerializerExtension(context, metadataVersion, sourceFileMap, descriptorTable)
return SerializerContext(
extension,
DescriptorSerializer.createTopLevel(extension)
)
}
private inline fun <T> withNewContext(crossinline block: SerializerContext.() -> T): T {
serializerContext = createNewContext()
return with(serializerContext, block)
}
private fun serializeClass(packageName: FqName,
builder: KonanProtoBuf.LinkDataClasses.Builder,
classDescriptor: ClassDescriptor) {
with(serializerContext) {
val previousSerializer = classSerializer
classSerializer = DescriptorSerializer.create(classDescriptor, serializerExtension, classSerializer)
val classProto = classSerializer.classProto(classDescriptor).build()
?: error("Class not serialized: $classDescriptor")
builder.addClasses(classProto)
val index = classSerializer.stringTable.getFqNameIndex(classDescriptor)
builder.addClassName(index)
serializeClasses(packageName, builder,
classDescriptor.unsubstitutedInnerClassesScope
.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS))
classSerializer = previousSerializer
}
}
private fun serializeClasses(packageName: FqName,
builder: KonanProtoBuf.LinkDataClasses.Builder,
descriptors: Collection<DeclarationDescriptor>) {
for (descriptor in descriptors) {
if (descriptor is ClassDescriptor) {
serializeClass(packageName, builder, descriptor)
}
}
}
private fun serializePackage(fqName: FqName, module: ModuleDescriptor):
List<KonanProtoBuf.LinkDataPackageFragment> {
// 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(CLASSIFIERS)
}.filter { !it.isExpectMember || it.isSerializableExpectClass }
)
val topLevelDescriptors = DescriptorSerializer.sort(
fragments.flatMap { fragment ->
fragment.getMemberScope().getDescriptorsFiltered(CALLABLES)
}.filter { !it.isExpectMember }
)
val result = mutableListOf<KonanProtoBuf.LinkDataPackageFragment>()
result += classifierDescriptors.chunked(TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE) { descriptors ->
withNewContext {
val classesProto = buildClassesProto { classesBuilder ->
serializeClasses(fqName, classesBuilder, descriptors)
}
val typeAliases = descriptors.filterIsInstance<TypeAliasDescriptor>()
val packageProto =
if (typeAliases.isNotEmpty()) buildPackageProto(fqName, typeAliases, fragments)
else emptyPackageProto()
buildFragment(
packageProto,
classesProto,
fqName,
descriptors.isEmpty()
)
}
}
result += topLevelDescriptors.chunked(TOP_LEVEL_DECLARATION_COUNT_PER_FILE) { descriptors ->
withNewContext {
buildFragment(
buildPackageProto(fqName, descriptors, fragments),
buildClassesProto {},
fqName,
descriptors.isEmpty())
}
}
if (result.isEmpty()) {
result += withNewContext {
buildFragment(
emptyPackageProto(),
buildClassesProto {},
fqName,
true)
}
}
return result
}
private fun buildClassesProto(action: (KonanProtoBuf.LinkDataClasses.Builder) -> Unit): KonanProtoBuf.LinkDataClasses {
val classesBuilder = KonanProtoBuf.LinkDataClasses.newBuilder()
action(classesBuilder)
return classesBuilder.build()
}
private fun emptyPackageProto(): ProtoBuf.Package = ProtoBuf.Package.newBuilder().build()
private fun SerializerContext.buildPackageProto(
fqName: FqName,
descriptors: List<DeclarationDescriptor>,
fragments: List<PackageFragmentDescriptor>) = topSerializer.packagePartProto(fqName, descriptors).build()
?: error("Package fragments not serialized: $fragments")
private 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
}
private fun SerializerContext.buildFragment(
packageProto: ProtoBuf.Package,
classesProto: KonanProtoBuf.LinkDataClasses,
fqName: FqName,
isEmpty: Boolean
): KonanProtoBuf.LinkDataPackageFragment {
val (stringTableProto, nameTableProto) = serializerExtension.stringTable.buildProto()
return KonanProtoBuf.LinkDataPackageFragment.newBuilder()
.setPackage(packageProto)
.setClasses(classesProto)
.setIsEmpty(isEmpty)
.setFqName(fqName.asString())
.setStringTable(stringTableProto)
.setNameTable(nameTableProto)
.build()
}
internal fun serializeModule(moduleDescriptor: ModuleDescriptor): SerializedMetadata {
val libraryProto = KonanProtoBuf.LinkDataLibrary.newBuilder()
libraryProto.moduleName = moduleDescriptor.name.asString()
val fragments = mutableListOf<List<ByteArray>>()
val fragmentNames = mutableListOf<String>()
getPackagesFqNames(moduleDescriptor).forEach iteration@{ packageFqName ->
val packageProtos =
serializePackage(packageFqName, moduleDescriptor)
if (packageProtos.isEmpty()) return@iteration
val packageFqNameStr = packageFqName.asString()
libraryProto.addPackageFragmentName(packageFqNameStr)
if (packageProtos.all { it.isEmpty }) {
libraryProto.addEmptyPackage(packageFqNameStr)
}
fragments.add(packageProtos.map { it.toByteArray() })
fragmentNames.add(packageFqNameStr)
}
sourceFileMap.filesAndClear().map { it.name ?: "" }.forEach {
libraryProto.addFile(it)
}
val libraryAsByteArray = libraryProto.build().toByteArray()
return SerializedMetadata(libraryAsByteArray, fragments, fragmentNames)
}
}
private const val TOP_LEVEL_DECLARATION_COUNT_PER_FILE = 128
private const val TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE = 64
@@ -1,92 +0,0 @@
/*
* 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.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
import org.jetbrains.kotlin.serialization.konan.SourceFileMap
import org.jetbrains.kotlin.types.KotlinType
internal class KonanSerializerExtension(val context: Context, override val metadataVersion: BinaryVersion,
val sourceFileMap: SourceFileMap, val descriptorTable: DescriptorTable
) :
KotlinSerializerExtensionBase(KonanSerializerProtocol) {
override val stringTable = KonanStringTable()
override fun shouldUseTypeTable(): Boolean = true
fun uniqId(descriptor: DeclarationDescriptor): KonanProtoBuf.DescriptorUniqId? {
val index = descriptorTable.get(descriptor)
return index?.let { newKonanDescriptorUniqId(it) }
}
override fun serializeTypeParameter(typeParameter: TypeParameterDescriptor, proto: ProtoBuf.TypeParameter.Builder) {
uniqId(typeParameter) ?.let { proto.setExtension(KonanProtoBuf.typeParamUniqId, it) }
super.serializeTypeParameter(typeParameter, proto)
}
override fun serializeValueParameter(descriptor: ValueParameterDescriptor, proto: ProtoBuf.ValueParameter.Builder) {
uniqId(descriptor) ?. let { proto.setExtension(KonanProtoBuf.valueParamUniqId, it) }
super.serializeValueParameter(descriptor, proto)
}
override fun serializeEnumEntry(descriptor: ClassDescriptor, proto: ProtoBuf.EnumEntry.Builder) {
uniqId(descriptor) ?.let { proto.setExtension(KonanProtoBuf.enumEntryUniqId, it) }
// Serialization doesn't preserve enum entry order, so we need to serialize ordinal.
super.serializeEnumEntry(descriptor, proto)
}
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: DescriptorSerializer) {
uniqId(descriptor) ?. let { proto.setExtension(KonanProtoBuf.classUniqId, it) }
super.serializeClass(descriptor, proto, versionRequirementTable, childSerializer)
childSerializer.typeTable.serialize()?.let { proto.mergeTypeTable(it) }
}
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder,
childSerializer: DescriptorSerializer) {
uniqId(descriptor) ?. let { proto.setExtension(KonanProtoBuf.constructorUniqId, it) }
super.serializeConstructor(descriptor, proto, childSerializer)
}
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: DescriptorSerializer) {
proto.setExtension(KonanProtoBuf.functionFile, sourceFileMap.assign(descriptor.source.containingFile))
uniqId(descriptor) ?. let { proto.setExtension(KonanProtoBuf.functionUniqId, it) }
super.serializeFunction(descriptor, proto, versionRequirementTable, childSerializer)
}
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: DescriptorSerializer) {
proto.setExtension(KonanProtoBuf.propertyFile, sourceFileMap.assign(descriptor.source.containingFile))
uniqId(descriptor) ?.let { proto.setExtension(KonanProtoBuf.propertyUniqId, it) }
super.serializeProperty(descriptor, proto, versionRequirementTable, childSerializer)
}
override fun serializeTypeAlias(typeAlias: TypeAliasDescriptor, proto: ProtoBuf.TypeAlias.Builder) {
uniqId(typeAlias)?.let { proto.setExtension(KonanProtoBuf.typeAliasUniqId, it) }
super.serializeTypeAlias(typeAlias, proto)
}
override fun releaseCoroutines(): Boolean =
context.config.configuration.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
}
@@ -1,53 +0,0 @@
/*
* 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.konan.serialization
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.StringTableImpl
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import java.io.OutputStream
class KonanStringTable : StringTableImpl() {
fun getClassOrPackageFqNameIndex(descriptor: ClassOrPackageFragmentDescriptor): Int {
when (descriptor) {
is PackageFragmentDescriptor ->
return getPackageFqNameIndex(descriptor.fqName)
is ClassDescriptor ->
return getFqNameIndex(descriptor as ClassifierDescriptorWithTypeParameters)
else -> error("Can not get fqNameIndex for $descriptor")
}
}
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
val superClassifiers = descriptor.getAllSuperClassifiers()
.mapNotNull { it as ClassifierDescriptorWithTypeParameters }
.filter { it != descriptor }
.toList()
if (superClassifiers.size == 1) {
superClassifiers[0].classId
} else {
val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) }
superClass?.classId ?: ClassId.topLevel(descriptor.module.builtIns.any.fqNameSafe)
}
} else {
super.getLocalClassIdReplacement(descriptor)
}
}
fun serializeTo(output: OutputStream) {
val (strings, qualifiedNames) = buildProto()
strings.writeDelimitedTo(output)
qualifiedNames.writeDelimitedTo(output)
}
}
@@ -1,28 +0,0 @@
/*
* 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.konan.serialization
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
import org.jetbrains.kotlin.backend.common.serialization.tryGetExtension
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
object KonanDescriptorUniqIdAware: DescriptorUniqIdAware {
override fun DeclarationDescriptor.getUniqId(): Long? = when (this) {
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(KonanProtoBuf.classUniqId)
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(KonanProtoBuf.functionUniqId)
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(KonanProtoBuf.propertyUniqId)
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(KonanProtoBuf.constructorUniqId)
is DeserializedTypeParameterDescriptor -> this.proto.tryGetExtension(KonanProtoBuf.typeParamUniqId)
is DeserializedTypeAliasDescriptor -> this.proto.tryGetExtension(KonanProtoBuf.typeAliasUniqId)
else -> null
}?.index
}
fun newKonanDescriptorUniqId(index: Long): KonanProtoBuf.DescriptorUniqId =
KonanProtoBuf.DescriptorUniqId.newBuilder().setIndex(index).build()
@@ -1,29 +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.
*/
syntax = "proto2";
package org.jetbrains.kotlin.metadata;
import "org/jetbrains/kotlin/backend/konan/serialization/google_descriptor.proto1";
option java_outer_classname = "ExtOptionsProtoBuf";
extend google.protobuf.FieldOptions {
optional bool skip_in_comparison = 50000;
optional bool name_id_in_table = 50001;
optional bool fq_name_id_in_table = 50002;
optional bool string_id_in_table = 50003;
}
@@ -1,555 +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.metadata;
import "org/jetbrains/kotlin/backend/konan/serialization/ext_options.proto1";
option java_outer_classname = "ProtoBuf";
option optimize_for = LITE_RUNTIME;
message StringTable {
repeated string string = 1;
}
message QualifiedNameTable {
message QualifiedName {
optional int32 parent_qualified_name = 1 [default = -1];
// id in the StringTable
required int32 short_name = 2;
optional Kind kind = 3 [default = PACKAGE];
enum Kind {
CLASS = 0;
PACKAGE = 1;
LOCAL = 2;
}
}
repeated QualifiedName qualified_name = 1;
}
message Annotation {
message Argument {
message Value {
enum Type {
BYTE = 0;
CHAR = 1;
SHORT = 2;
INT = 3;
LONG = 4;
FLOAT = 5;
DOUBLE = 6;
BOOLEAN = 7;
STRING = 8;
CLASS = 9;
ENUM = 10;
ANNOTATION = 11;
ARRAY = 12;
}
// Note: a *Value* has a Type, not an Argument! This is done for future language features which may involve using arrays
// of elements of different types. Such entries are allowed in the constant pool of JVM class files.
// However, to save space, this field is optional: in case of homogeneous arrays, only the type of the first element is required
optional Type type = 1;
// Only one of the following values should be present
optional sint64 int_value = 2;
optional float float_value = 3;
optional double double_value = 4;
optional int32 string_value = 5 [(string_id_in_table) = true];
// If type = CLASS, FQ name of the referenced class; if type = ENUM, FQ name of the enum class
optional int32 class_id = 6 [(fq_name_id_in_table) = true];
optional int32 enum_value_id = 7 [(name_id_in_table) = true];
optional Annotation annotation = 8;
repeated Value array_element = 9;
}
required int32 name_id = 1 [(name_id_in_table) = true];
required Value value = 2;
}
required int32 id = 1 [(fq_name_id_in_table) = true];
repeated Argument argument = 2;
}
message Type {
message Argument {
enum Projection {
IN = 0;
OUT = 1;
INV = 2;
STAR = 3;
}
optional Projection projection = 1 [default = INV];
// When projection is STAR, no type is written, otherwise type must be specified
optional Type type = 2;
optional int32 type_id = 3;
}
repeated Argument argument = 2;
optional bool nullable = 3 [default = false];
// If this field is set, the type is flexible.
// All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
optional int32 flexible_type_capabilities_id = 4 [(string_id_in_table) = true];
optional Type flexible_upper_bound = 5;
optional int32 flexible_upper_bound_id = 8;
// Only one of [class_name, type_parameter, type_parameter_name, type_alias_name] should be present
optional int32 class_name = 6 [(fq_name_id_in_table) = true];
optional int32 type_parameter = 7; // id of the type parameter
// Name of the type parameter in the immediate owner
optional int32 type_parameter_name = 9 [(name_id_in_table) = true];
// Note that this may be present only for abbreviated_type
// Top level types are always fully expanded
optional int32 type_alias_name = 12 [(fq_name_id_in_table) = true];
// Outer type may be present only if class_name or type_alias_name is present
optional Type outer_type = 10;
optional int32 outer_type_id = 11;
optional Type abbreviated_type = 13;
optional int32 abbreviated_type_id = 14;
/*
suspend
*/
optional int32 flags = 1;
extensions 100 to 199;
}
message TypeParameter {
required int32 id = 1;
required int32 name = 2 [(name_id_in_table) = true];
optional bool reified = 3 [default = false];
enum Variance {
IN = 0;
OUT = 1;
INV = 2;
}
optional Variance variance = 4 [default = INV];
repeated Type upper_bound = 5;
repeated int32 upper_bound_id = 6 [packed = true];
extensions 100 to 999;
}
message Class {
enum Kind {
// 3 bits
CLASS = 0;
INTERFACE = 1;
ENUM_CLASS = 2;
ENUM_ENTRY = 3;
ANNOTATION_CLASS = 4;
OBJECT = 5;
COMPANION_OBJECT = 6;
}
/*
hasAnnotations
Visibility
Modality
ClassKind
isInner
isData
isExternal
isExpect
isInline
*/
optional int32 flags = 1 [default = 6 /* public final class, no annotations */];
required int32 fq_name = 3 [(fq_name_id_in_table) = true];
optional int32 companion_object_name = 4 [(name_id_in_table) = true];
repeated TypeParameter type_parameter = 5;
repeated Type supertype = 6;
repeated int32 supertype_id = 2 [packed = true];
repeated int32 nested_class_name = 7 [packed = true, (name_id_in_table) = true];
repeated Constructor constructor = 8;
repeated Function function = 9;
repeated Property property = 10;
repeated TypeAlias type_alias = 11;
repeated EnumEntry enum_entry = 13;
repeated int32 sealed_subclass_fq_name = 16 [packed = true, (fq_name_id_in_table) = true];
optional TypeTable type_table = 30;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
optional VersionRequirementTable version_requirement_table = 32;
extensions 100 to 18999;
}
message Package {
repeated Function function = 3;
repeated Property property = 4;
repeated TypeAlias type_alias = 5;
optional TypeTable type_table = 30;
optional VersionRequirementTable version_requirement_table = 32;
extensions 100 to 199;
}
message TypeTable {
repeated Type type = 1;
// Index starting from which all types are nullable, or nothing if all types in this table are non-null.
// Note that the 'nullable' field of Type messages is ignored and shouldn't be written because it wastes too much space
optional int32 first_nullable = 2 [default = -1];
}
message Constructor {
/*
hasAnnotations
Visibility
isSecondary
*/
optional int32 flags = 1 [default = 6 /* public constructor, no annotations */];
repeated ValueParameter value_parameter = 2;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
extensions 100 to 18999;
}
message Function {
/*
hasAnnotations
Visibility
Modality
MemberKind
isOperator
isInfix
isInline
isTailrec
isExternal
isSuspend
isExpect
*/
optional int32 flags = 9 [default = 6 /* public final function, no annotations */];
optional int32 old_flags = 1 [default = 6];
required int32 name = 2 [(name_id_in_table) = true];
optional Type return_type = 3;
optional int32 return_type_id = 7;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
optional int32 receiver_type_id = 8;
repeated ValueParameter value_parameter = 6;
optional TypeTable type_table = 30;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
optional Contract contract = 32;
extensions 100 to 18999;
}
message Property {
/*
hasAnnotations
Visibility
Modality
MemberKind
isVar
hasGetter
hasSetter
isConst
isLateinit
hasConstant
isExternal
isDelegated
isExpect
*/
optional int32 flags = 11 [default = 518 /* public (6) final property with getter (512) */];
optional int32 old_flags = 1 [default = 2054];
required int32 name = 2 [(name_id_in_table) = true];
optional Type return_type = 3;
optional int32 return_type_id = 9;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
optional int32 receiver_type_id = 10;
optional ValueParameter setter_value_parameter = 6;
/*
hasAnnotations
Visibility
Modality
isNotDefault
isExternal
isInline
If getter_flags or setter_flags are absent, their value should be computed as follows:
- hasAnnotations, Visibility, Modality have the same value as in the property flags
- all other flags are false
*/
optional int32 getter_flags = 7;
optional int32 setter_flags = 8;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
extensions 100 to 18999;
}
message ValueParameter {
/*
hasAnnotations
declaresDefault
isCrossinline
isNoinline
*/
optional int32 flags = 1 [default = 0];
required int32 name = 2 [(name_id_in_table) = true];
optional Type type = 3;
optional int32 type_id = 5;
optional Type vararg_element_type = 4;
optional int32 vararg_element_type_id = 6;
extensions 100 to 199;
}
message TypeAlias {
/*
hasAnnotations
Visibility
*/
optional int32 flags = 1 [default = 6 /* public, no annotations */];
required int32 name = 2 [(name_id_in_table) = true];
repeated TypeParameter type_parameter = 3;
optional Type underlying_type = 4;
optional int32 underlying_type_id = 5;
optional Type expanded_type = 6;
optional int32 expanded_type_id = 7;
repeated Annotation annotation = 8;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
extensions 100 to 199;
}
message EnumEntry {
optional int32 name = 1 [(name_id_in_table) = true];
extensions 100 to 199;
}
enum Modality {
// 2 bits
FINAL = 0;
OPEN = 1;
ABSTRACT = 2;
SEALED = 3;
}
enum Visibility {
// 3 bits
INTERNAL = 0;
PRIVATE = 1;
PROTECTED = 2;
PUBLIC = 3;
PRIVATE_TO_THIS = 4;
LOCAL = 5;
}
enum MemberKind {
// 2 bits
DECLARATION = 0;
FAKE_OVERRIDE = 1;
DELEGATION = 2;
SYNTHESIZED = 3;
}
message VersionRequirement {
enum Level {
WARNING = 0;
ERROR = 1;
HIDDEN = 2;
}
enum VersionKind {
LANGUAGE_VERSION = 0;
COMPILER_VERSION = 1;
API_VERSION = 2;
}
// Kotlin version, since which this declaration is accessible, in the following format (encoded version is "major.minor.patch"):
// (patch << 7) + (minor << 3) + major
// Compilers with version less than this value should report a diagnostic if this declaration is selected as the resolution result
optional int32 version = 1;
// Version in base 256, in case we run out of space to store the version in the optimized form. Has priority over 'version'.
// (patch << 16) + (minor << 8) + major
optional int32 version_full = 2;
// Level of the reported diagnostic
optional Level level = 3 [default = ERROR];
// Error code, to be looked up on the website
optional int32 error_code = 4;
// Diagnostic message
optional int32 message = 5 [(string_id_in_table) = true];
// Which version is this requirement for. For example, if version_kind = API_VERSION, this declaration requires the API version
// (the "-api-version" argument value when compiling the call site) to be of at least the specified value
optional VersionKind version_kind = 6 [default = LANGUAGE_VERSION];
}
message VersionRequirementTable {
repeated VersionRequirement requirement = 1;
}
// A part of the package, which is used to serialize .kjsm/.meta.js, .kotlin_builtins and .kotlin_metadata files.
// Is not used in the JVM back-end
message PackageFragment {
optional StringTable strings = 1;
optional QualifiedNameTable qualified_names = 2;
optional Package package = 3;
repeated Class class = 4;
extensions 100 to 199;
}
message Contract {
repeated Effect effect = 1;
}
message Effect {
// This enum controls which effect this message contains and how 'effectConstructorArguments'
// should be parsed.
// Each enum value documented in the following syntax: "EffectName(arg1: T1, arg2: T2, ...)"
// Those arguments are expected to be found in 'effectConstructorArguments' in exactly the same
// order and amount as defined by signature, otherwise message should be dropped.
enum EffectType {
// Returns(value: ConstantValue?)
RETURNS_CONSTANT = 0;
// CallsInPlace(callable: ParameterReference)
// Additionally, InvocationKind in the field 'kind' may be provided to define exact amount of invocations.
CALLS = 1;
// ReturnsNotNull()
RETURNS_NOT_NULL = 2;
}
optional EffectType effect_type = 1;
repeated Expression effect_constructor_argument = 2;
// If present, then whole message is clause of form 'Effect -> Expression', where 'Effect'
// is given by other fields in this message, and 'Expression' is stored in this field.
optional Expression conclusion_of_conditional_effect = 3;
enum InvocationKind {
AT_MOST_ONCE = 0;
EXACTLY_ONCE = 1;
AT_LEAST_ONCE = 2;
}
optional InvocationKind kind = 4;
}
// We use some trickery to optimize memory footprint of contract-expressions:
// exact type of Expression is determined based on its contents.
message Expression {
/*
isNegated => this expression should be negated
isIsNullPredicate => this expression is IsNullPredicate with 'variableName' as argument
*/
optional int32 flags = 1;
// stored as index in valueParameters list of owner-function in 1-indexation
// Index '0' is reserved for extension receiver
optional int32 value_parameter_reference = 2;
enum ConstantValue {
TRUE = 0;
FALSE = 1;
NULL = 2;
}
optional ConstantValue constant_value = 3;
// present => this expression is IsInstancePredicate, with 'variableName' as LHS
// and with type encoded in either one of next two fields as RHS.
optional Type is_instance_type = 4;
optional int32 is_instance_type_id = 5;
// non-empty => this expression is boolean formula of form 'andArguments[0] && andArguments[1] && ...'
// Additionally, if first argument of formula is primitive expression (i.e. predicate or value),
// it is optimized and embedded straight into this message
repeated Expression and_argument = 6;
// non-empty => this expression is boolean formula of form 'orArguments[0] || andArguments[1] || ...'
// Additionally, if first argument of formula is primitive expression (i.e. predicate or value),
// it is optimized and embedded straight into this message.
repeated Expression or_argument = 7;
}
+2 -1
View File
@@ -65,6 +65,7 @@ ext {
kotlinNativeUtilsModule="org.jetbrains.kotlin:kotlin-native-utils:${kotlinVersion}"
kotlinUtilIoModule="org.jetbrains.kotlin:kotlin-util-io:${kotlinVersion}"
kotlinUtilKlibModule="org.jetbrains.kotlin:kotlin-util-klib:${kotlinVersion}"
kotlinUtilKliMetadatabModule="org.jetbrains.kotlin:kotlin-util-klib-metadata:${kotlinVersion}"
konanVersionFull = KonanVersionGeneratedKt.getCurrentKonanVersion()
gradlePluginVersion = konanVersionFull
@@ -608,4 +609,4 @@ task pusher(type: KotlinBuildPusher){
konanVersion = KonanVersionGeneratedKt.getCurrentKonanVersion()
buildServer = "teamcity.jetbrains.com"
token = project.findProperty("teamcityBearToken") ?: System.getenv("TEAMCITY_BEAR_TOKEN")
}
}
+2 -1
View File
@@ -94,8 +94,9 @@ UTILITIES_JAR="${KONAN_HOME}/konan/lib/utilities.jar"
NATIVE_UTILS_JAR="${KONAN_HOME}/konan/lib/kotlin-native-utils.jar"
UTIL_IO_JAR="${KONAN_HOME}/konan/lib/kotlin-util-io.jar"
UTIL_KLIB_JAR="${KONAN_HOME}/konan/lib/kotlin-util-klib.jar"
UTIL_KLIB_METADATA_JAR="${KONAN_HOME}/konan/lib/kotlin-util-klib-metadata.jar"
TROVE_JAR="${KONAN_HOME}/konan/lib/trove4j.jar"
KONAN_CLASSPATH="$KOTLIN_JAR:$KOTLIN_STDLIB_JAR:$KOTLIN_REFLECT_JAR:$KOTLIN_SCRIPT_RUNTIME_JAR:$INTEROP_JAR:$STUB_GENERATOR_JAR:$INTEROP_INDEXER_JAR:$KONAN_JAR:$KLIB_JAR:$UTILITIES_JAR:$SHARED_JAR:$EXTRACTED_METADATA_JAR:$EXTRACTED_SERIALIZER_JAR:$NATIVE_UTILS_JAR:$TROVE_JAR:$UTIL_IO_JAR:$UTIL_KLIB_JAR:$KOTLINX_CLI_JAR"
KONAN_CLASSPATH="$KOTLIN_JAR:$KOTLIN_STDLIB_JAR:$KOTLIN_REFLECT_JAR:$KOTLIN_SCRIPT_RUNTIME_JAR:$INTEROP_JAR:$STUB_GENERATOR_JAR:$INTEROP_INDEXER_JAR:$KONAN_JAR:$KLIB_JAR:$UTILITIES_JAR:$SHARED_JAR:$EXTRACTED_METADATA_JAR:$EXTRACTED_SERIALIZER_JAR:$NATIVE_UTILS_JAR:$TROVE_JAR:$UTIL_IO_JAR:$UTIL_KLIB_JAR:$UTIL_KLIB_METADATA_JAR:$KOTLINX_CLI_JAR"
TOOL_CLASS=org.jetbrains.kotlin.cli.utilities.MainKt
LIBCLANG_DISABLE_CRASH_RECOVERY=1 \
+2 -1
View File
@@ -71,9 +71,10 @@ set "UTILITIES_JAR=%KONAN_LIB%\utilities.jar"
set "NATIVE_UTILS_JAR=%KONAN_LIB%\kotlin-native-utils.jar"
set "UTIL_IO_JAR=%KONAN_LIB%\kotlin-util-io.jar"
set "UTIL_KLIB_JAR=%KONAN_LIB%\kotlin-util-klib.jar"
set "UTIL_KLIB_METADATA_JAR=%KONAN_LIB%\kotlin-util-klib-metadata.jar"
set TROVE_JAR="%KONAN_LIB%\lib\trove4j.jar"
set "KONAN_CLASSPATH=%KOTLIN_JAR%;%KOTLIN_STDLIB_JAR%;%KOTLIN_REFLECT_JAR%;%KOTLIN_SCRIPT_RUNTIME_JAR%;%INTEROP_RUNTIME_JAR%;%KONAN_JAR%;%STUB_GENERATOR_JAR%;%INTEROP_INDEXER_JAR%;%SHARED_JAR%;%EXTRACTED_METADATA_JAR%;%EXTRACTED_SERIALIZER_JAR%;%KLIB_JAR%;%UTILITIES_JAR%;%NATIVE_UTILS_JAR%;%UTIL_IO_JAR%;%UTIL_KLIB_JAR%;%TROVE_JAR%;%KOTLINX_CLI_JAR%"
set "KONAN_CLASSPATH=%KOTLIN_JAR%;%KOTLIN_STDLIB_JAR%;%KOTLIN_REFLECT_JAR%;%KOTLIN_SCRIPT_RUNTIME_JAR%;%INTEROP_RUNTIME_JAR%;%KONAN_JAR%;%STUB_GENERATOR_JAR%;%INTEROP_INDEXER_JAR%;%SHARED_JAR%;%EXTRACTED_METADATA_JAR%;%EXTRACTED_SERIALIZER_JAR%;%KLIB_JAR%;%UTILITIES_JAR%;%NATIVE_UTILS_JAR%;%UTIL_IO_JAR%;%UTIL_KLIB_JAR%;%UTIL_KLIB_METADATA_JAR%;%TROVE_JAR%;%KOTLINX_CLI_JAR%"
set JAVA_OPTS=-ea ^
-Xmx3G ^
@@ -1,103 +0,0 @@
syntax = "proto2";
package org.jetbrains.kotlin.metadata.konan;
// This, and all the rest of the included proto files have ".proto1" extension.
// That allows us to construct the current file,
// but protoc will skip .class files for them.
// The issue here is that we need to co-exist with the big Kotlin,
// in the same namespace of renamed org.jetbrains.kotlin.protobuf packages.
// In case we merge to the main Kotlin workspace the scheme will be simplified.
// FIXME(ddol): fix this import after moving `metadata` to main Kotlin repo - it should refer to the actual metadata.proto file from Kotlin project
import "metadata.proto1";
option java_outer_classname = "KonanProtoBuf";
option optimize_for = LITE_RUNTIME;
// Konan extensions to the "descriptors" protobuf.
message DescriptorUniqId {
required int64 index = 1;
}
extend Package {
optional int32 package_fq_name = 171;
}
extend Class {
repeated Annotation class_annotation = 170;
optional DescriptorUniqId class_uniq_id = 171;
}
extend Constructor {
repeated Annotation constructor_annotation = 170;
optional DescriptorUniqId constructor_uniq_id = 172;
}
extend Function {
repeated Annotation function_annotation = 170;
optional int32 function_file = 172;
optional DescriptorUniqId function_uniq_id = 173;
}
extend Property {
repeated Annotation property_annotation = 170;
repeated Annotation property_getter_annotation = 177;
repeated Annotation property_setter_annotation = 178;
optional Annotation.Argument.Value compile_time_value = 173;
optional int32 property_file = 176;
optional DescriptorUniqId property_uniq_id = 179;
}
extend EnumEntry {
repeated Annotation enum_entry_annotation = 170;
optional int32 enum_entry_ordinal = 171;
optional DescriptorUniqId enum_entry_uniq_id = 172;
}
extend ValueParameter {
repeated Annotation parameter_annotation = 170;
optional DescriptorUniqId value_param_uniq_id = 171;
}
extend TypeAlias {
// TODO repeated org.jetbrains.kotlin.metadata.Annotation type_alias_annotation = 130;
optional DescriptorUniqId type_alias_uniq_id = 131;
}
extend Type {
repeated Annotation type_annotation = 170;
}
extend TypeParameter {
repeated Annotation type_parameter_annotation = 170;
optional DescriptorUniqId type_param_uniq_id = 171;
}
// 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,29 +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.
*/
syntax = "proto2";
package org.jetbrains.kotlin.metadata;
import "google_descriptor.proto1";
option java_outer_classname = "ExtOptionsProtoBuf";
extend google.protobuf.FieldOptions {
optional bool skip_in_comparison = 50000;
optional bool name_id_in_table = 50001;
optional bool fq_name_id_in_table = 50002;
optional bool string_id_in_table = 50003;
}
@@ -1,621 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// The messages in this file describe the definitions found in .proto files.
// A valid .proto file can be translated directly to a FileDescriptorProto
// without any other information (e.g. without reading its imports).
syntax = "proto2";
package google.protobuf;
option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
// descriptor.proto must be optimized for speed because reflection-based
// algorithms don't work during bootstrapping.
option optimize_for = SPEED;
// The protocol compiler can output a FileDescriptorSet containing the .proto
// files it parses.
message FileDescriptorSet {
repeated FileDescriptorProto file = 1;
}
// Describes a complete .proto file.
message FileDescriptorProto {
optional string name = 1; // file name, relative to root of source tree
optional string package = 2; // e.g. "foo", "foo.bar", etc.
// Names of files imported by this file.
repeated string dependency = 3;
// Indexes of the public imported files in the dependency list above.
repeated int32 public_dependency = 10;
// Indexes of the weak imported files in the dependency list.
// For Google-internal migration only. Do not use.
repeated int32 weak_dependency = 11;
// All top-level definitions in this file.
repeated DescriptorProto message_type = 4;
repeated EnumDescriptorProto enum_type = 5;
repeated ServiceDescriptorProto service = 6;
repeated FieldDescriptorProto extension = 7;
optional FileOptions options = 8;
// This field contains optional information about the original source code.
// You may safely remove this entire field whithout harming runtime
// functionality of the descriptors -- the information is needed only by
// development tools.
optional SourceCodeInfo source_code_info = 9;
}
// Describes a message type.
message DescriptorProto {
optional string name = 1;
repeated FieldDescriptorProto field = 2;
repeated FieldDescriptorProto extension = 6;
repeated DescriptorProto nested_type = 3;
repeated EnumDescriptorProto enum_type = 4;
message ExtensionRange {
optional int32 start = 1;
optional int32 end = 2;
}
repeated ExtensionRange extension_range = 5;
optional MessageOptions options = 7;
}
// Describes a field within a message.
message FieldDescriptorProto {
enum Type {
// 0 is reserved for errors.
// Order is weird for historical reasons.
TYPE_DOUBLE = 1;
TYPE_FLOAT = 2;
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
// negative values are likely.
TYPE_INT64 = 3;
TYPE_UINT64 = 4;
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
// negative values are likely.
TYPE_INT32 = 5;
TYPE_FIXED64 = 6;
TYPE_FIXED32 = 7;
TYPE_BOOL = 8;
TYPE_STRING = 9;
TYPE_GROUP = 10; // Tag-delimited aggregate.
TYPE_MESSAGE = 11; // Length-delimited aggregate.
// New in version 2.
TYPE_BYTES = 12;
TYPE_UINT32 = 13;
TYPE_ENUM = 14;
TYPE_SFIXED32 = 15;
TYPE_SFIXED64 = 16;
TYPE_SINT32 = 17; // Uses ZigZag encoding.
TYPE_SINT64 = 18; // Uses ZigZag encoding.
};
enum Label {
// 0 is reserved for errors
LABEL_OPTIONAL = 1;
LABEL_REQUIRED = 2;
LABEL_REPEATED = 3;
// TODO(sanjay): Should we add LABEL_MAP?
};
optional string name = 1;
optional int32 number = 3;
optional Label label = 4;
// If type_name is set, this need not be set. If both this and type_name
// are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
optional Type type = 5;
// For message and enum types, this is the name of the type. If the name
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
// rules are used to find the type (i.e. first the nested types within this
// message are searched, then within the parent, on up to the root
// namespace).
optional string type_name = 6;
// For extensions, this is the name of the type being extended. It is
// resolved in the same manner as type_name.
optional string extendee = 2;
// For numeric types, contains the original text representation of the value.
// For booleans, "true" or "false".
// For strings, contains the default text contents (not escaped in any way).
// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
// TODO(kenton): Base-64 encode?
optional string default_value = 7;
optional FieldOptions options = 8;
}
// Describes an enum type.
message EnumDescriptorProto {
optional string name = 1;
repeated EnumValueDescriptorProto value = 2;
optional EnumOptions options = 3;
}
// Describes a value within an enum.
message EnumValueDescriptorProto {
optional string name = 1;
optional int32 number = 2;
optional EnumValueOptions options = 3;
}
// Describes a service.
message ServiceDescriptorProto {
optional string name = 1;
repeated MethodDescriptorProto method = 2;
optional ServiceOptions options = 3;
}
// Describes a method of a service.
message MethodDescriptorProto {
optional string name = 1;
// Input and output type names. These are resolved in the same way as
// FieldDescriptorProto.type_name, but must refer to a message type.
optional string input_type = 2;
optional string output_type = 3;
optional MethodOptions options = 4;
}
// ===================================================================
// Options
// Each of the definitions above may have "options" attached. These are
// just annotations which may cause code to be generated slightly differently
// or may contain hints for code that manipulates protocol messages.
//
// Clients may define custom options as extensions of the *Options messages.
// These extensions may not yet be known at parsing time, so the parser cannot
// store the values in them. Instead it stores them in a field in the *Options
// message called uninterpreted_option. This field must have the same name
// across all *Options messages. We then use this field to populate the
// extensions when we build a descriptor, at which point all protos have been
// parsed and so all extensions are known.
//
// Extension numbers for custom options may be chosen as follows:
// * For options which will only be used within a single application or
// organization, or for experimental options, use field numbers 50000
// through 99999. It is up to you to ensure that you do not use the
// same number for multiple options.
// * For options which will be published and used publicly by multiple
// independent entities, e-mail protobuf-global-extension-registry@google.com
// to reserve extension numbers. Simply provide your project name (e.g.
// Object-C plugin) and your porject website (if available) -- there's no need
// to explain how you intend to use them. Usually you only need one extension
// number. You can declare multiple options with only one extension number by
// putting them in a sub-message. See the Custom Options section of the docs
// for examples:
// http://code.google.com/apis/protocolbuffers/docs/proto.html#options
// If this turns out to be popular, a web service will be set up
// to automatically assign option numbers.
message FileOptions {
// Sets the Java package where classes generated from this .proto will be
// placed. By default, the proto package is used, but this is often
// inappropriate because proto packages do not normally start with backwards
// domain names.
optional string java_package = 1;
// If set, all the classes from the .proto file are wrapped in a single
// outer class with the given name. This applies to both Proto1
// (equivalent to the old "--one_java_file" option) and Proto2 (where
// a .proto always translates to a single class, but you may want to
// explicitly choose the class name).
optional string java_outer_classname = 8;
// If set true, then the Java code generator will generate a separate .java
// file for each top-level message, enum, and service defined in the .proto
// file. Thus, these types will *not* be nested inside the outer class
// named by java_outer_classname. However, the outer class will still be
// generated to contain the file's getDescriptor() method as well as any
// top-level extensions defined in the file.
optional bool java_multiple_files = 10 [default=false];
// If set true, then the Java code generator will generate equals() and
// hashCode() methods for all messages defined in the .proto file. This is
// purely a speed optimization, as the AbstractMessage base class includes
// reflection-based implementations of these methods.
optional bool java_generate_equals_and_hash = 20 [default=false];
// Generated classes can be optimized for speed or code size.
enum OptimizeMode {
SPEED = 1; // Generate complete code for parsing, serialization,
// etc.
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
}
optional OptimizeMode optimize_for = 9 [default=SPEED];
// Sets the Go package where structs generated from this .proto will be
// placed. There is no default.
optional string go_package = 11;
// Should generic services be generated in each language? "Generic" services
// are not specific to any particular RPC system. They are generated by the
// main code generators in each language (without additional plugins).
// Generic services were the only kind of service generation supported by
// early versions of proto2.
//
// Generic services are now considered deprecated in favor of using plugins
// that generate code specific to your particular RPC system. Therefore,
// these default to false. Old code which depends on generic services should
// explicitly set them to true.
optional bool cc_generic_services = 16 [default=false];
optional bool java_generic_services = 17 [default=false];
optional bool py_generic_services = 18 [default=false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message MessageOptions {
// Set true to use the old proto1 MessageSet wire format for extensions.
// This is provided for backwards-compatibility with the MessageSet wire
// format. You should not use this for any other reason: It's less
// efficient, has fewer features, and is more complicated.
//
// The message must be defined exactly as follows:
// message Foo {
// option message_set_wire_format = true;
// extensions 4 to max;
// }
// Note that the message cannot have any defined fields; MessageSets only
// have extensions.
//
// All extensions of your type must be singular messages; e.g. they cannot
// be int32s, enums, or repeated messages.
//
// Because this is an option, the above two restrictions are not enforced by
// the protocol compiler.
optional bool message_set_wire_format = 1 [default=false];
// Disables the generation of the standard "descriptor()" accessor, which can
// conflict with a field of the same name. This is meant to make migration
// from proto1 easier; new code should avoid fields named "descriptor".
optional bool no_standard_descriptor_accessor = 2 [default=false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message FieldOptions {
// The ctype option instructs the C++ code generator to use a different
// representation of the field than it normally would. See the specific
// options below. This option is not yet implemented in the open source
// release -- sorry, we'll try to include it in a future version!
optional CType ctype = 1 [default = STRING];
enum CType {
// Default mode.
STRING = 0;
CORD = 1;
STRING_PIECE = 2;
}
// The packed option can be enabled for repeated primitive fields to enable
// a more efficient representation on the wire. Rather than repeatedly
// writing the tag and type for each element, the entire array is encoded as
// a single length-delimited blob.
optional bool packed = 2;
// Should this field be parsed lazily? Lazy applies only to message-type
// fields. It means that when the outer message is initially parsed, the
// inner message's contents will not be parsed but instead stored in encoded
// form. The inner message will actually be parsed when it is first accessed.
//
// This is only a hint. Implementations are free to choose whether to use
// eager or lazy parsing regardless of the value of this option. However,
// setting this option true suggests that the protocol author believes that
// using lazy parsing on this field is worth the additional bookkeeping
// overhead typically needed to implement it.
//
// This option does not affect the public interface of any generated code;
// all method signatures remain the same. Furthermore, thread-safety of the
// interface is not affected by this option; const methods remain safe to
// call from multiple threads concurrently, while non-const methods continue
// to require exclusive access.
//
//
// Note that implementations may choose not to check required fields within
// a lazy sub-message. That is, calling IsInitialized() on the outher message
// may return true even if the inner message has missing required fields.
// This is necessary because otherwise the inner message would have to be
// parsed in order to perform the check, defeating the purpose of lazy
// parsing. An implementation which chooses not to check required fields
// must be consistent about it. That is, for any particular sub-message, the
// implementation must either *always* check its required fields, or *never*
// check its required fields, regardless of whether or not the message has
// been parsed.
optional bool lazy = 5 [default=false];
// Is this field deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for accessors, or it will be completely ignored; in the very least, this
// is a formalization for deprecating fields.
optional bool deprecated = 3 [default=false];
// EXPERIMENTAL. DO NOT USE.
// For "map" fields, the name of the field in the enclosed type that
// is the key for this map. For example, suppose we have:
// message Item {
// required string name = 1;
// required string value = 2;
// }
// message Config {
// repeated Item items = 1 [experimental_map_key="name"];
// }
// In this situation, the map key for Item will be set to "name".
// TODO: Fully-implement this, then remove the "experimental_" prefix.
optional string experimental_map_key = 9;
// For Google-internal migration only. Do not use.
optional bool weak = 10 [default=false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message EnumOptions {
// Set this option to false to disallow mapping different tag names to a same
// value.
optional bool allow_alias = 2 [default=true];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message EnumValueOptions {
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message ServiceOptions {
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
// framework. We apologize for hoarding these numbers to ourselves, but
// we were already using them long before we decided to release Protocol
// Buffers.
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message MethodOptions {
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
// framework. We apologize for hoarding these numbers to ourselves, but
// we were already using them long before we decided to release Protocol
// Buffers.
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
// A message representing a option the parser does not recognize. This only
// appears in options protos created by the compiler::Parser class.
// DescriptorPool resolves these when building Descriptor objects. Therefore,
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
// in them.
message UninterpretedOption {
// The name of the uninterpreted option. Each string represents a segment in
// a dot-separated name. is_extension is true iff a segment represents an
// extension (denoted with parentheses in options specs in .proto files).
// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
// "foo.(bar.baz).qux".
message NamePart {
required string name_part = 1;
required bool is_extension = 2;
}
repeated NamePart name = 2;
// The value of the uninterpreted option, in whatever type the tokenizer
// identified it as during parsing. Exactly one of these should be set.
optional string identifier_value = 3;
optional uint64 positive_int_value = 4;
optional int64 negative_int_value = 5;
optional double double_value = 6;
optional bytes string_value = 7;
optional string aggregate_value = 8;
}
// ===================================================================
// Optional source code info
// Encapsulates information about the original source file from which a
// FileDescriptorProto was generated.
message SourceCodeInfo {
// A Location identifies a piece of source code in a .proto file which
// corresponds to a particular definition. This information is intended
// to be useful to IDEs, code indexers, documentation generators, and similar
// tools.
//
// For example, say we have a file like:
// message Foo {
// optional string foo = 1;
// }
// Let's look at just the field definition:
// optional string foo = 1;
// ^ ^^ ^^ ^ ^^^
// a bc de f ghi
// We have the following locations:
// span path represents
// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
//
// Notes:
// - A location may refer to a repeated field itself (i.e. not to any
// particular index within it). This is used whenever a set of elements are
// logically enclosed in a single code segment. For example, an entire
// extend block (possibly containing multiple extension definitions) will
// have an outer location whose path refers to the "extensions" repeated
// field without an index.
// - Multiple locations may have the same path. This happens when a single
// logical declaration is spread out across multiple places. The most
// obvious example is the "extend" block again -- there may be multiple
// extend blocks in the same scope, each of which will have the same path.
// - A location's span is not always a subset of its parent's span. For
// example, the "extendee" of an extension declaration appears at the
// beginning of the "extend" block and is shared by all extensions within
// the block.
// - Just because a location's span is a subset of some other location's span
// does not mean that it is a descendent. For example, a "group" defines
// both a type and a field in a single declaration. Thus, the locations
// corresponding to the type and field and their components will overlap.
// - Code which tries to interpret locations should probably be designed to
// ignore those that it doesn't understand, as more types of locations could
// be recorded in the future.
repeated Location location = 1;
message Location {
// Identifies which part of the FileDescriptorProto was defined at this
// location.
//
// Each element is a field number or an index. They form a path from
// the root FileDescriptorProto to the place where the definition. For
// example, this path:
// [ 4, 3, 2, 7, 1 ]
// refers to:
// file.message_type(3) // 4, 3
// .field(7) // 2, 7
// .name() // 1
// This is because FileDescriptorProto.message_type has field number 4:
// repeated DescriptorProto message_type = 4;
// and DescriptorProto.field has field number 2:
// repeated FieldDescriptorProto field = 2;
// and FieldDescriptorProto.name has field number 1:
// optional string name = 1;
//
// Thus, the above path gives the location of a field name. If we removed
// the last element:
// [ 4, 3, 2, 7 ]
// this path refers to the whole field declaration (from the beginning
// of the label to the terminating semicolon).
repeated int32 path = 1 [packed=true];
// Always has exactly three or four elements: start line, start column,
// end line (optional, otherwise assumed same as start line), end column.
// These are packed into a single field for efficiency. Note that line
// and column numbers are zero-based -- typically you will want to add
// 1 to each before displaying to a user.
repeated int32 span = 2 [packed=true];
// If this SourceCodeInfo represents a complete declaration, these are any
// comments appearing before and after the declaration which appear to be
// attached to the declaration.
//
// A series of line comments appearing on consecutive lines, with no other
// tokens appearing on those lines, will be treated as a single comment.
//
// Only the comment content is provided; comment markers (e.g. //) are
// stripped out. For block comments, leading whitespace and an asterisk
// will be stripped from the beginning of each line other than the first.
// Newlines are included in the output.
//
// Examples:
//
// optional int32 foo = 1; // Comment attached to foo.
// // Comment attached to bar.
// optional int32 bar = 2;
//
// optional string baz = 3;
// // Comment attached to baz.
// // Another line attached to baz.
//
// // Comment attached to qux.
// //
// // Another line attached to qux.
// optional double qux = 4;
//
// optional string corge = 5;
// /* Block comment attached
// * to corge. Leading asterisks
// * will be removed. */
// /* Block comment attached to
// * grault. */
// optional int32 grault = 6;
optional string leading_comments = 3;
optional string trailing_comments = 4;
}
}
@@ -1,555 +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.metadata;
import "ext_options.proto1";
option java_outer_classname = "ProtoBuf";
option optimize_for = LITE_RUNTIME;
message StringTable {
repeated string string = 1;
}
message QualifiedNameTable {
message QualifiedName {
optional int32 parent_qualified_name = 1 [default = -1];
// id in the StringTable
required int32 short_name = 2;
optional Kind kind = 3 [default = PACKAGE];
enum Kind {
CLASS = 0;
PACKAGE = 1;
LOCAL = 2;
}
}
repeated QualifiedName qualified_name = 1;
}
message Annotation {
message Argument {
message Value {
enum Type {
BYTE = 0;
CHAR = 1;
SHORT = 2;
INT = 3;
LONG = 4;
FLOAT = 5;
DOUBLE = 6;
BOOLEAN = 7;
STRING = 8;
CLASS = 9;
ENUM = 10;
ANNOTATION = 11;
ARRAY = 12;
}
// Note: a *Value* has a Type, not an Argument! This is done for future language features which may involve using arrays
// of elements of different types. Such entries are allowed in the constant pool of JVM class files.
// However, to save space, this field is optional: in case of homogeneous arrays, only the type of the first element is required
optional Type type = 1;
// Only one of the following values should be present
optional sint64 int_value = 2;
optional float float_value = 3;
optional double double_value = 4;
optional int32 string_value = 5 [(string_id_in_table) = true];
// If type = CLASS, FQ name of the referenced class; if type = ENUM, FQ name of the enum class
optional int32 class_id = 6 [(fq_name_id_in_table) = true];
optional int32 enum_value_id = 7 [(name_id_in_table) = true];
optional Annotation annotation = 8;
repeated Value array_element = 9;
}
required int32 name_id = 1 [(name_id_in_table) = true];
required Value value = 2;
}
required int32 id = 1 [(fq_name_id_in_table) = true];
repeated Argument argument = 2;
}
message Type {
message Argument {
enum Projection {
IN = 0;
OUT = 1;
INV = 2;
STAR = 3;
}
optional Projection projection = 1 [default = INV];
// When projection is STAR, no type is written, otherwise type must be specified
optional Type type = 2;
optional int32 type_id = 3;
}
repeated Argument argument = 2;
optional bool nullable = 3 [default = false];
// If this field is set, the type is flexible.
// All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
optional int32 flexible_type_capabilities_id = 4 [(string_id_in_table) = true];
optional Type flexible_upper_bound = 5;
optional int32 flexible_upper_bound_id = 8;
// Only one of [class_name, type_parameter, type_parameter_name, type_alias_name] should be present
optional int32 class_name = 6 [(fq_name_id_in_table) = true];
optional int32 type_parameter = 7; // id of the type parameter
// Name of the type parameter in the immediate owner
optional int32 type_parameter_name = 9 [(name_id_in_table) = true];
// Note that this may be present only for abbreviated_type
// Top level types are always fully expanded
optional int32 type_alias_name = 12 [(fq_name_id_in_table) = true];
// Outer type may be present only if class_name or type_alias_name is present
optional Type outer_type = 10;
optional int32 outer_type_id = 11;
optional Type abbreviated_type = 13;
optional int32 abbreviated_type_id = 14;
/*
suspend
*/
optional int32 flags = 1;
extensions 100 to 199;
}
message TypeParameter {
required int32 id = 1;
required int32 name = 2 [(name_id_in_table) = true];
optional bool reified = 3 [default = false];
enum Variance {
IN = 0;
OUT = 1;
INV = 2;
}
optional Variance variance = 4 [default = INV];
repeated Type upper_bound = 5;
repeated int32 upper_bound_id = 6 [packed = true];
extensions 100 to 999;
}
message Class {
enum Kind {
// 3 bits
CLASS = 0;
INTERFACE = 1;
ENUM_CLASS = 2;
ENUM_ENTRY = 3;
ANNOTATION_CLASS = 4;
OBJECT = 5;
COMPANION_OBJECT = 6;
}
/*
hasAnnotations
Visibility
Modality
ClassKind
isInner
isData
isExternal
isExpect
isInline
*/
optional int32 flags = 1 [default = 6 /* public final class, no annotations */];
required int32 fq_name = 3 [(fq_name_id_in_table) = true];
optional int32 companion_object_name = 4 [(name_id_in_table) = true];
repeated TypeParameter type_parameter = 5;
repeated Type supertype = 6;
repeated int32 supertype_id = 2 [packed = true];
repeated int32 nested_class_name = 7 [packed = true, (name_id_in_table) = true];
repeated Constructor constructor = 8;
repeated Function function = 9;
repeated Property property = 10;
repeated TypeAlias type_alias = 11;
repeated EnumEntry enum_entry = 13;
repeated int32 sealed_subclass_fq_name = 16 [packed = true, (fq_name_id_in_table) = true];
optional TypeTable type_table = 30;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
optional VersionRequirementTable version_requirement_table = 32;
extensions 100 to 18999;
}
message Package {
repeated Function function = 3;
repeated Property property = 4;
repeated TypeAlias type_alias = 5;
optional TypeTable type_table = 30;
optional VersionRequirementTable version_requirement_table = 32;
extensions 100 to 199;
}
message TypeTable {
repeated Type type = 1;
// Index starting from which all types are nullable, or nothing if all types in this table are non-null.
// Note that the 'nullable' field of Type messages is ignored and shouldn't be written because it wastes too much space
optional int32 first_nullable = 2 [default = -1];
}
message Constructor {
/*
hasAnnotations
Visibility
isSecondary
*/
optional int32 flags = 1 [default = 6 /* public constructor, no annotations */];
repeated ValueParameter value_parameter = 2;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
extensions 100 to 18999;
}
message Function {
/*
hasAnnotations
Visibility
Modality
MemberKind
isOperator
isInfix
isInline
isTailrec
isExternal
isSuspend
isExpect
*/
optional int32 flags = 9 [default = 6 /* public final function, no annotations */];
optional int32 old_flags = 1 [default = 6];
required int32 name = 2 [(name_id_in_table) = true];
optional Type return_type = 3;
optional int32 return_type_id = 7;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
optional int32 receiver_type_id = 8;
repeated ValueParameter value_parameter = 6;
optional TypeTable type_table = 30;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
optional Contract contract = 32;
extensions 100 to 18999;
}
message Property {
/*
hasAnnotations
Visibility
Modality
MemberKind
isVar
hasGetter
hasSetter
isConst
isLateinit
hasConstant
isExternal
isDelegated
isExpect
*/
optional int32 flags = 11 [default = 518 /* public (6) final property with getter (512) */];
optional int32 old_flags = 1 [default = 2054];
required int32 name = 2 [(name_id_in_table) = true];
optional Type return_type = 3;
optional int32 return_type_id = 9;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
optional int32 receiver_type_id = 10;
optional ValueParameter setter_value_parameter = 6;
/*
hasAnnotations
Visibility
Modality
isNotDefault
isExternal
isInline
If getter_flags or setter_flags are absent, their value should be computed as follows:
- hasAnnotations, Visibility, Modality have the same value as in the property flags
- all other flags are false
*/
optional int32 getter_flags = 7;
optional int32 setter_flags = 8;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
extensions 100 to 18999;
}
message ValueParameter {
/*
hasAnnotations
declaresDefault
isCrossinline
isNoinline
*/
optional int32 flags = 1 [default = 0];
required int32 name = 2 [(name_id_in_table) = true];
optional Type type = 3;
optional int32 type_id = 5;
optional Type vararg_element_type = 4;
optional int32 vararg_element_type_id = 6;
extensions 100 to 199;
}
message TypeAlias {
/*
hasAnnotations
Visibility
*/
optional int32 flags = 1 [default = 6 /* public, no annotations */];
required int32 name = 2 [(name_id_in_table) = true];
repeated TypeParameter type_parameter = 3;
optional Type underlying_type = 4;
optional int32 underlying_type_id = 5;
optional Type expanded_type = 6;
optional int32 expanded_type_id = 7;
repeated Annotation annotation = 8;
// Index into the VersionRequirementTable
optional int32 version_requirement = 31;
extensions 100 to 199;
}
message EnumEntry {
optional int32 name = 1 [(name_id_in_table) = true];
extensions 100 to 199;
}
enum Modality {
// 2 bits
FINAL = 0;
OPEN = 1;
ABSTRACT = 2;
SEALED = 3;
}
enum Visibility {
// 3 bits
INTERNAL = 0;
PRIVATE = 1;
PROTECTED = 2;
PUBLIC = 3;
PRIVATE_TO_THIS = 4;
LOCAL = 5;
}
enum MemberKind {
// 2 bits
DECLARATION = 0;
FAKE_OVERRIDE = 1;
DELEGATION = 2;
SYNTHESIZED = 3;
}
message VersionRequirement {
enum Level {
WARNING = 0;
ERROR = 1;
HIDDEN = 2;
}
enum VersionKind {
LANGUAGE_VERSION = 0;
COMPILER_VERSION = 1;
API_VERSION = 2;
}
// Kotlin version, since which this declaration is accessible, in the following format (encoded version is "major.minor.patch"):
// (patch << 7) + (minor << 3) + major
// Compilers with version less than this value should report a diagnostic if this declaration is selected as the resolution result
optional int32 version = 1;
// Version in base 256, in case we run out of space to store the version in the optimized form. Has priority over 'version'.
// (patch << 16) + (minor << 8) + major
optional int32 version_full = 2;
// Level of the reported diagnostic
optional Level level = 3 [default = ERROR];
// Error code, to be looked up on the website
optional int32 error_code = 4;
// Diagnostic message
optional int32 message = 5 [(string_id_in_table) = true];
// Which version is this requirement for. For example, if version_kind = API_VERSION, this declaration requires the API version
// (the "-api-version" argument value when compiling the call site) to be of at least the specified value
optional VersionKind version_kind = 6 [default = LANGUAGE_VERSION];
}
message VersionRequirementTable {
repeated VersionRequirement requirement = 1;
}
// A part of the package, which is used to serialize .kjsm/.meta.js, .kotlin_builtins and .kotlin_metadata files.
// Is not used in the JVM back-end
message PackageFragment {
optional StringTable strings = 1;
optional QualifiedNameTable qualified_names = 2;
optional Package package = 3;
repeated Class class = 4;
extensions 100 to 199;
}
message Contract {
repeated Effect effect = 1;
}
message Effect {
// This enum controls which effect this message contains and how 'effectConstructorArguments'
// should be parsed.
// Each enum value documented in the following syntax: "EffectName(arg1: T1, arg2: T2, ...)"
// Those arguments are expected to be found in 'effectConstructorArguments' in exactly the same
// order and amount as defined by signature, otherwise message should be dropped.
enum EffectType {
// Returns(value: ConstantValue?)
RETURNS_CONSTANT = 0;
// CallsInPlace(callable: ParameterReference)
// Additionally, InvocationKind in the field 'kind' may be provided to define exact amount of invocations.
CALLS = 1;
// ReturnsNotNull()
RETURNS_NOT_NULL = 2;
}
optional EffectType effect_type = 1;
repeated Expression effect_constructor_argument = 2;
// If present, then whole message is clause of form 'Effect -> Expression', where 'Effect'
// is given by other fields in this message, and 'Expression' is stored in this field.
optional Expression conclusion_of_conditional_effect = 3;
enum InvocationKind {
AT_MOST_ONCE = 0;
EXACTLY_ONCE = 1;
AT_LEAST_ONCE = 2;
}
optional InvocationKind kind = 4;
}
// We use some trickery to optimize memory footprint of contract-expressions:
// exact type of Expression is determined based on its contents.
message Expression {
/*
isNegated => this expression should be negated
isIsNullPredicate => this expression is IsNullPredicate with 'variableName' as argument
*/
optional int32 flags = 1;
// stored as index in valueParameters list of owner-function in 1-indexation
// Index '0' is reserved for extension receiver
optional int32 value_parameter_reference = 2;
enum ConstantValue {
TRUE = 0;
FALSE = 1;
NULL = 2;
}
optional ConstantValue constant_value = 3;
// present => this expression is IsInstancePredicate, with 'variableName' as LHS
// and with type encoded in either one of next two fields as RHS.
optional Type is_instance_type = 4;
optional int32 is_instance_type_id = 5;
// non-empty => this expression is boolean formula of form 'andArguments[0] && andArguments[1] && ...'
// Additionally, if first argument of formula is primitive expression (i.e. predicate or value),
// it is optimized and embedded straight into this message
repeated Expression and_argument = 6;
// non-empty => this expression is boolean formula of form 'orArguments[0] || andArguments[1] || ...'
// Additionally, if first argument of formula is primitive expression (i.e. predicate or value),
// it is optimized and embedded straight into this message.
repeated Expression or_argument = 7;
}
@@ -1,32 +0,0 @@
package org.jetbrains.kotlin.descriptors.konan
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.StorageManager
interface KonanModuleDescriptorFactory {
/**
* Base method for creation of any Kotlin/Native [ModuleDescriptor].
*/
fun createDescriptor(
name: Name,
storageManager: StorageManager,
builtIns: KotlinBuiltIns,
origin: KonanModuleOrigin,
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(
name: Name,
storageManager: StorageManager,
origin: KonanModuleOrigin,
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
): ModuleDescriptorImpl
}
@@ -1,27 +0,0 @@
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)!!
@@ -1,45 +0,0 @@
package org.jetbrains.kotlin.descriptors.konan.impl
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
import org.jetbrains.kotlin.descriptors.konan.KonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.isInteropLibrary
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
import org.jetbrains.kotlin.storage.StorageManager
internal object KonanModuleDescriptorFactoryImpl: KonanModuleDescriptorFactory {
override fun createDescriptor(
name: Name,
storageManager: StorageManager,
builtIns: KotlinBuiltIns,
origin: KonanModuleOrigin,
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
) = ModuleDescriptorImpl(
name,
storageManager,
builtIns,
capabilities = customCapabilities + mapOf(
KonanModuleOrigin.CAPABILITY to origin,
ImplicitIntegerCoercion.MODULE_CAPABILITY to origin.isInteropLibrary()
))
override fun createDescriptorAndNewBuiltIns(
name: Name,
storageManager: StorageManager,
origin: KonanModuleOrigin,
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
): ModuleDescriptorImpl {
val builtIns = KonanBuiltIns(storageManager)
val moduleDescriptor = createDescriptor(name, storageManager, builtIns, origin, customCapabilities)
builtIns.builtInsModule = moduleDescriptor
return moduleDescriptor
}
}
@@ -1,7 +0,0 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolver
import org.jetbrains.kotlin.konan.library.resolver.impl.KonanLibraryResolverImpl
fun SearchPathResolverWithTarget.libraryResolver(): KonanLibraryResolver =
KonanLibraryResolverImpl(this)
@@ -1,56 +0,0 @@
package org.jetbrains.kotlin.konan.library.resolver
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.SearchPathResolverWithTarget
import org.jetbrains.kotlin.library.UnresolvedLibrary
interface KonanLibraryResolver {
val searchPathResolver: SearchPathResolverWithTarget
/**
* 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
): 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 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
}
@@ -1,26 +0,0 @@
package org.jetbrains.kotlin.konan.library.resolver
import org.jetbrains.kotlin.konan.library.KonanLibrary
interface PackageAccessedHandler {
fun markPackageAccessed(fqName: String)
}
/**
* 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
}
@@ -1,151 +0,0 @@
/*
* 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.konan.library.resolver.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.library.resolver.*
import org.jetbrains.kotlin.konan.util.WithLogger
import org.jetbrains.kotlin.library.UnresolvedLibrary
import org.jetbrains.kotlin.library.unresolvedDependencies
internal class KonanLibraryResolverImpl(
override val searchPathResolver: SearchPathResolverWithTarget
): KonanLibraryResolver, 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<KonanLibrary> {
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<KonanLibrary>.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 [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 { KonanResolvedLibraryImpl(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
}
}
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"
}
@@ -1,32 +0,0 @@
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.serialization.konan.SourceFileMap
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
internal class KonanResolvedLibraryImpl(override val library: KonanLibrary): KonanResolvedLibrary {
private val _resolvedDependencies = mutableListOf<KonanResolvedLibrary>()
private val _emptyPackages by lazy { parseModuleHeader(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: String) {
if (!isNeededForLink // fast path
&& !_emptyPackages.contains(fqName)) {
isNeededForLink = true
}
}
override fun toString() = "library=$library, dependsOn=${_resolvedDependencies.joinToString { it.library.toString() }}"
}
@@ -1,50 +1,12 @@
package org.jetbrains.kotlin.konan.utils
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
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 {
/**
* 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)
}
object KonanFactories : KlibMetadataFactories(::createKonanBuiltIns, NullFlexibleTypeDeserializer)
@@ -1,30 +0,0 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
import org.jetbrains.kotlin.serialization.deserialization.getClassId
class KonanClassDataFinder(
private val fragment: KonanProtoBuf.LinkDataPackageFragment,
private val nameResolver: NameResolver
) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? {
val proto = fragment.classes
val nameList = proto.classNameList
val index = nameList.indexOfFirst { nameResolver.getClassId(it) == classId }
if (index == -1) {
return null
}
val foundClass = proto.getClasses(index) ?: error("Could not find data for serialized class $classId")
/* TODO: binary version supposed to be read from protobuf. */
return ClassData(nameResolver, foundClass, KonanMetadataVersion.INSTANCE, SourceElement.NO_SOURCE)
}
}
@@ -1,9 +0,0 @@
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)
@@ -1,35 +0,0 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
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
): 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
): ModuleDescriptorImpl
}
@@ -1,24 +0,0 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
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>
}
@@ -1,16 +0,0 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
class KonanMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
override fun isCompatible(): Boolean = this.major == 1 && this.minor == 0
companion object {
@JvmField
val INSTANCE = KonanMetadataVersion(1, 0, 0)
@JvmField
val INVALID_VERSION = KonanMetadataVersion()
}
}
@@ -1,105 +0,0 @@
/*
* 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.serialization.konan
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
import org.jetbrains.kotlin.konan.library.resolver.impl.KonanResolvedLibraryImpl
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.Name
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.storage.StorageManager
private val KonanLibrary.fileSources: SourceFileMap get() {
val result = SourceFileMap()
val proto = parseModuleHeader(moduleHeaderData)
proto.fileList.forEachIndexed { index, it ->
result.provide(it, index, this)
}
return result
}
class KonanPackageFragment(
fqName: FqName,
private val library: KonanLibrary,
private val packageAccessedHandler: PackageAccessedHandler?,
storageManager: StorageManager,
module: ModuleDescriptor,
partName: String
) : DeserializedPackageFragment(fqName, storageManager, module) {
val sourceFileMap: SourceFileMap by lazy {
library.fileSources
}
lateinit var components: DeserializationComponents
override fun initialize(components: DeserializationComponents) {
this.components = components
}
// The proto field is lazy so that we can load only needed
// packages from the library.
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy {
parsePackageFragment(library.packageMetadata(fqName.asString(), partName))
}
val proto: KonanProtoBuf.LinkDataPackageFragment
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName.asString()) }
private val nameResolver by lazy {
NameResolverImpl(protoForNames.stringTable, protoForNames.nameTable)
}
override val classDataFinder by lazy {
KonanClassDataFinder(proto, nameResolver)
}
private val _memberScope by lazy {
/* TODO: we fake proto binary versioning for now. */
DeserializedPackageMemberScope(
this,
proto.getPackage(),
nameResolver,
KonanMetadataVersion.INSTANCE,
/* containerSource = */ null,
components) { loadClassNames() }
}
override fun getMemberScope(): DeserializedPackageMemberScope = _memberScope
private val classifierNames: Set<Name> by lazy {
val result = mutableSetOf<Name>()
result.addAll(loadClassNames())
protoForNames.getPackage().typeAliasList.mapTo(result) { nameResolver.getName(it.name) }
result
}
fun hasTopLevelClassifier(name: Name): Boolean = name in classifierNames
private fun loadClassNames(): Collection<Name> {
val classNameList = protoForNames.classes.classNameList
val names = classNameList.mapNotNull {
val classId = nameResolver.getClassId(it)
val shortName = classId.shortClassName
if (!classId.isNestedClass) shortName else null
}
return names
}
}
@@ -1,49 +0,0 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
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
): 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
)
@@ -1,21 +0,0 @@
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(this) },
KonanProtoBuf.packageFqName,
KonanProtoBuf.constructorAnnotation,
KonanProtoBuf.classAnnotation,
KonanProtoBuf.functionAnnotation,
KonanProtoBuf.propertyAnnotation,
KonanProtoBuf.propertyGetterAnnotation,
KonanProtoBuf.propertySetterAnnotation,
KonanProtoBuf.enumEntryAnnotation,
KonanProtoBuf.compileTimeValue,
KonanProtoBuf.parameterAnnotation,
KonanProtoBuf.typeAnnotation,
KonanProtoBuf.typeParameterAnnotation
)
@@ -1,14 +0,0 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer
import org.jetbrains.kotlin.types.SimpleType
object NullFlexibleTypeDeserializer : FlexibleTypeDeserializer {
override fun create(
proto: ProtoBuf.Type,
flexibleId: String,
lowerBound: SimpleType,
upperBound: SimpleType) = error("Illegal use of flexible type deserializer.")
}
@@ -1,55 +0,0 @@
/*
* 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.serialization.konan
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment
private class DeserializedSourceFile(
val name_: String, val index: Int, val library: KonanLibrary) : 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: KonanLibrary) {
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()
}
}
@@ -1,131 +0,0 @@
package org.jetbrains.kotlin.serialization.konan.impl
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.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.PackageFragmentProviderImpl
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
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.descriptors.konan.isKonanStdlib
import org.jetbrains.kotlin.incremental.components.LookupTracker
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.deserialization.*
import org.jetbrains.kotlin.serialization.konan.*
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?
) = createDescriptorOptionalBuiltIns(library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler)
override fun createDescriptorAndNewBuiltIns(
library: KonanLibrary,
languageVersionSettings: LanguageVersionSettings,
storageManager: StorageManager,
packageAccessedHandler: PackageAccessedHandler?
) = createDescriptorOptionalBuiltIns(library, languageVersionSettings, storageManager, null, packageAccessedHandler)
private fun createDescriptorOptionalBuiltIns(
library: KonanLibrary,
languageVersionSettings: LanguageVersionSettings,
storageManager: StorageManager,
builtIns: KotlinBuiltIns?,
packageAccessedHandler: PackageAccessedHandler?
): ModuleDescriptorImpl {
val libraryProto = parseModuleHeader(library.moduleHeaderData)
val moduleName = Name.special(libraryProto.moduleName)
val moduleOrigin = DeserializedKonanModuleOrigin(library)
val moduleDescriptor = if (builtIns != null )
descriptorFactory.createDescriptor(moduleName, storageManager, builtIns, moduleOrigin)
else
descriptorFactory.createDescriptorAndNewBuiltIns(moduleName, storageManager, moduleOrigin)
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
val provider = createPackageFragmentProvider(
library,
packageAccessedHandler,
libraryProto.packageFragmentNameList,
storageManager,
moduleDescriptor,
deserializationConfiguration)
if (!moduleDescriptor.isKonanStdlib())
moduleDescriptor.initialize(provider)
else {
// [K][Suspend]FunctionN belong to stdlib.
val packagePartProviders = mutableListOf(provider)
packagePartProviders += functionInterfacePackageFragmentProvider(storageManager, moduleDescriptor)
moduleDescriptor.initialize(CompositePackageFragmentProvider(packagePartProviders))
}
return moduleDescriptor
}
private fun createPackageFragmentProvider(
library: KonanLibrary,
packageAccessedHandler: PackageAccessedHandler?,
packageFragmentNames: List<String>,
storageManager: StorageManager,
moduleDescriptor: ModuleDescriptor,
configuration: DeserializationConfiguration
): PackageFragmentProvider {
val deserializedPackageFragments = packageFragmentsFactory.createDeserializedPackageFragments(
library, packageFragmentNames, moduleDescriptor, packageAccessedHandler, storageManager)
val syntheticPackageFragments = packageFragmentsFactory.createSyntheticPackageFragments(
library, deserializedPackageFragments, moduleDescriptor)
val provider = PackageFragmentProviderImpl(deserializedPackageFragments + syntheticPackageFragments)
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(
moduleDescriptor,
notFoundClasses,
KonanSerializerProtocol)
val components = DeserializationComponents(
storageManager,
moduleDescriptor,
configuration,
DeserializedClassDataFinder(provider),
annotationAndConstantLoader,
provider,
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 provider
}
}
@@ -1,133 +0,0 @@
package org.jetbrains.kotlin.serialization.konan.impl
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.exportForwardDeclarations
import org.jetbrains.kotlin.konan.library.isInterop
import org.jetbrains.kotlin.konan.library.packageFqName
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedPackageFragmentsFactory
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
internal object KonanDeserializedPackageFragmentsFactoryImpl: KonanDeserializedPackageFragmentsFactory {
override fun createDeserializedPackageFragments(
library: KonanLibrary,
packageFragmentNames: List<String>,
moduleDescriptor: ModuleDescriptor,
packageAccessedHandler: PackageAccessedHandler?,
storageManager: StorageManager
) = packageFragmentNames.flatMap {
val fqName = FqName(it)
val parts = library.packageMetadataParts(fqName.asString())
parts.map { partName ->
KonanPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partName)
}
}
override fun createSyntheticPackageFragments(
library: KonanLibrary,
deserializedPackageFragments: List<KonanPackageFragment>,
moduleDescriptor: ModuleDescriptor
): List<PackageFragmentDescriptor> {
if (!library.isInterop) return emptyList()
val mainPackageFqName = library.packageFqName ?.let { FqName(it) }
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
val exportForwardDeclarations = library.exportForwardDeclarations.map { FqName(it) }
val aliasedPackageFragments = deserializedPackageFragments.filter { it.fqName == mainPackageFqName }
val result = mutableListOf<PackageFragmentDescriptor>()
listOf(ForwardDeclarationsFqNames.cNamesStructs, ForwardDeclarationsFqNames.objCNamesClasses, ForwardDeclarationsFqNames.objCNamesProtocols).mapTo(result) { fqName ->
ClassifierAliasingPackageFragmentDescriptor(aliasedPackageFragments, moduleDescriptor, fqName)
}
result.add(ExportedForwardDeclarationsPackageFragmentDescriptor(moduleDescriptor, mainPackageFqName, exportForwardDeclarations))
return result
}
}
/**
* The package fragment to export forward declarations from interop package namespace, i.e.
* redirect "$pkg.$name" to e.g. "cnames.structs.$name".
*/
class ExportedForwardDeclarationsPackageFragmentDescriptor(
module: ModuleDescriptor,
fqName: FqName,
declarations: List<FqName>
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
private val nameToFqName = declarations.map { it.shortName() to it }.toMap()
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
val declFqName = nameToFqName[name] ?: return null
val packageView = module.getPackage(declFqName.parent())
return packageView.memberScope.getContributedClassifier(name, location)
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("declarations = $declarations")
p.popIndent()
p.println("}")
}
}
override fun getMemberScope() = memberScope
}
/**
* The package fragment that redirects all requests for classifier lookup to its targets.
*/
class ClassifierAliasingPackageFragmentDescriptor(
targets: List<KonanPackageFragment>,
module: ModuleDescriptor,
fqName: FqName
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation) =
targets.firstNotNullResult {
if (it.hasTopLevelClassifier(name)) {
it.getMemberScope().getContributedClassifier(name, location)
} else {
null
}
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("targets = $targets")
p.popIndent()
p.println("}")
}
}
override fun getMemberScope(): MemberScope = memberScope
}
@@ -1,181 +0,0 @@
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)?
): KonanResolvedModuleDescriptors {
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
@Suppress("NAME_SHADOWING")
var builtIns = builtIns
// Build module descriptors.
resolvedLibraries.forEach { library, packageAccessedHandler ->
profile("Loading ${library.libraryName}") {
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
val moduleDescriptor = createDescriptorOptionalBuiltsIns(
library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler)
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)
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: 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?
) = if (builtIns != null)
moduleDescriptorFactory.createDescriptor(library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler)
else
moduleDescriptorFactory.createDescriptorAndNewBuiltIns(library, languageVersionSettings, storageManager, packageAccessedHandler)
}
/**
* Package fragment which creates descriptors for forward declarations on demand.
*/
private 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"))
}
+2 -1
View File
@@ -29,4 +29,5 @@ org.gradle.jvmargs='-Dfile.encoding=UTF-8'
org.gradle.workers.max=4
# Uncomment to enable composite build
#kotlinProjectPath=<insert the path to Kotlin project root here>
#kotlinProjectPath=<insert the path to Kotlin project root here>
kotlinProjectPath=/Users/jetbrains/kotlin-native/kotlin
@@ -13,15 +13,16 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION_WITH_DOT
import org.jetbrains.kotlin.konan.library.resolverByName
import org.jetbrains.kotlin.library.resolverByName
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import org.jetbrains.kotlin.library.unpackZippedKonanLibraryTo
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDeserializedDescriptorFactory
import org.jetbrains.kotlin.konan.util.Logger
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
import org.jetbrains.kotlin.util.Logger
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.lang.System.out
import kotlin.system.exitProcess
@@ -85,7 +86,7 @@ object KlibToolLogger : Logger {
val defaultRepository = File(DependencyProcessor.localKonanDir.resolve("klib").absolutePath)
open class ModuleDeserializer(val library: ByteArray) {
protected val moduleHeader: KonanProtoBuf.LinkDataLibrary
protected val moduleHeader: KlibMetadataProtoBuf.Header
get() = parseModuleHeader(library)
val moduleName: String
@@ -112,8 +113,11 @@ class Library(val name: String, val requestedRepository: String?, val target: St
println("ABI version: $headerAbiVersion")
println("Compiler version: ${headerCompilerVersion?.toString(true, true)}")
println("Library version: $headerLibraryVersion")
val targets = library.targetList.joinToString(", ")
print("Available targets: $targets\n")
if (library is KonanLibrary) {
val targets = library.targetList.joinToString(", ")
print("Available targets: $targets\n")
}
}
fun install() {
@@ -151,7 +155,7 @@ class Library(val name: String, val requestedRepository: String?, val target: St
val storageManager = LockBasedStorageManager("klib")
val library = libraryInRepoOrCurrentDir(repository, name)
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
val module = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, versionSpec, storageManager)
val module = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, versionSpec, storageManager, null)
val defaultModules = mutableListOf<ModuleDescriptorImpl>()
if (!module.isKonanStdlib()) {
@@ -163,7 +167,7 @@ class Library(val name: String, val requestedRepository: String?, val target: St
resolver.defaultLinks(false, true, true)
.mapTo(defaultModules) {
DefaultDeserializedDescriptorFactory.createDescriptor(
it, versionSpec, storageManager, module.builtIns)
it, versionSpec, storageManager, module.builtIns, null)
}
}
+1
View File
@@ -56,6 +56,7 @@ if (hasProperty("kotlinProjectPath")) {
substitute module("org.jetbrains.kotlin:kotlin-stdlib-gen:$kotlinStdlibVersion") with project(':tools:kotlin-stdlib-gen')
substitute module("org.jetbrains.kotlin:kotlin-util-io:$kotlinVersion") with project(':kotlin-util-io')
substitute module("org.jetbrains.kotlin:kotlin-util-klib:$kotlinVersion") with project(':kotlin-util-klib')
substitute module("org.jetbrains.kotlin:kotlin-util-klib-metadata:$kotlinVersion") with project(':kotlin-util-klib-metadata')
substitute module("org.jetbrains.kotlin:kotlin-native-utils:$kotlinVersion") with project(':kotlin-native:kotlin-native-utils')
}
}
+2 -1
View File
@@ -1 +1,2 @@
rootProject.name = "kotlin-native-shared"
rootProject.name = "kotlin-native-shared"
@@ -6,30 +6,14 @@ import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl
import org.jetbrains.kotlin.konan.library.impl.createKonanLibrary
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.*
import kotlin.system.exitProcess
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION_WITH_DOT
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.UnresolvedLibrary
import org.jetbrains.kotlin.library.uniqueName
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.util.DummyLogger
import org.jetbrains.kotlin.util.Logger
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove the constants below:
const val KONAN_STDLIB_NAME = "stdlib"
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this interface!
interface SearchPathResolver : WithLogger {
val searchRoots: List<File>
fun resolutionSequence(givenPath: String): Sequence<File>
fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean = false): KonanLibraryImpl
fun resolve(givenPath: String): KonanLibraryImpl
fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean, noEndorsedLibs: Boolean): List<KonanLibraryImpl>
}
// FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove this interface!
interface SearchPathResolverWithTarget: SearchPathResolver {
interface SearchPathResolverWithTarget<out L: KotlinLibrary>: SearchPathResolverWithAttributes<L> {
val target: KonanTarget
val knownAbiVersions: List<KotlinAbiVersion>?
val knownCompilerVersions: List<KonanVersion>?
}
fun defaultResolver(
@@ -37,17 +21,17 @@ fun defaultResolver(
target: KonanTarget,
distribution: Distribution = Distribution(),
compatibleCompilerVersions: List<KonanVersion> = emptyList()
): SearchPathResolverWithTarget = defaultResolver(repositories, emptyList(), target, distribution, compatibleCompilerVersions)
): SearchPathResolverWithTarget<KonanLibraryImpl> = defaultResolver(repositories, emptyList(), target, distribution, compatibleCompilerVersions)
fun defaultResolver(
repositories: List<String>,
directLibs: List<String>,
target: KonanTarget,
distribution: Distribution,
compatibleCompilerVersions: List<KonanVersion> = emptyList(),
logger: Logger = DummyLogger,
skipCurrentDir: Boolean = false
): SearchPathResolverWithTarget = KonanLibraryProperResolver(
repositories: List<String>,
directLibs: List<String>,
target: KonanTarget,
distribution: Distribution,
compatibleCompilerVersions: List<KonanVersion> = emptyList(),
logger: Logger = DummyLogger,
skipCurrentDir: Boolean = false
): SearchPathResolverWithTarget<KonanLibraryImpl> = KonanLibraryProperResolver(
repositories,
directLibs,
target,
@@ -58,139 +42,6 @@ fun defaultResolver(
skipCurrentDir,
logger)
fun resolverByName(
repositories: List<String>,
directLibs: List<String> = emptyList(),
distributionKlib: String? = null,
localKonanDir: String? = null,
skipCurrentDir: Boolean = false,
logger: Logger = DummyLogger
): SearchPathResolver = KonanLibrarySearchPathResolver(repositories, directLibs, distributionKlib, localKonanDir, skipCurrentDir, logger)
internal open class KonanLibrarySearchPathResolver(
repositories: List<String>,
directLibs: List<String>,
val distributionKlib: String?,
val localKonanDir: String?,
val skipCurrentDir: Boolean,
override val logger:Logger = DummyLogger
) : SearchPathResolver {
val localHead: File?
get() = localKonanDir?.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<KonanLibrary> by lazy {
directLibs.mapNotNull { found(File(it)) }.map { createKonanLibrary(it, null) }
}
// 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): KonanLibraryImpl {
val givenPath = unresolved.path
return resolutionSequence(givenPath).firstOrNull() ?. let {
createKonanLibrary(it, null, isDefaultLink) as KonanLibraryImpl
} ?: 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) == KONAN_STDLIB_NAME }
.map { UnresolvedLibrary(it.absolutePath, null) }
.map { resolve(it, isDefaultLink = true) }
} else emptySequence()
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean, noEndorsedLibs: Boolean): List<KonanLibraryImpl> {
val result = mutableListOf<KonanLibraryImpl>()
if (!noStdLib) {
result.add(resolve(UnresolvedLibrary(KONAN_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
}
}
internal class KonanLibraryProperResolver(
repositories: List<String>,
directLibs: List<String>,
@@ -201,8 +52,8 @@ internal class KonanLibraryProperResolver(
localKonanDir: String?,
skipCurrentDir: Boolean,
override val logger: Logger = DummyLogger
) : KonanLibrarySearchPathResolver(repositories, directLibs, distributionKlib, localKonanDir, skipCurrentDir, logger),
SearchPathResolverWithTarget
) : KotlinLibrarySearchPathResolver<KonanLibraryImpl>(repositories, directLibs, distributionKlib, localKonanDir, skipCurrentDir, logger),
SearchPathResolverWithTarget<KonanLibraryImpl>
{
override val distPlatformHead: File?
get() = distributionKlib?.File()?.child("platform")?.child(target.visibleName)
@@ -220,7 +71,7 @@ internal class KonanLibraryProperResolver(
}
}
internal fun SearchPathResolverWithTarget.libraryMatch(candidate: KonanLibraryImpl, unresolved: UnresolvedLibrary): Boolean {
internal fun SearchPathResolverWithTarget<KonanLibraryImpl>.libraryMatch(candidate: KonanLibraryImpl, unresolved: UnresolvedLibrary): Boolean {
val resolverTarget = this.target
val candidatePath = candidate.libraryFile.absolutePath
@@ -262,8 +113,3 @@ internal fun SearchPathResolverWithTarget.libraryMatch(candidate: KonanLibraryIm
return true
}
private fun KonanVersion.compatible(other: KonanVersion) =
this.major == other.major
&& this.minor == other.minor
&& this.maintenance == other.maintenance
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.konan.util
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
import java.io.File
import java.io.StringReader
import java.util.*
@@ -1,24 +0,0 @@
package org.jetbrains.kotlin.konan.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)
}
}
@@ -26,10 +26,11 @@ import org.jetbrains.kotlin.gradle.plugin.tasks.KonanArtifactWithLibrariesTask
import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask
import org.jetbrains.kotlin.konan.*
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.library.SearchPathResolver
import org.jetbrains.kotlin.konan.library.defaultResolver
import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.library.SearchPathResolver
import java.io.File
open class KonanLibrariesSpec(val task: KonanArtifactWithLibrariesTask, val project: Project) {
@@ -152,7 +153,7 @@ open class KonanLibrariesSpec(val task: KonanArtifactWithLibrariesTask, val proj
)
)
fun asFiles(resolver: SearchPathResolver): List<File> = mutableListOf<File>().apply {
fun asFiles(resolver: SearchPathResolver<KonanLibraryImpl>): List<File> = mutableListOf<File>().apply {
files.flatMapTo(this) { it.files }
addAll(artifactFiles)
addAll(task.platformConfiguration.files)
+2
View File
@@ -16,6 +16,8 @@ repositories {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$buildKotlinVersion"
compile "org.jetbrains.kotlin:kotlin-util-io:$kotlinVersion"
compile "org.jetbrains.kotlin:kotlin-util-klib:$kotlinVersion"
compile project(':backend.native')
compile project(':Interop:StubGenerator')
compile project(':klib')
@@ -5,11 +5,15 @@
package org.jetbrains.kotlin.cli.utilities
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.defaultResolver
import org.jetbrains.kotlin.konan.library.includedHeaders
import org.jetbrains.kotlin.konan.library.packageFqName
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.native.interop.gen.jvm.interop
import org.jetbrains.kotlin.konan.target.PlatformManager
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
import org.jetbrains.kotlin.library.toUnresolvedLibraries
import org.jetbrains.kotlin.native.interop.gen.jvm.interop
import org.jetbrains.kotlin.native.interop.tool.*
// TODO: this function should eventually be eliminated from 'utilities'.
@@ -52,7 +56,7 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
val allLibraries = resolver.resolveWithDependencies(
libraries.toUnresolvedLibraries, noStdLib = true, noDefaultLibs = noDefaultLibs,
noEndorsedLibs = noEndorsedLibs
).getFullList()
).getFullList() as List<KonanLibrary>
val imports = allLibraries.map { library ->
// TODO: handle missing properties?