JVM IR: generate Kotlin metadata

Introduce MetadataSource as a way to store the original descriptor for
any element (before any lowerings) and maintain it until the end of the
codegen where it's used in generating the metadata. Note that JVM
signatures written to the metadata are formed from the _resulting_
generated elements, not by mapping the original descriptors.

Some corner cases are not supported yet, namely properties declared in
companion objects, synthetic methods for property annotations,
JvmPackageName, etc.

 #KT-29119 Fixed
This commit is contained in:
Alexander Udalov
2019-02-07 19:34:46 +01:00
parent 3d1858a8c5
commit c357967c2c
108 changed files with 157 additions and 121 deletions
@@ -28,7 +28,11 @@ interface IrSymbolOwner : IrElement {
val symbol: IrSymbol
}
interface IrDeclaration : IrStatement, IrAnnotationContainer {
interface IrMetadataSourceOwner : IrElement {
val metadata: MetadataSource?
}
interface IrDeclaration : IrStatement, IrAnnotationContainer, IrMetadataSourceOwner {
val descriptor: DeclarationDescriptor
var origin: IrDeclarationOrigin
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.types.IrType
interface IrField : IrSymbolDeclaration<IrFieldSymbol>, IrOverridableDeclaration<IrFieldSymbol>,
IrDeclarationWithName, IrDeclarationWithVisibility, IrDeclarationParent {
IrDeclarationWithName, IrDeclarationWithVisibility, IrDeclarationParent {
override val descriptor: PropertyDescriptor
val type: IrType
@@ -21,4 +21,6 @@ interface IrField : IrSymbolDeclaration<IrFieldSymbol>, IrOverridableDeclaration
var initializer: IrExpressionBody?
var correspondingProperty: IrProperty?
override val metadata: MetadataSource.Property?
}
@@ -38,12 +38,14 @@ interface IrExternalPackageFragment : IrPackageFragment {
override val symbol: IrExternalPackageFragmentSymbol
}
interface IrFile : IrPackageFragment, IrAnnotationContainer {
interface IrFile : IrPackageFragment, IrAnnotationContainer, IrMetadataSourceOwner {
override val symbol: IrFileSymbol
val fileEntry: SourceManager.FileEntry
val fileAnnotations: MutableList<AnnotationDescriptor>
override val metadata: MetadataSource.File?
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrFile =
accept(transformer, data) as IrFile
}
@@ -38,6 +38,8 @@ interface IrFunction :
val valueParameters: MutableList<IrValueParameter>
var body: IrBody?
override val metadata: MetadataSource.Function?
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.declarations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
interface MetadataSource {
class Class(val descriptor: ClassDescriptor) : MetadataSource
class File(val descriptors: List<DeclarationDescriptor>) : MetadataSource
class Function(val descriptor: FunctionDescriptor) : MetadataSource
class Property(val descriptor: PropertyDescriptor) : MetadataSource
}
@@ -102,6 +102,8 @@ class IrClassImpl(
override val superTypes: MutableList<IrType> = SmartList()
override var metadata: MetadataSource? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.expressions.IrCall
abstract class IrDeclarationBase(
@@ -32,4 +33,7 @@ abstract class IrDeclarationBase(
override lateinit var parent: IrDeclarationParent
override val annotations: MutableList<IrCall> = ArrayList()
}
override val metadata: MetadataSource?
get() = null
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
@@ -90,6 +91,8 @@ class IrFieldImpl(
override var correspondingProperty: IrProperty? = null
override val overriddenSymbols: MutableList<IrFieldSymbol> = mutableListOf()
override var metadata: MetadataSource.Property? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitField(this, data)
}
@@ -101,4 +104,4 @@ class IrFieldImpl(
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
initializer = initializer?.transform(transformer, data)
}
}
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
@@ -72,6 +73,8 @@ class IrFileImpl(
override val annotations: MutableList<IrCall> = ArrayList()
override var metadata: MetadataSource.File? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFile(this, data)
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
@@ -58,6 +55,8 @@ abstract class IrFunctionBase(
final override var body: IrBody? = null
override var metadata: MetadataSource.Function? = null
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
typeParameters.forEach { it.accept(visitor, data) }
@@ -77,4 +76,4 @@ abstract class IrFunctionBase(
body = body?.transform(transformer, data)
}
}
}
@@ -8,17 +8,13 @@ package org.jetbrains.kotlin.ir.declarations.lazy
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinType
import kotlin.reflect.KProperty
abstract class IrLazyDeclarationBase(
startOffset: Int,
@@ -53,6 +49,10 @@ abstract class IrLazyDeclarationBase(
override val annotations: MutableList<IrCall> = arrayListOf()
override var metadata: Nothing?
get() = null
set(_) = error("We should never need to store metadata of external declarations.")
private fun createLazyParent(): IrDeclarationParent? {
val currentDescriptor = descriptor
@@ -67,4 +67,4 @@ abstract class IrLazyDeclarationBase(
else -> throw AssertionError("Package or class expected: $containingDeclaration; for $currentDescriptor")
}
}
}
}
@@ -233,7 +233,9 @@ open class SymbolTable : ReferenceSymbolTable {
fun declareClass(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
modality: Modality = descriptor.modality,
classFactory: (IrClassSymbol) -> IrClass = { IrClassImpl(startOffset, endOffset, origin, it, modality) }
classFactory: (IrClassSymbol) -> IrClass = {
IrClassImpl(startOffset, endOffset, origin, it, modality).apply { metadata = MetadataSource.Class(it.descriptor) }
}
): IrClass {
return classSymbolTable.declare(
descriptor,
@@ -252,7 +254,11 @@ open class SymbolTable : ReferenceSymbolTable {
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ClassConstructorDescriptor,
constructorFactory: (IrConstructorSymbol) -> IrConstructor = { IrConstructorImpl(startOffset, endOffset, origin, it, IrUninitializedType) }
constructorFactory: (IrConstructorSymbol) -> IrConstructor = {
IrConstructorImpl(startOffset, endOffset, origin, it, IrUninitializedType).apply {
metadata = MetadataSource.Function(it.descriptor)
}
}
): IrConstructor =
constructorSymbolTable.declare(
descriptor,
@@ -286,7 +292,11 @@ open class SymbolTable : ReferenceSymbolTable {
origin: IrDeclarationOrigin,
descriptor: PropertyDescriptor,
type: IrType,
fieldFactory: (IrFieldSymbol) -> IrField = { IrFieldImpl(startOffset, endOffset, origin, it, type) }
fieldFactory: (IrFieldSymbol) -> IrField = {
IrFieldImpl(startOffset, endOffset, origin, it, type).apply {
metadata = MetadataSource.Property(it.descriptor)
}
}
): IrField =
fieldSymbolTable.declare(
descriptor,
@@ -320,7 +330,11 @@ open class SymbolTable : ReferenceSymbolTable {
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: FunctionDescriptor,
functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction = { IrFunctionImpl(startOffset, endOffset, origin, it, IrUninitializedType) }
functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction = {
IrFunctionImpl(startOffset, endOffset, origin, it, IrUninitializedType).apply {
metadata = MetadataSource.Function(it.descriptor)
}
}
): IrSimpleFunction {
return simpleFunctionSymbolTable.declare(
descriptor,