JVM_IR: read Klib

This commit is contained in:
Georgy Bronnikov
2019-11-29 11:49:20 +03:00
parent 47d6bdfd35
commit 5ede65c525
15 changed files with 462 additions and 28 deletions
@@ -12,6 +12,9 @@ import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.ir.backend.jvm.serialization.EmptyLoggingContext
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrLinker
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmMangler
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
@@ -43,11 +46,26 @@ object JvmBackendFacade {
}
}
val irProviders = generateTypicalIrProviderList(
psi2irContext.moduleDescriptor, psi2irContext.irBuiltIns, psi2irContext.symbolTable,
extensions = extensions
val stubGenerator = DeclarationStubGenerator(
psi2irContext.moduleDescriptor, psi2irContext.symbolTable, psi2irContext.irBuiltIns.languageVersionSettings, extensions
)
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders = irProviders, expectDescriptorToSymbol = null)
val deserializer = JvmIrLinker(
psi2irContext.moduleDescriptor, EmptyLoggingContext, psi2irContext.irBuiltIns, psi2irContext.symbolTable, stubGenerator
)
psi2irContext.moduleDescriptor.allDependencyModules.filter { it.getCapability(KlibModuleOrigin.CAPABILITY) != null }.forEach {
deserializer.deserializeIrModuleHeader(it)
}
val irProviders = listOf(deserializer, stubGenerator)
stubGenerator.setIrProviders(irProviders)
val irModuleFragment = psi2ir.generateModuleFragment(
psi2irContext, files,
irProviders = irProviders,
expectDescriptorToSymbol = null
)
// We need to compile all files we reference in Klibs
irModuleFragment.files.addAll(deserializer.getAllIrFiles())
doGenerateFilesInternal(
state, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, irProviders, extensions
)
@@ -282,7 +282,7 @@ open class ClassCodegen protected constructor(
if (entry is MultifileFacadeFileEntry) {
return entry.partFiles.flatMap { it.loadSourceFilesInfo() }
}
return listOf(File(context.psiSourceManager.getFileEntry(this)!!.name))
return listOfNotNull(context.psiSourceManager.getFileEntry(this)?.let { File(it.name) })
}
companion object {
@@ -21,18 +21,26 @@ import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclaration
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmSimpleFileClassInfo
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import java.io.File
import java.util.*
internal val fileClassPhase = makeIrModulePhase(
@@ -71,10 +79,21 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
private fun createFileClass(irFile: IrFile, fileClassMembers: List<IrDeclaration>): IrClass {
val fileEntry = irFile.fileEntry
val ktFile = context.psiSourceManager.getKtFile(fileEntry as PsiSourceManager.PsiFileEntry)
?: throw AssertionError("Unexpected file entry: $fileEntry")
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(ktFile)
val descriptor = WrappedClassDescriptor(sourceElement = KotlinSourceElement(ktFile))
val fileClassInfo: JvmFileClassInfo?
val descriptor: ClassDescriptor
when (fileEntry) {
is PsiSourceManager.PsiFileEntry -> {
val ktFile = context.psiSourceManager.getKtFile(fileEntry as PsiSourceManager.PsiFileEntry)
?: throw AssertionError("Unexpected file entry: $fileEntry")
fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(ktFile)
descriptor = WrappedClassDescriptor(sourceElement = KotlinSourceElement(ktFile))
}
is NaiveSourceBasedFileEntryImpl -> {
fileClassInfo = JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(irFile.fqName, fileEntry.name), false)
descriptor = WrappedClassDescriptor()
}
else -> error("unknown kind of file entry: $fileEntry")
}
return IrClassImpl(
0, fileEntry.maxOffset,
IrDeclarationOrigin.FILE_CLASS,
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
@@ -21,6 +22,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.KotlinType
@@ -632,3 +634,37 @@ val IrFunctionReference.typeSubstitutionMap: Map<IrTypeParameterSymbol, IrType>
val IrFunctionAccessExpression.typeSubstitutionMap: Map<IrTypeParameterSymbol, IrType>
get() = getTypeSubstitutionMap(symbol.owner)
fun SymbolTable.referenceMember(descriptor: DeclarationDescriptor): IrSymbol =
descriptor.accept(
object : DeclarationDescriptorVisitorEmptyBodies<IrSymbol, Unit?>() {
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit?) =
if (DescriptorUtils.isEnumEntry(descriptor))
referenceEnumEntry(descriptor)
else
referenceClass(descriptor)
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: Unit?) =
referenceConstructor(descriptor as ClassConstructorDescriptor)
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit?) = referenceSimpleFunction(descriptor)
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit?) = referenceProperty(descriptor)
override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: Unit?) = referenceTypeParameter(descriptor)
override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit?) = referenceTypeAlias(descriptor)
override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor?, data: Unit?): IrSymbol {
throw AssertionError("Unexpected member descriptor: $descriptor")
}
},
null
)
fun SymbolTable.findOrDeclareExternalPackageFragment(descriptor: PackageFragmentDescriptor) =
referenceExternalPackageFragment(descriptor).also {
if (!it.isBound) {
declareExternalPackageFragment(descriptor)
}
}.owner
@@ -27,11 +27,11 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
abstract class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor,
val mangler: KotlinMangler,
val builtIns: IrBuiltIns,
val builtIns: IrBuiltIns?,
val resolvedForwardDeclarations: MutableMap<UniqId, UniqId>
) : DescriptorUniqIdAware {
protected open fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
protected open fun resolveSpecialDescriptor(fqn: FqName) = builtIns!!.builtIns.getBuiltInClassByFqName(fqn)
open fun checkIfSpecialDescriptorId(id: Long) = with(mangler) { id.isSpecial }
protected open fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) =
@@ -46,7 +46,8 @@ abstract class KotlinIrLinker(
val symbolTable: SymbolTable,
private val exportedDependencies: List<ModuleDescriptor>,
private val forwardModuleDescriptor: ModuleDescriptor?,
mangler: KotlinMangler
mangler: KotlinMangler,
private val tolerateNonKlibDescriptors: Boolean = false
) : DescriptorUniqIdAware, IrDeserializer {
private val expectUniqIdToActualUniqId = mutableMapOf<UniqId, UniqId>()
@@ -133,7 +134,9 @@ abstract class KotlinIrLinker(
private val moduleDeserializationState = DeserializationState.ModuleDeserializationState(this)
val moduleReversedFileIndex = mutableMapOf<UniqId, IrDeserializerForFile>()
private val moduleDependencies by lazy {
moduleDescriptor.allDependencyModules.filter { it != moduleDescriptor }.map { deserializersForModules[it]!! }
moduleDescriptor.allDependencyModules.filter { it != moduleDescriptor }.mapNotNull {
deserializersForModules[it] ?: if (tolerateNonKlibDescriptors) null else error("Module without deserializer $it")
}
}
// This is a heavy initializer
@@ -562,12 +565,21 @@ abstract class KotlinIrLinker(
}
val descriptorUniqId = topLevelDescriptor.getUniqId()
?: error("Could not get descriptor uniq id for $topLevelDescriptor")
?: if (tolerateNonKlibDescriptors) {
return null
} else {
error("Could not get descriptor uniq id for $topLevelDescriptor")
}
val topLevelKey = UniqId(descriptorUniqId)
val moduleOfOrigin = topLevelDescriptor.module
val moduleDeserializer = deserializersForModules[moduleOfOrigin] ?: error("No module deserializer found for $moduleOfOrigin")
val moduleDeserializer = deserializersForModules[moduleOfOrigin] ?:
if (tolerateNonKlibDescriptors) {
return null
} else {
error("No module deserializer found for $moduleOfOrigin")
}
moduleDeserializer.addModuleReachableTopLevel(topLevelKey)
@@ -697,6 +709,10 @@ abstract class KotlinIrLinker(
fun deserializeOnlyHeaderModule(moduleDescriptor: ModuleDescriptor): IrModuleFragment =
deserializeIrModuleHeader(moduleDescriptor, DeserializationStrategy.ONLY_DECLARATION_HEADERS)
fun getAllIrFiles(): List<IrFile> {
return deserializersForModules.values.flatMap { it.module.files }
}
}
enum class DeserializationStrategy(val needBodies: Boolean, val explicitlyExported: Boolean, val theWholeWorld: Boolean) {
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.jvm
import org.jetbrains.kotlin.konan.CompilerVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.KotlinLibraryProperResolverWithAttributes
import org.jetbrains.kotlin.library.UnresolvedLibrary
import org.jetbrains.kotlin.library.impl.createKotlinLibraryComponents
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
import org.jetbrains.kotlin.util.Logger
val jvmLibrariesProvidedByDefault = setOf("stdlib", "kotlin")
class JvmLibraryResolver(
repositories: List<String>,
directLibs: List<String>,
knownAbiVersions: List<KotlinAbiVersion>?,
knownCompilerVersions: List<CompilerVersion>?,
distributionKlib: String?,
localKotlinDir: String?,
skipCurrentDir: Boolean,
logger: Logger
) : KotlinLibraryProperResolverWithAttributes<KotlinLibrary>(
repositories,
directLibs,
knownAbiVersions,
knownCompilerVersions,
distributionKlib,
localKotlinDir,
skipCurrentDir,
logger,
emptyList()
) {
// Stick with the default KotlinLibrary for now.
override fun libraryComponentBuilder(file: File, isDefault: Boolean) = createKotlinLibraryComponents(file, isDefault)
// We do not need stdlib in klib form.
override fun isProvidedByDefault(unresolved: UnresolvedLibrary): Boolean =
unresolved.path in jvmLibrariesProvidedByDefault
}
// TODO: This is a temporary set of library resolver policies for jvm compiler.
fun jvmResolveLibraries(libraries: List<String>, logger: Logger): KotlinLibraryResolveResult {
val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null) }
val libraryAbsolutePaths = libraries.map { File(it).absolutePath }
// Configure the resolver to only work with absolute paths for now.
val libraryResolver = JvmLibraryResolver(
repositories = emptyList(),
directLibs = libraryAbsolutePaths,
knownAbiVersions = listOf(KotlinAbiVersion.CURRENT),
knownCompilerVersions = emptyList<CompilerVersion>(),
distributionKlib = null,
localKotlinDir = null,
skipCurrentDir = false,
logger = logger
).libraryResolver()
val resolvedLibraries =
libraryResolver.resolveWithDependencies(
unresolvedLibraries = unresolvedLibraries,
noStdLib = true,
noDefaultLibs = true,
noEndorsedLibs = true
)
return resolvedLibraries
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.jvm.serialization
import org.jetbrains.kotlin.backend.common.serialization.DescriptorReferenceDeserializer
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
class JvmDescriptorReferenceDeserializer(currentModule: ModuleDescriptor, private val uniqIdAware: DescriptorUniqIdAware) :
DescriptorReferenceDeserializer(currentModule, JvmMangler, builtIns = null, resolvedForwardDeclarations = mutableMapOf()),
DescriptorUniqIdAware by uniqIdAware {
override fun resolveSpecialDescriptor(fqn: FqName): ClassDescriptor {
error("Should never be called")
}
override fun checkIfSpecialDescriptorId(id: Long) = false
override fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long? = null
}
@@ -0,0 +1,85 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.jvm.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.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
class JvmDescriptorUniqIdAware(val symbolTable: SymbolTable, val stubGenerator: DeclarationStubGenerator) : DescriptorUniqIdAware {
override fun DeclarationDescriptor.getUniqId(): Long? =
when (this) {
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(KlibMetadataProtoBuf.classUniqId)?.index
?: referenceAndHash(this)
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.functionUniqId)?.index
?: referenceAndHash(this)
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.propertyUniqId)?.index
?: referenceAndHash(this)
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.constructorUniqId)?.index
?: referenceAndHash(this)
is DeserializedTypeParameterDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.typeParamUniqId)?.index
?: referenceAndHash(this)
is DeserializedTypeAliasDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.typeAliasUniqId)?.index
?: referenceAndHash(this)
else -> referenceAndHash(this)
}
private fun referenceAndHash(descriptor: DeclarationDescriptor): Long? =
if (descriptor is CallableMemberDescriptor && descriptor.kind === CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
null
else with(JvmMangler) {
referenceWithParents(descriptor).hashedMangle
}
private fun referenceWithParents(descriptor: DeclarationDescriptor): IrDeclaration {
val original = descriptor.original
val result = referenceOrDeclare(original)
var currentDescriptor = original
var current = result
// If current is a lazy declaration, the parent may already be set.
while (current.parent == null) {
val nextDescriptor = when {
currentDescriptor is TypeParameterDescriptor && currentDescriptor.containingDeclaration is PropertyDescriptor -> {
val property = currentDescriptor.containingDeclaration as PropertyDescriptor
// No way to choose between getter and setter by descriptor alone :(
property.getter ?: property.setter!!
}
else ->
currentDescriptor.containingDeclaration!!
}
if (nextDescriptor is PackageFragmentDescriptor) {
current.parent = symbolTable.findOrDeclareExternalPackageFragment(nextDescriptor)
break
} else {
val next = referenceOrDeclare(nextDescriptor)
current.parent = next as IrDeclarationParent
currentDescriptor = nextDescriptor
current = next
}
}
return result
}
private fun referenceOrDeclare(descriptor: DeclarationDescriptor): IrDeclaration =
symbolTable.referenceMember(descriptor).also {
if (!it.isBound) {
stubGenerator.getDeclaration(it)
}
}.owner as IrDeclaration
}
// May be needed in the future
//
//fun DeclarationDescriptor.willBeEliminatedInLowerings(): Boolean =
// isAnnotationConstructor() ||
// (this is PropertyAccessorDescriptor &&
// correspondingProperty.hasJvmFieldAnnotation())
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.jvm.serialization
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.UniqId
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
class JvmIrLinker(
currentModule: ModuleDescriptor,
logger: LoggingContext,
builtIns: IrBuiltIns,
symbolTable: SymbolTable,
stubGenerator: DeclarationStubGenerator
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, JvmMangler,
// TODO: Use protected shouldBeDeserialized() ?
tolerateNonKlibDescriptors = true),
DescriptorUniqIdAware {
override val descriptorReferenceDeserializer =
JvmDescriptorReferenceDeserializer(currentModule, JvmDescriptorUniqIdAware(symbolTable, stubGenerator))
override fun DeclarationDescriptor.getUniqId() = with(descriptorReferenceDeserializer) {
getUniqId()
}
override fun handleNoModuleDeserializerFound(key: UniqId): DeserializationState<*> {
return globalDeserializationState // !!!!!! Wrong, as external references will all have UniqId.NONE
}
override fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, uniqId: UniqId) =
moduleDescriptor.kotlinLibrary.irDeclaration(uniqId.index, fileIndex)
override fun readSymbol(moduleDescriptor: ModuleDescriptor, fileIndex: Int, symbolIndex: Int) =
moduleDescriptor.kotlinLibrary.symbol(symbolIndex, fileIndex)
override fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int) =
moduleDescriptor.kotlinLibrary.type(typeIndex, fileIndex)
override fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int) =
moduleDescriptor.kotlinLibrary.string(stringIndex, fileIndex)
override fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int) =
moduleDescriptor.kotlinLibrary.body(bodyIndex, fileIndex)
override fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int) =
moduleDescriptor.kotlinLibrary.file(fileIndex)
override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
moduleDescriptor.kotlinLibrary.fileCount()
override fun checkAccessibility(declarationDescriptor: DeclarationDescriptor): Boolean {
require(declarationDescriptor is DeclarationDescriptorWithVisibility)
return declarationDescriptor.isPublishedApi() ||
declarationDescriptor.visibility.let {
it.isPublicAPI || it == Visibilities.INTERNAL ||
it == JavaVisibilities.PACKAGE_VISIBILITY || it == JavaVisibilities.PROTECTED_AND_PACKAGE
}
}
private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.jvm.serialization
import org.jetbrains.kotlin.backend.common.LoggingContext
object EmptyLoggingContext: LoggingContext {
override var inVerbosePhase = false
override fun log(message: () -> String) {}
}