Minor changes in preparation for IR deserialization.

This commit is contained in:
Alexander Gorshenev
2018-08-03 19:26:23 +03:00
committed by alexander-gorshenev
parent 01ab4965b1
commit cea32bd4e3
15 changed files with 141 additions and 53 deletions
@@ -12,7 +12,11 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.name.FqName
interface CommonBackendContext : BackendContext {
interface LoggingContext {
fun log(message: () -> String)
}
interface CommonBackendContext : BackendContext, LoggingContext {
override val ir: Ir<CommonBackendContext>
//TODO move to builtins
@@ -23,7 +27,5 @@ interface CommonBackendContext : BackendContext {
//TODO move to builtins
fun getInternalFunctions(name: String): List<FunctionDescriptor>
fun log(message: () -> String)
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
}
@@ -21,14 +21,18 @@ import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.IrStatementsBuilder
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
@@ -334,4 +338,24 @@ val IrFunction.isStatic: Boolean
get() = parent is IrClass && dispatchReceiverParameter == null
val IrDeclaration.isTopLevel: Boolean
get() = parent is IrPackageFragment
get() = parent is IrPackageFragment
fun <T : IrElement> IrStatementsBuilder<T>.irTemporaryWithWrappedDescriptor(
value: IrExpression,
nameHint: String? = null): IrVariable {
val temporary = scope.createTemporaryVariableWithWrappedDescriptor(value, nameHint)
+temporary
return temporary
}
fun Scope.createTemporaryVariableWithWrappedDescriptor(
irExpression: IrExpression,
nameHint: String? = null,
isMutable: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE): IrVariable {
return createTemporaryVariableWithGivenDescriptor(
irExpression, nameHint, isMutable, origin, WrappedVariableDescriptor()
).apply { (this.descriptor as WrappedVariableDescriptor).bind(this) }
}
@@ -31,7 +31,9 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.types.toIrType
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.functions
@@ -55,9 +57,10 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
private val buildersStack = mutableListOf<IrBuilderWithScope>()
private val context = lower.context
private val builtIns = context.builtIns
private val irBuiltIns = context.irBuiltIns
private val typesWithSpecialAppendFunction =
PrimitiveType.values().map { builtIns.getPrimitiveKotlinType(it) } + builtIns.stringType
PrimitiveType.values().map { builtIns.getPrimitiveKotlinType(it).toIrType()!! } + irBuiltIns.stringType
private val nameToString = Name.identifier("toString")
private val nameAppend = Name.identifier("append")
@@ -79,7 +82,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
}
private val appendFunctions: Map<KotlinType, IrSimpleFunction?> =
private val appendFunctions: Map<IrType, IrSimpleFunction?> =
typesWithSpecialAppendFunction.map { type ->
type to stringBuilder.functions.toList().atMostOne {
it.name == nameAppend &&
@@ -88,7 +91,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
}
}.toMap()
private fun typeToAppendFunction(type: KotlinType): IrSimpleFunction {
private fun typeToAppendFunction(type: IrType): IrSimpleFunction {
return appendFunctions[type] ?: defaultAppendFunction
}
@@ -100,7 +103,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
return blockBuilder.irBlock(expression) {
val stringBuilderImpl = irTemporary(irCall(constructor))
expression.arguments.forEach { arg ->
val appendFunction = typeToAppendFunction(arg.type.toKotlinType())
val appendFunction = typeToAppendFunction(arg.type)
+irCall(appendFunction).apply {
dispatchReceiver = irGet(stringBuilderImpl)
putValueArgument(0, arg)
@@ -21,27 +21,23 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.DFS
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect"))
val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflection"))
val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines"))
fun IrType.isFunction(): Boolean {
fun IrType.isFunction() = this.isNameInPackage("Function", kotlinPackageFqn)
fun IrType.isKFunction() = this.isNameInPackage("KFunction", kotlinReflectionPackageFqn)
fun IrType.isSuspendFunction() = this.isNameInPackage("SuspendFunction", kotlinCoroutinesPackageFqn)
fun IrType.isNameInPackage(prefix: String, packageFqName: FqName): Boolean {
val classifier = classifierOrNull ?: return false
val name = classifier.descriptor.name.asString()
if (!name.startsWith("Function")) return false
if (!name.startsWith(prefix)) return false
val declaration = classifier.owner as IrDeclaration
val parent = declaration.parent as? IrPackageFragment ?: return false
return parent.fqName == kotlinPackageFqn
}
return parent.fqName == packageFqName
fun IrType.isKFunction(): Boolean {
val classifier = classifierOrNull ?: return false
val name = classifier.descriptor.name.asString()
if (!name.startsWith("KFunction")) return false
val declaration = classifier.owner as IrDeclaration
val parent = declaration.parent as? IrPackageFragment ?: return false
return parent.fqName == kotlinReflectionPackageFqn
}
@@ -88,4 +84,4 @@ fun IrType.isThrowable(): Boolean {
} else return false
}
fun IrType.isThrowableTypeOrSubtype() = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable)
fun IrType.isThrowableTypeOrSubtype() = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isThrowable)
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi.KtFile
@@ -53,11 +54,11 @@ class Psi2IrTranslator(
fun createGeneratorContext(moduleDescriptor: ModuleDescriptor, bindingContext: BindingContext, symbolTable: SymbolTable = SymbolTable()) =
GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable)
fun generateModuleFragment(context: GeneratorContext, ktFiles: Collection<KtFile>): IrModuleFragment {
fun generateModuleFragment(context: GeneratorContext, ktFiles: Collection<KtFile>, deserializer: IrDeserializer? = null): IrModuleFragment {
val moduleGenerator = ModuleGenerator(context)
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
postprocess(context, irModule)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer)
return irModule
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
@@ -39,9 +40,9 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
irModule.files.addAll(generateFiles(ktFiles))
}
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment, deserializer: IrDeserializer? = null) {
ExternalDependenciesGenerator(
irModule.descriptor, context.symbolTable, context.irBuiltIns
irModule.descriptor, context.symbolTable, context.irBuiltIns, deserializer
).generateUnboundSymbolsAsDependencies(irModule, context.bindingContext)
}
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
@@ -29,8 +26,10 @@ import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
@@ -90,6 +89,26 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
parent = getLocalDeclarationParent()
}
}
fun createTemporaryVariableWithGivenDescriptor(
irExpression: IrExpression,
nameHint: String? = null,
isMutable: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
descriptor: VariableDescriptor
): IrVariable {
return IrVariableImpl(
irExpression.startOffset, irExpression.endOffset, origin,
IrVariableSymbolImpl(descriptor),
Name.identifier(getNameForTemporary(nameHint)),
irExpression.type,
isVar = isMutable,
isConst = false,
isLateinit = false
).also {
it.initializer = irExpression
}
}
}
@Suppress("DeprecatedCallableAddReplaceWith")
@@ -42,10 +42,10 @@ val IrType.classifierOrFail: IrClassifierSymbol
val IrType.classifierOrNull: IrClassifierSymbol?
get() = safeAs<IrSimpleType>()?.classifier
fun IrType.makeNotNull() =
fun IrType.makeNotNull(addKotlinType:Boolean = true) =
if (this is IrSimpleType && this.hasQuestionMark)
IrSimpleTypeImpl(
makeKotlinType(classifier, arguments, false),
if (addKotlinType) makeKotlinType(classifier, arguments, false) else null,
classifier,
false,
arguments,
@@ -55,10 +55,10 @@ fun IrType.makeNotNull() =
else
this
fun IrType.makeNullable() =
fun IrType.makeNullable(addKotlinType:Boolean = true) =
if (this is IrSimpleType && !this.hasQuestionMark)
IrSimpleTypeImpl(
makeKotlinType(classifier, arguments, true),
if (addKotlinType) makeKotlinType(classifier, arguments, true) else null,
classifier,
true,
arguments,
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.declarations.lazy.*
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
@@ -34,7 +36,8 @@ class DeclarationStubGenerator(
moduleDescriptor: ModuleDescriptor,
val symbolTable: SymbolTable,
val origin: IrDeclarationOrigin,
val languageVersionSettings: LanguageVersionSettings
val languageVersionSettings: LanguageVersionSettings,
val deserializer: IrDeserializer? = null
) {
private val lazyTable = symbolTable.lazyWrapper
@@ -83,6 +86,7 @@ class DeclarationStubGenerator(
descriptor: PropertyDescriptor,
bindingContext: BindingContext? = null
): IrProperty = symbolTable.referenceProperty(descriptor) {
deserializer?.findDeserializedDeclaration(descriptor) as IrProperty? ?:
IrLazyProperty(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor,
this, typeTranslator, bindingContext
@@ -106,8 +110,10 @@ class DeclarationStubGenerator(
origin,
descriptor.original,
descriptor.type.toIrType()
).apply {
correspondingProperty = generatePropertyStub(descriptor, bindingContext)
) {
deserializer?.findDeserializedDeclaration(referenced) as IrField? ?:
IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, descriptor.type.toIrType())
}.apply {
initializer = descriptor.compileTimeInitializer?.let {
IrExpressionBodyImpl(
constantValueGenerator.generateConstantValueAsExpression(
@@ -142,7 +148,10 @@ class DeclarationStubGenerator(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
origin,
descriptor.original
) { IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
) {
deserializer?.findDeserializedDeclaration(referenced) as IrSimpleFunction? ?:
IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
internal fun generateConstructorStub(descriptor: ClassConstructorDescriptor): IrConstructor {
@@ -153,7 +162,10 @@ class DeclarationStubGenerator(
return symbolTable.declareConstructor(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original
) { IrLazyConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
) {
deserializer?.findDeserializedDeclaration(referenced) as IrConstructor? ?:
IrLazyConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
@@ -182,7 +194,10 @@ class DeclarationStubGenerator(
}
return symbolTable.declareClass(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor
) { IrLazyClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator) }
) {
deserializer?.findDeserializedDeclaration(referenceClass) as IrClass? ?:
IrLazyClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
internal fun generateEnumEntryStub(descriptor: ClassDescriptor): IrEnumEntry {
@@ -191,6 +206,7 @@ class DeclarationStubGenerator(
return referenced.owner
}
return symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
deserializer?.findDeserializedDeclaration(referenced) as IrEnumEntry? ?:
IrLazyEnumEntryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -201,6 +217,7 @@ class DeclarationStubGenerator(
return referenced.owner
}
return symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
deserializer?.findDeserializedDeclaration(referenced) as IrTypeParameter? ?:
IrLazyTypeParameter(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin,
it, this, typeTranslator
@@ -220,4 +237,4 @@ class DeclarationStubGenerator(
)
}
}
}
}
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
@@ -200,16 +202,25 @@ open class DeepCopyIrTreeWithSymbols(
}
override fun visitProperty(declaration: IrProperty): IrProperty =
IrPropertyImpl(
declaration.startOffset, declaration.endOffset,
IrPropertyImpl(declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
declaration.descriptor,
declaration.name,
declaration.visibility,
declaration.modality,
declaration.isVar,
declaration.isConst,
declaration.isLateinit,
declaration.isDelegated,
declaration.descriptor, // TODO
declaration.backingField?.transform(),
declaration.getter?.transform(),
declaration.setter?.transform()
declaration.isExternal
).apply {
transformAnnotations(declaration)
this.backingField = declaration.backingField?.transform()
this.getter = declaration.getter?.transform()
this.setter = declaration.setter?.transform()
this.backingField?.let {
it.correspondingProperty = this
}
}
override fun visitField(declaration: IrField): IrField =
@@ -81,7 +81,10 @@ open class DeepCopySymbolRemapper(
override fun visitField(declaration: IrField) {
remapSymbol(fields, declaration) {
IrFieldSymbolImpl(descriptorsRemapper.remapDeclaredField(it.descriptor))
if (declaration.correspondingProperty == null)
IrFieldSymbolImpl(descriptorsRemapper.remapDeclaredField(it.descriptor))
else
IrFieldSymbolImpl(descriptorsRemapper.remapDeclaredProperty(it.descriptor))
}
declaration.acceptChildrenVoid(this)
}
@@ -25,6 +25,7 @@ interface DescriptorsRemapper {
fun remapDeclaredExternalPackageFragment(descriptor: PackageFragmentDescriptor): PackageFragmentDescriptor = descriptor
fun remapDeclaredField(descriptor: PropertyDescriptor): PropertyDescriptor = descriptor
fun remapDeclaredFilePackageFragment(descriptor: PackageFragmentDescriptor): PackageFragmentDescriptor = descriptor
fun remapDeclaredProperty(descriptor: PropertyDescriptor): PropertyDescriptor = descriptor
fun remapDeclaredSimpleFunction(descriptor: FunctionDescriptor): FunctionDescriptor = descriptor
fun remapDeclaredTypeParameter(descriptor: TypeParameterDescriptor): TypeParameterDescriptor = descriptor
fun remapDeclaredValueParameter(descriptor: ParameterDescriptor): ParameterDescriptor = descriptor
@@ -178,8 +178,9 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
dumpTypeArguments(expression)
expression.dispatchReceiver?.accept(this, "\$this")
expression.extensionReceiver?.accept(this, "\$receiver")
for (valueParameter in expression.descriptor.valueParameters) {
expression.getValueArgument(valueParameter.index)?.accept(this, valueParameter.name.asString())
for (i in 0..expression.valueArgumentsCount - 1) {
val valueArgument = expression.getValueArgument(i)
valueArgument?.accept(this, "argument $i")
}
}
}
@@ -25,10 +25,11 @@ import org.jetbrains.kotlin.resolve.BindingContext
class ExternalDependenciesGenerator(
moduleDescriptor: ModuleDescriptor,
val symbolTable: SymbolTable,
val irBuiltIns: IrBuiltIns
val irBuiltIns: IrBuiltIns,
val deserializer: IrDeserializer? = null
) {
private val stubGenerator = DeclarationStubGenerator(
moduleDescriptor, symbolTable, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, irBuiltIns.languageVersionSettings
moduleDescriptor, symbolTable, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, irBuiltIns.languageVersionSettings, deserializer
)
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment, bindingContext: BindingContext? = null) {
@@ -58,6 +59,8 @@ class ExternalDependenciesGenerator(
stubGenerator.generateOrGetTypeParameterStub(it.descriptor)
}
deserializer?.declareForwardDeclarations()
assert(symbolTable.unboundClasses.isEmpty())
assert(symbolTable.unboundConstructors.isEmpty())
assert(symbolTable.unboundEnumEntries.isEmpty())
@@ -32,6 +32,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
interface IrDeserializer {
fun findDeserializedDeclaration(symbol: IrSymbol): IrDeclaration?
fun findDeserializedDeclaration(propertyDescriptor: PropertyDescriptor): IrProperty?
fun declareForwardDeclarations()
}
interface ReferenceSymbolTable {
fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol