Fake wrapped descriptors first working draft

get rid of descriptors in Bridge and Enum lowerings
Replace property accessors function type with IrSimpleFunction because they couldn't be constructors
get rid of descriptors in Callable reference lowering
refactored descriptor factory and inner class lowering
Add isReified property to IrTypeParameter declaration
keep getting rid of descriptors
Get rid of descriptors in Shared Variable Manager
LocalDeclarationLowering also uses no descriptors
Fix psi2ir
Fix nested classes names
Fix outer reference in inner classes
Fix name generator
get rid of descriptors in coroutines - something is working
Fix name generator
Fix unbound symbols in JVM BE
Rename DeclarationFactory members
This commit is contained in:
Roman Artemev
2018-07-25 23:03:09 +03:00
committed by romanart
parent daadba0927
commit d1621b80cc
88 changed files with 3138 additions and 2716 deletions
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.common.descriptors.DescriptorsFactory
import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager
import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory
import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -27,5 +27,5 @@ interface BackendContext {
val builtIns: KotlinBuiltIns
val irBuiltIns: IrBuiltIns
val sharedVariablesManager: SharedVariablesManager
val descriptorsFactory: DescriptorsFactory
val declarationFactory: DeclarationFactory
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.util.usesDefaultArguments
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -35,7 +36,7 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
* However any returned call can be correctly optimized as tail recursion.
*/
fun collectTailRecursionCalls(irFunction: IrFunction): Set<IrCall> {
if (!irFunction.descriptor.isTailrec) {
if ((irFunction as? IrSimpleFunction)?.isTailrec != true) {
return emptySet()
}
@@ -1,20 +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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.common.descriptors
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
interface DescriptorsFactory {
fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol
fun getOuterThisFieldSymbol(innerClass: IrClass): IrFieldSymbol
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructorSymbol
fun getSymbolForObjectInstance(singleton: IrClassSymbol): IrFieldSymbol
}
@@ -0,0 +1,568 @@
/*
* 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.common.descriptors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.types.*
abstract class WrappedDeclarationDescriptor<T : IrDeclaration>(override val annotations: Annotations) : DeclarationDescriptor {
lateinit var owner: T
fun bind(declaration: T) { owner = declaration }
}
abstract class WrappedCallableDescriptor<T : IrDeclaration>(
annotations: Annotations,
private val sourceElement: SourceElement
) : CallableDescriptor, WrappedDeclarationDescriptor<T>(annotations) {
override fun getOriginal() = this
override fun substitute(substitutor: TypeSubstitutor): CallableDescriptor {
TODO("not implemented")
}
override fun getOverriddenDescriptors(): Collection<CallableDescriptor> {
TODO("not implemented")
}
override fun getSource() = sourceElement
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = null
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
override fun getTypeParameters(): List<TypeParameterDescriptor> {
TODO("not implemented")
}
override fun getReturnType(): KotlinType? {
TODO("not implemented")
}
override fun getValueParameters(): MutableList<ValueParameterDescriptor> {
TODO("not implemented")
}
override fun hasStableParameterNames(): Boolean {
TODO("not implemented")
}
override fun hasSynthesizedParameterNames() = false
override fun getVisibility(): Visibility {
TODO("not implemented")
}
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R {
TODO("not implemented")
}
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
TODO("not implemented")
}
}
open class WrappedValueParameterDescriptor(
annotations: Annotations = Annotations.EMPTY,
sourceElement: SourceElement = SourceElement.NO_SOURCE
) : ValueParameterDescriptor, WrappedCallableDescriptor<IrValueParameter>(annotations, sourceElement) {
override val index get() = owner.index
override val isCrossinline get() = owner.isCrossinline
override val isNoinline get() = owner.isNoinline
override val varargElementType get() = owner.varargElementType?.toKotlinType()
override fun isConst() = false
override fun isVar() = false
override fun getContainingDeclaration() = (owner.parent as IrFunction).descriptor
override fun getType() = owner.type.toKotlinType()
override fun getName() = owner.name
override fun declaresDefaultValue() = owner.defaultValue != null
override fun getCompileTimeInitializer(): ConstantValue<*>? = null
override fun copy(newOwner: CallableDescriptor, newName: Name, newIndex: Int) = object : WrappedValueParameterDescriptor() {
override fun getContainingDeclaration() = newOwner as FunctionDescriptor
override fun getName() = newName
override val index = newIndex
}.also { it.bind(owner) }
override fun getOverriddenDescriptors(): Collection<ValueParameterDescriptor> = emptyList()
override fun getOriginal() = this
override fun substitute(substitutor: TypeSubstitutor): ValueParameterDescriptor {
TODO("")
}
override fun getReturnType(): KotlinType? = owner.type.toKotlinType()
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D) =
visitor!!.visitValueParameterDescriptor(this, data)!!
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitValueParameterDescriptor(this, null)
}
}
open class WrappedTypeParameterDescriptor(
annotations: Annotations = Annotations.EMPTY,
sourceElement: SourceElement = SourceElement.NO_SOURCE
) : TypeParameterDescriptor, WrappedCallableDescriptor<IrTypeParameter>(annotations, sourceElement) {
override fun getName() = owner.name
override fun isReified() = owner.isReified
override fun getVariance() = owner.variance
override fun getUpperBounds() = owner.superTypes.map { it.toKotlinType() }
override fun getTypeConstructor(): TypeConstructor {
return object : TypeConstructor {
override fun getParameters(): List<TypeParameterDescriptor> {
TODO("not implemented")
}
override fun getSupertypes() = upperBounds
override fun isFinal() = false
override fun isDenotable() = false
override fun getDeclarationDescriptor() = owner.descriptor
override fun getBuiltIns(): KotlinBuiltIns {
TODO("not implemented")
}
}
}
override fun getOriginal() = this
override fun getIndex() = owner.index
override fun isCapturedFromOuterDeclaration() = false
override fun getDefaultType(): SimpleType {
TODO("not implemented")
}
override fun getContainingDeclaration() = (owner.parent as IrDeclaration).descriptor
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R =
visitor!!.visitTypeParameterDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitTypeParameterDescriptor(this, null)
}
}
open class WrappedVariableDescriptor(
annotations: Annotations = Annotations.EMPTY,
sourceElement: SourceElement = SourceElement.NO_SOURCE
) : VariableDescriptor, WrappedCallableDescriptor<IrVariable>(annotations, sourceElement) {
override fun getContainingDeclaration() = (owner.parent as IrFunction).descriptor
override fun getType() = owner.type.toKotlinType()
override fun getName() = owner.name
override fun isConst() = owner.isConst
override fun isVar() = owner.isVar
override fun isLateInit() = owner.isLateinit
override fun getCompileTimeInitializer(): ConstantValue<*>? {
TODO("")
}
override fun getOverriddenDescriptors(): Collection<VariableDescriptor> {
TODO("Not Implemented")
}
override fun getOriginal() = this
override fun substitute(substitutor: TypeSubstitutor): VariableDescriptor {
TODO("")
}
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R =
visitor!!.visitVariableDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitVariableDescriptor(this, null)
}
}
open class WrappedSimpleFunctionDescriptor(
annotations: Annotations = Annotations.EMPTY,
sourceElement: SourceElement = SourceElement.NO_SOURCE
) : SimpleFunctionDescriptor, WrappedCallableDescriptor<IrSimpleFunction>(annotations, sourceElement) {
override fun getOverriddenDescriptors() = owner.overriddenSymbols.map { it.descriptor }
override fun getContainingDeclaration() = (owner.parent as IrSymbolOwner).symbol.descriptor
override fun getModality() = owner.modality
override fun getName() = owner.name
override fun getVisibility() = owner.visibility
override fun getReturnType() = owner.returnType.toKotlinType()
override fun getDispatchReceiverParameter() = owner.dispatchReceiverParameter?.run {
(containingDeclaration as ClassDescriptor).thisAsReceiverParameter
}
val extensionReceiver by lazy {
owner.extensionReceiverParameter?.let {
ReceiverParameterDescriptorImpl(this, ExtensionReceiver(it.descriptor, it.type.toKotlinType(), null))
}
}
override fun getExtensionReceiverParameter() = extensionReceiver
override fun getTypeParameters() = owner.typeParameters.map { it.descriptor }
override fun getValueParameters() = owner.valueParameters
.asSequence()
.mapNotNull { it.descriptor as? ValueParameterDescriptor }
.toMutableList()
override fun isExternal() = owner.isExternal
override fun isSuspend() = owner.isSuspend
override fun isTailrec() = owner.isTailrec
override fun isInline() = owner.isInline
override fun isExpect() = false
override fun isActual() = false
override fun isInfix() = false
override fun isOperator() = false
override fun getOriginal() = this
override fun substitute(substitutor: TypeSubstitutor): SimpleFunctionDescriptor {
TODO("")
}
override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) {
TODO("not implemented")
}
override fun getKind() =
if (owner.origin == IrDeclarationOrigin.FAKE_OVERRIDE) CallableMemberDescriptor.Kind.FAKE_OVERRIDE
else CallableMemberDescriptor.Kind.SYNTHESIZED
override fun isHiddenToOvercomeSignatureClash(): Boolean {
TODO("not implemented")
}
override fun copy(
newOwner: DeclarationDescriptor?,
modality: Modality?,
visibility: Visibility?,
kind: CallableMemberDescriptor.Kind?,
copyOverrides: Boolean
): SimpleFunctionDescriptor {
TODO("not implemented")
}
override fun isHiddenForResolutionEverywhereBesideSupercalls(): Boolean {
TODO("not implemented")
}
override fun getInitialSignatureDescriptor() = null
override fun <V : Any?> getUserData(key: FunctionDescriptor.UserDataKey<V>?): V? = null
override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out SimpleFunctionDescriptor> {
TODO("not implemented")
}
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D) =
visitor!!.visitFunctionDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitFunctionDescriptor(this, null)
}
}
open class WrappedClassConstructorDescriptor(
annotations: Annotations = Annotations.EMPTY,
sourceElement: SourceElement = SourceElement.NO_SOURCE
) : ClassConstructorDescriptor, WrappedCallableDescriptor<IrConstructor>(annotations, sourceElement) {
override fun getContainingDeclaration() = (owner.parent as IrClass).descriptor
override fun getTypeParameters() = owner.typeParameters.map { it.descriptor }
override fun getValueParameters() = owner.valueParameters.asSequence()
.mapNotNull { it.descriptor as? ValueParameterDescriptor }
.toMutableList()
override fun getOriginal() = this
override fun substitute(substitutor: TypeSubstitutor): ClassConstructorDescriptor {
TODO("not implemented")
}
override fun copy(
newOwner: DeclarationDescriptor,
modality: Modality,
visibility: Visibility,
kind: CallableMemberDescriptor.Kind,
copyOverrides: Boolean
): ClassConstructorDescriptor {
TODO("not implemented")
}
override fun getModality() = Modality.FINAL
override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) {
TODO("not implemented")
}
override fun getKind() = CallableMemberDescriptor.Kind.SYNTHESIZED
override fun getConstructedClass() = (owner.parent as IrClass).descriptor
override fun getName() = owner.name
override fun getOverriddenDescriptors(): MutableCollection<out FunctionDescriptor> = mutableListOf()
override fun getInitialSignatureDescriptor(): FunctionDescriptor? = null
override fun getVisibility() = owner.visibility
override fun isHiddenToOvercomeSignatureClash(): Boolean {
TODO("not implemented")
}
override fun isOperator() = false
override fun isInline() = owner.isInline
override fun isHiddenForResolutionEverywhereBesideSupercalls(): Boolean {
TODO("not implemented")
}
override fun getReturnType() = owner.returnType.toKotlinType()
override fun isPrimary() = owner.isPrimary
override fun isExpect() = false
override fun isTailrec() = false
override fun isActual() = false
override fun isInfix() = false
override fun isSuspend() = false
override fun <V : Any?> getUserData(key: FunctionDescriptor.UserDataKey<V>?): V? = null
override fun isExternal() = owner.isExternal
override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out FunctionDescriptor> {
TODO("not implemented")
}
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R =
visitor!!.visitConstructorDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitConstructorDescriptor(this, null)
}
}
open class WrappedClassDescriptor(
annotations: Annotations = Annotations.EMPTY,
private val sourceElement: SourceElement = SourceElement.NO_SOURCE
) : ClassDescriptor, WrappedDeclarationDescriptor<IrClass>(annotations) {
override fun getName() = owner.name
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope {
TODO("not implemented")
}
override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope {
TODO("not implemented")
}
override fun getUnsubstitutedMemberScope(): MemberScope {
TODO("not implemented")
}
override fun getUnsubstitutedInnerClassesScope(): MemberScope {
TODO("not implemented")
}
override fun getStaticScope(): MemberScope {
TODO("not implemented")
}
override fun getSource() = sourceElement
override fun getConstructors() = owner.declarations.asSequence().filterIsInstance<IrConstructor>().map { it.descriptor }.toList()
override fun getContainingDeclaration() = (owner.parent as IrSymbolOwner).symbol.descriptor
override fun getDefaultType(): SimpleType {
TODO("not implemented")
}
override fun getKind() = owner.kind
override fun getModality() = owner.modality
override fun getCompanionObjectDescriptor() = owner.declarations.filterIsInstance<IrClass>().firstOrNull { it.isCompanion }?.descriptor
override fun getVisibility() = owner.visibility
override fun isCompanionObject() = owner.isCompanion
override fun isData() = owner.isData
override fun isInline() = owner.isInline
override fun getThisAsReceiverParameter() = owner.thisReceiver?.descriptor as ReceiverParameterDescriptor
override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? {
TODO("not implemented")
}
override fun getDeclaredTypeParameters() = owner.typeParameters.map { it.descriptor }
override fun getSealedSubclasses(): Collection<ClassDescriptor> {
TODO("not implemented")
}
override fun getOriginal() = this
override fun isExpect() = false
override fun substitute(substitutor: TypeSubstitutor): ClassifierDescriptorWithTypeParameters {
TODO("not implemented")
}
override fun isActual() = false
override fun getTypeConstructor(): TypeConstructor {
TODO("not implemented")
}
override fun isInner() = owner.isInner
override fun isExternal() = owner.isExternal
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R =
visitor!!.visitClassDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitClassDescriptor(this, null)
}
}
open class WrappedPropertyDescriptor(
annotations: Annotations = Annotations.EMPTY,
private val sourceElement: SourceElement = SourceElement.NO_SOURCE
) : PropertyDescriptor, WrappedDeclarationDescriptor<IrField>(annotations) {
override fun getModality() = if (owner.isFinal) Modality.FINAL else Modality.OPEN
override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) {
TODO("not implemented")
}
override fun getKind() = CallableMemberDescriptor.Kind.SYNTHESIZED
override fun getName() = owner.name
override fun getSource() = sourceElement
override fun hasSynthesizedParameterNames(): Boolean {
TODO("not implemented")
}
override fun getOverriddenDescriptors(): MutableCollection<out PropertyDescriptor> = mutableListOf()
override fun copy(
newOwner: DeclarationDescriptor?,
modality: Modality?,
visibility: Visibility?,
kind: CallableMemberDescriptor.Kind?,
copyOverrides: Boolean
): CallableMemberDescriptor {
TODO("not implemented")
}
override fun getValueParameters(): MutableList<ValueParameterDescriptor> = mutableListOf()
override fun getCompileTimeInitializer(): ConstantValue<*>? {
TODO("not implemented")
}
override fun isSetterProjectedOut(): Boolean {
TODO("not implemented")
}
override fun getAccessors(): MutableList<PropertyAccessorDescriptor> = mutableListOf()
override fun getTypeParameters() = emptyList()
override fun getVisibility() = owner.visibility
override val setter: PropertySetterDescriptor? get() = null
override fun getOriginal() = this
override fun isExpect() = false
override fun substitute(substitutor: TypeSubstitutor): PropertyDescriptor {
TODO("not implemented")
}
override fun isActual() = false
override fun getReturnType() = owner.type.toKotlinType()
override fun hasStableParameterNames(): Boolean {
TODO("not implemented")
}
override fun getType(): KotlinType = owner.type.toKotlinType()
override fun isVar() = owner.isFinal
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? {
TODO("not implemented")
}
override fun isConst() = false
override fun getContainingDeclaration() = (owner.parent as IrSymbolOwner).symbol.descriptor
override fun isLateInit() = false
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? {
TODO("not implemented")
}
override fun isExternal() = owner.isExternal
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D) =
visitor!!.visitPropertyDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitPropertyDescriptor(this, null)
}
override val getter: PropertyGetterDescriptor? get() = null
override fun newCopyBuilder(): CallableMemberDescriptor.CopyBuilder<out PropertyDescriptor> {
TODO("not implemented")
}
override val isDelegated get() = false
}
@@ -0,0 +1,18 @@
/*
* 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.common.ir
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.IrType
interface DeclarationFactory {
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
fun getFieldForEnumEntry(enumEntry: IrEnumEntry, type: IrType): IrField
fun getOuterThisField(innerClass: IrClass): IrField
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: IrConstructor): IrConstructor
fun getFieldForObjectInstance(singleton: IrClass): IrField
}
@@ -25,7 +25,7 @@ abstract class Ir<out T : CommonBackendContext>(val context: T, val irModule: Ir
abstract val symbols: Symbols<T>
val defaultParameterDeclarationsCache = mutableMapOf<FunctionDescriptor, IrFunction>()
val defaultParameterDeclarationsCache = mutableMapOf<IrFunction, IrFunction>()
open fun shouldGenerateHandlerParameterForDefaultBodyFun() = false
}
@@ -17,18 +17,25 @@
package org.jetbrains.kotlin.backend.common.ir
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
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.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
import org.jetbrains.kotlin.ir.util.defaultType
import java.io.StringWriter
@@ -133,3 +140,40 @@ fun IrClass.addSimpleDelegatingConstructor(
this.declarations.add(constructor)
}
}
val IrCall.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
val IrFunctionReference.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
fun IrValueParameter.copyTo(irFunction: IrFunction, shift: Int = 0): IrValueParameter {
val descriptor = WrappedValueParameterDescriptor(symbol.descriptor.annotations, symbol.descriptor.source)
val symbol = IrValueParameterSymbolImpl(descriptor)
return IrValueParameterImpl(
startOffset, endOffset, origin, symbol,
name, shift + index, type, varargElementType, isCrossinline, isNoinline
).also {
descriptor.bind(it)
it.parent = irFunction
}
}
fun IrTypeParameter.copyTo(irFunction: IrFunction, shift: Int = 0): IrTypeParameter {
val descriptor = WrappedTypeParameterDescriptor(symbol.descriptor.annotations, symbol.descriptor.source)
val symbol = IrTypeParameterSymbolImpl(descriptor)
return IrTypeParameterImpl(startOffset, endOffset, origin, symbol, name, shift + index, isReified, variance).also {
descriptor.bind(it)
it.parent = irFunction
}
}
fun IrFunction.copyParameterDeclarationsFrom(from: IrFunction) {
dispatchReceiverParameter = from.dispatchReceiverParameter?.copyTo(this)
extensionReceiverParameter = from.extensionReceiverParameter?.copyTo(this)
val shift = valueParameters.size
valueParameters += from.valueParameters.map { it.copyTo(this, shift) }
assert(typeParameters.isEmpty())
from.typeParameters.mapTo(typeParameters) { it.copyTo(this) }
}
@@ -1,20 +1,9 @@
/*
* Copyright 2010-2017 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.
* 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.common.descriptors
package org.jetbrains.kotlin.backend.common.ir
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrVariable
@@ -16,13 +16,12 @@
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.backend.common.peek
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCatch
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrValueAccessExpression
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -33,27 +32,27 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
// TODO: rename the file.
class Closure(val capturedValues: List<IrValueSymbol> = emptyList())
class ClosureAnnotator {
private val closureBuilders = mutableMapOf<DeclarationDescriptor, ClosureBuilder>()
class ClosureAnnotator(declaration: IrDeclaration) {
private val closureBuilders = mutableMapOf<IrDeclaration, ClosureBuilder>()
constructor(declaration: IrDeclaration) {
init {
// Collect all closures for classes and functions. Collect call graph
declaration.acceptChildrenVoid(ClosureCollectorVisitor())
}
fun getFunctionClosure(descriptor: FunctionDescriptor) = getClosure(descriptor)
fun getClassClosure(descriptor: ClassDescriptor) = getClosure(descriptor)
fun getFunctionClosure(declaration: IrFunction) = getClosure(declaration)
fun getClassClosure(declaration: IrClass) = getClosure(declaration)
private fun getClosure(descriptor: DeclarationDescriptor) : Closure {
private fun getClosure(declaration: IrDeclaration): Closure {
closureBuilders.values.forEach { it.processed = false }
return closureBuilders
.getOrElse(descriptor) { throw AssertionError("No closure builder for passed descriptor.") }
.buildClosure()
.getOrElse(declaration) { throw AssertionError("No closure builder for passed descriptor.") }
.buildClosure()
}
private class ClosureBuilder(val owner: DeclarationDescriptor) {
private class ClosureBuilder(val owner: IrDeclaration) {
val capturedValues = mutableSetOf<IrValueSymbol>()
private val declaredValues = mutableSetOf<ValueDescriptor>()
private val declaredValues = mutableSetOf<IrValueDeclaration>()
private val includes = mutableSetOf<ClosureBuilder>()
var processed = false
@@ -65,10 +64,10 @@ class ClosureAnnotator {
*/
fun buildClosure(): Closure {
val result = mutableSetOf<IrValueSymbol>().apply { addAll(capturedValues) }
includes.forEach {
if (!it.processed) {
it.processed = true
it.buildClosure().capturedValues.filterTo(result) { isExternal(it.descriptor) }
includes.forEach { builder ->
if (!builder.processed) {
builder.processed = true
builder.buildClosure().capturedValues.filterTo(result) { isExternal(it.owner) }
}
}
// TODO: We can save the closure and reuse it.
@@ -80,20 +79,19 @@ class ClosureAnnotator {
includes.add(includingBuilder)
}
fun declareVariable(valueDescriptor: ValueDescriptor?) {
if (valueDescriptor != null)
declaredValues.add(valueDescriptor)
fun declareVariable(valueDeclaration: IrValueDeclaration?) {
if (valueDeclaration != null)
declaredValues.add(valueDeclaration)
}
fun seeVariable(value: IrValueSymbol) {
if (isExternal(value.descriptor))
if (isExternal(value.owner))
capturedValues.add(value)
}
fun isExternal(valueDescriptor: ValueDescriptor): Boolean {
return !declaredValues.contains(valueDescriptor)
fun isExternal(valueDeclaration: IrValueDeclaration): Boolean {
return !declaredValues.contains(valueDeclaration)
}
}
private inner class ClosureCollectorVisitor : IrElementVisitorVoid {
@@ -104,7 +102,7 @@ class ClosureAnnotator {
// We don't include functions or classes in a parent function when they are declared.
// Instead we will include them when are is used (use = call for a function or constructor call for a class).
val parentBuilder = closuresStack.peek()
if (parentBuilder != null && parentBuilder.owner !is FunctionDescriptor) {
if (parentBuilder != null && parentBuilder.owner !is IrFunction) {
parentBuilder.include(builder)
}
}
@@ -114,18 +112,18 @@ class ClosureAnnotator {
}
override fun visitClass(declaration: IrClass) {
val classDescriptor = declaration.descriptor
val closureBuilder = ClosureBuilder(classDescriptor)
closureBuilders[declaration.descriptor] = closureBuilder
val closureBuilder = ClosureBuilder(declaration)
closureBuilders[declaration] = closureBuilder
closureBuilder.declareVariable(classDescriptor.thisAsReceiverParameter)
closureBuilder.declareVariable(declaration.thisReceiver)
if (declaration.isInner) {
closureBuilder.declareVariable((classDescriptor.containingDeclaration as ClassDescriptor).thisAsReceiverParameter)
closureBuilder.declareVariable((declaration.parent as IrClass).thisReceiver)
includeInParent(closureBuilder)
}
classDescriptor.unsubstitutedPrimaryConstructor?.valueParameters?.forEach {
closureBuilder.declareVariable(it)
declaration.declarations.firstOrNull { it is IrConstructor && it.isPrimary }?.let {
val constructor = it as IrConstructor
constructor.valueParameters.forEach { v -> closureBuilder.declareVariable(v) }
}
closuresStack.push(closureBuilder)
@@ -134,23 +132,26 @@ class ClosureAnnotator {
}
override fun visitFunction(declaration: IrFunction) {
val functionDescriptor = declaration.descriptor
val closureBuilder = ClosureBuilder(functionDescriptor)
closureBuilders[functionDescriptor] = closureBuilder
val closureBuilder = ClosureBuilder(declaration)
closureBuilders[declaration] = closureBuilder
declaration.valueParameters.forEach { closureBuilder.declareVariable(it) }
closureBuilder.declareVariable(declaration.dispatchReceiverParameter)
closureBuilder.declareVariable(declaration.extensionReceiverParameter)
if (declaration is IrConstructor) {
val constructedClass = (declaration.parent as IrClass)
closureBuilder.declareVariable(constructedClass.thisReceiver)
functionDescriptor.valueParameters.forEach { closureBuilder.declareVariable(it) }
closureBuilder.declareVariable(functionDescriptor.dispatchReceiverParameter)
closureBuilder.declareVariable(functionDescriptor.extensionReceiverParameter)
if (functionDescriptor is ConstructorDescriptor) {
closureBuilder.declareVariable(functionDescriptor.constructedClass.thisAsReceiverParameter)
// Include closure of the class in the constructor closure.
val classBuilder = closuresStack.peek()
classBuilder?.let {
assert(classBuilder.owner == functionDescriptor.constructedClass)
assert(classBuilder.owner == constructedClass)
closureBuilder.include(classBuilder)
}
}
closuresStack.push(closureBuilder)
declaration.acceptChildrenVoid(this)
closuresStack.pop()
@@ -169,21 +170,40 @@ class ClosureAnnotator {
}
override fun visitVariable(declaration: IrVariable) {
closuresStack.peek()?.declareVariable(declaration.descriptor)
closuresStack.peek()?.declareVariable(declaration)
super.visitVariable(declaration)
}
override fun visitCatch(aCatch: IrCatch) {
closuresStack.peek()?.declareVariable(aCatch.parameter)
closuresStack.peek()?.declareVariable(aCatch.catchParameter)
super.visitCatch(aCatch)
}
// Process delegating constructor calls, enum constructor calls, calls and callable references.
override fun visitMemberAccess(expression: IrMemberAccessExpression) {
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
expression.acceptChildrenVoid(this)
val descriptor = expression.descriptor
if (DescriptorUtils.isLocal(descriptor)) {
val builder = closureBuilders[descriptor]
processMemberAccess(expression.symbol.owner)
}
override fun visitCall(expression: IrCall) {
expression.acceptChildrenVoid(this)
processMemberAccess(expression.symbol.owner)
}
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall) {
expression.acceptChildrenVoid(this)
processMemberAccess(expression.symbol.owner)
}
override fun visitFunctionReference(expression: IrFunctionReference) {
expression.acceptChildrenVoid(this)
processMemberAccess(expression.symbol.owner)
}
// override fun visitPropertyReference(expression: IrPropertyReference) = processMemberAccess(expression.)
private fun processMemberAccess(declaration: IrDeclaration) {
if (DescriptorUtils.isLocal(declaration.descriptor)) {
val builder = closureBuilders[declaration]
builder?.let {
closuresStack.peek()?.include(builder)
}
@@ -8,20 +8,18 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
@@ -30,13 +28,18 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.calls.components.isVararg
// TODO: fix expect/actual default parameters
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
DeclarationContainerLoweringPass {
@@ -53,71 +56,70 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
private val symbols = context.ir.symbols
private fun lower(irFunction: IrFunction): List<IrFunction> {
val functionDescriptor = irFunction.descriptor
if (!functionDescriptor.needsDefaultArgumentsLowering(skipInlineMethods))
if (!irFunction.needsDefaultArgumentsLowering(skipInlineMethods))
return listOf(irFunction)
val bodies = functionDescriptor.valueParameters
.mapNotNull { irFunction.getDefault(it) }
val bodies = irFunction.valueParameters.mapNotNull { it.defaultValue }
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
log { "detected ${irFunction.name.asString()} has got #${bodies.size} default expressions" }
if (bodies.isNotEmpty()) {
val newIrFunction = irFunction.generateDefaultsFunction(context)
newIrFunction.parent = irFunction.parent
val descriptor = newIrFunction.descriptor
log { "$functionDescriptor -> $descriptor" }
log { "$irFunction -> $newIrFunction" }
val builder = context.createIrBuilder(newIrFunction.symbol)
newIrFunction.body = builder.irBlockBody(newIrFunction) {
val params = mutableListOf<IrVariable>()
val variables = mutableMapOf<ValueDescriptor, IrValueDeclaration>()
val variables = mutableMapOf<IrValueDeclaration, IrValueDeclaration>()
irFunction.dispatchReceiverParameter?.let {
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!
variables[it] = newIrFunction.dispatchReceiverParameter!!
}
if (descriptor.extensionReceiverParameter != null) {
variables[functionDescriptor.extensionReceiverParameter!!] =
newIrFunction.extensionReceiverParameter!!
irFunction.extensionReceiverParameter?.let {
variables[it] = newIrFunction.extensionReceiverParameter!!
}
for (valueParameter in functionDescriptor.valueParameters) {
for (valueParameter in irFunction.valueParameters) {
val parameter = newIrFunction.valueParameters[valueParameter.index]
val argument = if (valueParameter.hasDefaultValue()) {
val argument = if (valueParameter.defaultValue != null) {
val kIntAnd = symbols.intAnd.owner
val condition = irNotEquals(irCall(kIntAnd).apply {
dispatchReceiver = irGet(maskParameter(newIrFunction, valueParameter.index / 32))
putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
}, irInt(0))
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
/* Use previously calculated values in next expression. */
val expressionBody = valueParameter.defaultValue!!
expressionBody.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
log { "GetValue: ${expression.descriptor}" }
val valueSymbol = variables[expression.descriptor] ?: return expression
log { "GetValue: ${expression.symbol.owner}" }
val valueSymbol = variables[expression.symbol.owner] ?: return expression
return irGet(valueSymbol)
}
})
irIfThenElse(
type = parameter.type,
condition = condition,
thenPart = expressionBody.expression,
elsePart = irGet(parameter)
)
/* Mapping calculated values with its origin variables. */
} else {
irGet(parameter)
}
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
params.add(temporaryVariable)
variables.put(valueParameter, temporaryVariable)
variables[valueParameter] = temporaryVariable
}
if (irFunction is IrConstructor) {
+IrDelegatingConstructorCallImpl(
startOffset = irFunction.startOffset,
@@ -126,31 +128,23 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor,
typeArgumentsCount = irFunction.typeParameters.size
).apply {
params.forEachIndexed { i, variable ->
putValueArgument(i, irGet(variable))
}
if (functionDescriptor.dispatchReceiverParameter != null) {
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
}
dispatchReceiver = newIrFunction.dispatchReceiverParameter?.let { irGet(it) }
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
}
} else {
+irReturn(irCall(irFunction).apply {
if (functionDescriptor.dispatchReceiverParameter != null) {
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
}
if (functionDescriptor.extensionReceiverParameter != null) {
extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!]!!)
}
params.forEachIndexed { i, variable ->
putValueArgument(i, irGet(variable))
}
dispatchReceiver = newIrFunction.dispatchReceiverParameter?.let { irGet(it) }
extensionReceiver = newIrFunction.extensionReceiverParameter?.let { irGet(it) }
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
})
}
}
// Remove default argument initializers.
irFunction.valueParameters.forEach {
it.defaultValue = null
}
// irFunction.valueParameters.forEach {
// it.defaultValue = null
// }
return listOf(irFunction, newIrFunction)
}
@@ -161,18 +155,14 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
}
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor): IrExpressionBody {
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
}
private fun maskParameterDescriptor(function: IrFunction, number: Int) =
maskParameter(function, number).descriptor as ValueParameterDescriptor
private fun maskParameterDeclaration(function: IrFunction, number: Int) =
maskParameter(function, number)
private fun maskParameter(function: IrFunction, number: Int) =
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }
function.valueParameters.single { it.name == parameterMaskName(number) }
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
private fun markerParameterDeclaration(function: IrFunction) =
function.valueParameters.single { it.name == kConstructorMarkerName }
open class DefaultParameterInjector constructor(
val context: CommonBackendContext,
@@ -183,12 +173,17 @@ open class DefaultParameterInjector constructor(
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
super.visitDelegatingConstructorCall(expression)
val descriptor = expression.descriptor
if (!descriptor.needsDefaultArgumentsLowering(skipInline))
val declaration = expression.symbol.owner as IrFunction
if (!declaration.needsDefaultArgumentsLowering(skipInline))
return expression
val argumentsCount = argumentCount(expression)
if (argumentsCount == descriptor.valueParameters.size)
if (argumentsCount == declaration.valueParameters.size)
return expression
val (symbolForCall, params) = parametersForCall(expression)
symbolForCall as IrConstructorSymbol
return IrDelegatingConstructorCallImpl(
@@ -211,18 +206,24 @@ open class DefaultParameterInjector constructor(
override fun visitCall(expression: IrCall): IrExpression {
super.visitCall(expression)
val functionDescriptor = expression.descriptor
val functionDeclaration = expression.symbol.owner
if (!functionDescriptor.needsDefaultArgumentsLowering(skipInline))
if (!functionDeclaration.needsDefaultArgumentsLowering(skipInline))
return expression
val argumentsCount = argumentCount(expression)
if (argumentsCount == functionDescriptor.valueParameters.size)
if (argumentsCount == functionDeclaration.valueParameters.size)
return expression
val (symbol, params) = parametersForCall(expression)
val descriptor = symbol.descriptor
descriptor.typeParameters.forEach { log { "$descriptor [${it.index}]: $it" } }
descriptor.original.typeParameters.forEach { log { "${descriptor.original}[${it.index}] : $it" } }
val declaration = symbol.owner
for (i in 0 until expression.typeArgumentsCount) {
log { "$descriptor [$i]: $expression.getTypeArgument(i)" }
}
declaration.typeParameters.forEach { log { "$declaration[${it.index}] : $it" } }
return IrCallImpl(
startOffset = expression.startOffset,
endOffset = expression.endOffset,
@@ -238,81 +239,86 @@ open class DefaultParameterInjector constructor(
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
putValueArgument(it.first.index, it.second)
}
expression.extensionReceiver?.apply {
extensionReceiver = expression.extensionReceiver
}
expression.dispatchReceiver?.apply {
dispatchReceiver = expression.dispatchReceiver
}
dispatchReceiver = expression.dispatchReceiver
extensionReceiver = expression.extensionReceiver
log { "call::extension@: ${ir2string(expression.extensionReceiver)}" }
log { "call::dispatch@: ${ir2string(expression.dispatchReceiver)}" }
}
}
private fun IrFunction.findSuperMethodWithDefaultArguments(): IrFunction? {
if (!this.descriptor.needsDefaultArgumentsLowering(skipInline)) return null
if (!needsDefaultArgumentsLowering(skipInline)) return null
if (this !is IrSimpleFunction) return this
this.overriddenSymbols.forEach {
it.owner.findSuperMethodWithDefaultArguments()?.let { return it }
for (s in overriddenSymbols) {
s.owner.findSuperMethodWithDefaultArguments()?.let { return it }
}
return this
}
private fun parametersForCall(expression: IrFunctionAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
val descriptor = expression.descriptor
val keyFunction = expression.symbol.owner.findSuperMethodWithDefaultArguments()!!
val realFunction = keyFunction.generateDefaultsFunction(context)
realFunction.parent = keyFunction.parent
val realDescriptor = realFunction.descriptor
private fun parametersForCall(expression: IrFunctionAccessExpression): Pair<IrFunctionSymbol, List<Pair<IrValueParameter, IrExpression?>>> {
val declaration = expression.symbol.owner
log { "$descriptor -> $realDescriptor" }
val maskValues = Array((descriptor.valueParameters.size + 31) / 32, { 0 })
val params = mutableListOf<Pair<ValueParameterDescriptor, IrExpression?>>()
params.addAll(descriptor.valueParameters.mapIndexed { i, _ ->
val keyFunction = declaration.findSuperMethodWithDefaultArguments()!!
val realFunction = keyFunction.generateDefaultsFunction(context)
realFunction.parent = keyFunction.parent
log { "$declaration -> $realFunction" }
val maskValues = Array((declaration.valueParameters.size + 31) / 32) { 0 }
val params = mutableListOf<Pair<IrValueParameter, IrExpression?>>()
params += declaration.valueParameters.mapIndexed { i, _ ->
val valueArgument = expression.getValueArgument(i)
if (valueArgument == null) {
val maskIndex = i / 32
maskValues[maskIndex] = maskValues[maskIndex] or (1 shl (i % 32))
}
val valueParameterDescriptor = realDescriptor.valueParameters[i]
val defaultValueArgument = if (valueParameterDescriptor.isVararg) {
val valueParameterDeclaration = realFunction.valueParameters[i]
val defaultValueArgument = if (valueParameterDeclaration.varargElementType != null) {
null
} else {
nullConst(expression, realFunction.valueParameters[i].type)
}
valueParameterDescriptor to (valueArgument ?: defaultValueArgument)
})
valueParameterDeclaration to (valueArgument ?: defaultValueArgument)
}
maskValues.forEachIndexed { i, maskValue ->
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
params += maskParameterDeclaration(realFunction, i) to IrConstImpl.int(
startOffset = irBody.startOffset,
endOffset = irBody.endOffset,
type = context.irBuiltIns.intType,
value = maskValue
)
}
if (expression.descriptor is ClassConstructorDescriptor) {
if (expression.symbol is IrConstructorSymbol) {
val defaultArgumentMarker = context.ir.symbols.defaultConstructorMarker
params += markerParameterDescriptor(realDescriptor) to IrGetObjectValueImpl(
params += markerParameterDeclaration(realFunction) to IrGetObjectValueImpl(
startOffset = irBody.startOffset,
endOffset = irBody.endOffset,
type = defaultArgumentMarker.owner.defaultType,
symbol = defaultArgumentMarker
)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
params += realDescriptor.valueParameters.last() to
params += realFunction.valueParameters.last() to
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.irBuiltIns.nothingNType)
}
params.forEach {
log { "descriptor::${realDescriptor.name.asString()}#${it.first.index}: ${it.first.name.asString()}" }
log { "descriptor::${realFunction.name.asString()}#${it.first.index}: ${it.first.name.asString()}" }
}
return Pair(realFunction.symbol, params)
}
private fun argumentCount(expression: IrMemberAccessExpression) =
expression.descriptor.valueParameters.count { expression.getValueArgument(it) != null }
private fun argumentCount(expression: IrMemberAccessExpression): Int {
var result = 0
for (i in 0 until expression.valueArgumentsCount) {
expression.getValueArgument(i)?.run { ++result }
}
return result
}
})
}
@@ -331,169 +337,126 @@ open class DefaultParameterInjector constructor(
private fun log(msg: () -> String) = context.log { "DEFAULT-INJECTOR: ${msg()}" }
}
private fun CallableMemberDescriptor.needsDefaultArgumentsLowering(skipInlineMethods: Boolean) =
valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline && skipInlineMethods)
private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext): IrFunction = with(this.descriptor) {
return context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
val descriptor = when (this) {
is ClassConstructorDescriptor ->
ClassConstructorDescriptorImpl.create(
/* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations,
/* isPrimary = */ false,
/* source = */ source
)
else -> {
val name = Name.identifier("$name\$default")
SimpleFunctionDescriptorImpl.create(
/* containingDeclaration = */ containingDeclaration,
/* annotations = */ annotations,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.SYNTHESIZED,
/* source = */ source
)
}
}
val function = this@generateDefaultsFunction
val syntheticParameters = MutableList((valueParameters.size + 31) / 32) { i ->
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), context.irBuiltIns.intType)
}
if (this is ClassConstructorDescriptor) {
syntheticParameters += valueParameter(
descriptor, syntheticParameters.last().index + 1,
kConstructorMarkerName,
context.ir.symbols.defaultConstructorMarker.owner.defaultType
)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
syntheticParameters += valueParameter(
descriptor, syntheticParameters.last().index + 1,
"handler".synthesizedName,
context.irBuiltIns.anyType
)
}
val newValueParameters = function.valueParameters.map {
val parameterDescriptor = ValueParameterDescriptorImpl(
containingDeclaration = descriptor,
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
index = it.index,
annotations = it.descriptor.annotations,
name = it.name,
outType = it.descriptor.type,
declaresDefaultValue = false,
isCrossinline = it.isCrossinline,
isNoinline = it.isNoinline,
varargElementType = (it.descriptor as ValueParameterDescriptor).varargElementType,
source = it.descriptor.source
)
it.copy(parameterDescriptor)
} + syntheticParameters
descriptor.initialize(
/* receiverParameterType = */ extensionReceiverParameter,
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
/* typeParameters = */ typeParameters.map {
TypeParameterDescriptorImpl.createForFurtherModification(
/* containingDeclaration = */ descriptor,
/* annotations = */ it.annotations,
/* reified = */ it.isReified,
/* variance = */ it.variance,
/* name = */ it.name,
/* index = */ it.index,
/* source = */ it.source,
/* reportCycleError = */ null,
/* supertypeLoopsChecker = */ SupertypeLoopChecker.EMPTY
).apply {
it.upperBounds.forEach { addUpperBound(it) }
setInitialized()
}
},
/* unsubstitutedValueParameters = */ newValueParameters.map { it.descriptor as ValueParameterDescriptor },
/* unsubstitutedReturnType = */ returnType,
/* modality = */ Modality.FINAL,
/* visibility = */ this.visibility
)
descriptor.isSuspend = this.isSuspend
context.log { "adds to cache[$this] = $descriptor" }
val startOffset = this.startOffsetOrUndefined
val endOffset = this.endOffsetOrUndefined
val result: IrFunction = when (descriptor) {
is ClassConstructorDescriptor -> IrConstructorImpl(
startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
descriptor
)
else -> IrFunctionImpl(
startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
descriptor
)
}
result.returnType = function.returnType
function.typeParameters.mapTo(result.typeParameters) {
assert(function.descriptor.typeParameters[it.index] == it.descriptor)
IrTypeParameterImpl(
startOffset, endOffset, origin, descriptor.typeParameters[it.index]
).apply { this.superTypes += it.superTypes }
}
result.parent = function.parent
result.createDispatchReceiverParameter()
function.extensionReceiverParameter?.let {
result.extensionReceiverParameter = IrValueParameterImpl(
it.startOffset,
it.endOffset,
it.origin,
descriptor.extensionReceiverParameter!!,
it.type,
it.varargElementType
).apply { parent = result }
}
result.valueParameters += newValueParameters.also { it.forEach { it.parent = result } }
function.annotations.mapTo(result.annotations) { it.deepCopyWithSymbols() }
result
class DefaultParameterCleaner constructor(val context: CommonBackendContext) : FunctionLoweringPass {
override fun lower(irFunction: IrFunction) {
irFunction.valueParameters.forEach { it.defaultValue = null }
}
}
private fun IrFunction.needsDefaultArgumentsLowering(skipInlineMethods: Boolean): Boolean {
if (isInline && skipInlineMethods) return false
if (valueParameters.any { it.defaultValue != null }) return true
if (this !is IrSimpleFunction) return false
return overriddenSymbols.any { it.owner.needsDefaultArgumentsLowering(skipInlineMethods) }
}
private fun IrFunction.generateDefaultsFunctionImpl(context: CommonBackendContext): IrFunction {
val newFunction = buildFunctionDeclaration(this)
val syntheticParameters = MutableList((valueParameters.size + 31) / 32) { i ->
valueParameter(valueParameters.size + i, parameterMaskName(i), context.irBuiltIns.intType)
}
if (this is IrConstructor) {
syntheticParameters += newFunction.valueParameter(
syntheticParameters.last().index + 1,
kConstructorMarkerName,
context.ir.symbols.defaultConstructorMarker.owner.defaultType
)
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
syntheticParameters += newFunction.valueParameter(
syntheticParameters.last().index + 1,
"handler".synthesizedName,
context.irBuiltIns.anyType
)
}
val newValueParameters = valueParameters.map { it.copyTo(newFunction) } + syntheticParameters
val newTypeParameters = typeParameters.map { it.copyTo(newFunction) }
newFunction.returnType = returnType
newFunction.dispatchReceiverParameter = dispatchReceiverParameter?.copyTo(newFunction)
newFunction.extensionReceiverParameter = extensionReceiverParameter?.copyTo(newFunction)
newFunction.valueParameters += newValueParameters
newFunction.typeParameters += newTypeParameters
annotations.mapTo(newFunction.annotations) { it.deepCopyWithSymbols() }
return newFunction
}
private fun buildFunctionDeclaration(irFunction: IrFunction): IrFunction {
when (irFunction) {
is IrConstructor -> {
val descriptor = WrappedClassConstructorDescriptor(irFunction.descriptor.annotations, irFunction.descriptor.source)
return IrConstructorImpl(
irFunction.startOffset,
irFunction.endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
IrConstructorSymbolImpl(descriptor),
irFunction.name,
irFunction.visibility,
irFunction.isInline,
irFunction.isExternal,
false
).also {
descriptor.bind(it)
it.parent = irFunction.parent
}
}
is IrSimpleFunction -> {
val descriptor = WrappedSimpleFunctionDescriptor(irFunction.descriptor.annotations, irFunction.descriptor.source)
val name = Name.identifier("${irFunction.name}\$default")
return IrFunctionImpl(
irFunction.startOffset,
irFunction.endOffset,
DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER,
IrSimpleFunctionSymbolImpl(descriptor),
name,
irFunction.visibility,
irFunction.modality,
irFunction.isInline,
irFunction.isExternal,
irFunction.isTailrec,
irFunction.isSuspend
).also {
descriptor.bind(it)
it.parent = irFunction.parent
}
}
else -> throw IllegalStateException("Unknown function type")
}
}
private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext): IrFunction =
context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
generateDefaultsFunctionImpl(context)
}
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
private fun IrFunction.valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: IrType): IrValueParameter {
val parameterDescriptor = ValueParameterDescriptorImpl(
containingDeclaration = descriptor,
original = null,
index = index,
annotations = Annotations.EMPTY,
name = name,
outType = type.toKotlinType(),
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = null,
source = SourceElement.NO_SOURCE
)
private fun IrFunction.valueParameter(index: Int, name: Name, type: IrType): IrValueParameter {
val parameterDescriptor = WrappedValueParameterDescriptor()
return IrValueParameterImpl(
startOffset,
endOffset,
IrDeclarationOrigin.DEFINED,
parameterDescriptor,
IrValueParameterSymbolImpl(parameterDescriptor),
name,
index,
type,
null
)
null,
false,
false
).also {
parameterDescriptor.bind(it)
it.parent = this
}
}
internal val kConstructorMarkerName = "marker".synthesizedName
@@ -15,11 +15,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
@@ -94,8 +93,8 @@ class InitializersLowering(
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null,
instanceInitializerStatements.map { it.copy(irClass) })
val copiedBlock = IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType, null, instanceInitializerStatements).copy(irClass) as IrBlock
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null, copiedBlock.statements)
}
})
}
@@ -125,7 +124,7 @@ class InitializersLowering(
companion object {
val clinitName = Name.special("<clinit>")
fun IrStatement.copy(containingDeclaration: IrClass) = deepCopyWithSymbols(containingDeclaration)
fun IrExpression.copy(containingDeclaration: IrClass) = deepCopyWithSymbols(containingDeclaration)
fun IrStatement.copy(containingDeclaration: IrDeclarationParent) = deepCopyWithSymbols(containingDeclaration)
fun IrExpression.copy(containingDeclaration: IrDeclarationParent) = deepCopyWithSymbols(containingDeclaration)
}
}
@@ -8,29 +8,25 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import java.util.*
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
override fun lower(irClass: IrClass) {
InnerClassTransformer(irClass).lowerInnerClass()
}
@@ -38,12 +34,10 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
private inner class InnerClassTransformer(val irClass: IrClass) {
lateinit var outerThisField: IrField
val oldConstructorParameterToNew = HashMap<ValueDescriptor, IrValueParameter>()
val class2Symbol = HashMap<ClassDescriptor, IrClass>()
val oldConstructorParameterToNew = HashMap<IrValueParameter, IrValueParameter>()
fun lowerInnerClass() {
if (!irClass.isInner) return
rememberClassSymbols()
createOuterThisField()
lowerConstructors()
@@ -51,36 +45,10 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
lowerOuterThisReferences()
}
//TODO: rewrite: this methods is required to 'getClassForImplicitThis' method
private fun rememberClassSymbols() {
var current = irClass.parent as? IrClass
while (current != null) {
class2Symbol[current.descriptor] = current
current = current.parent as? IrClass
}
irClass.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitClass(declaration: IrClass) {
return super.visitClass(declaration).also { class2Symbol[declaration.descriptor] = declaration }
}
})
}
private fun createOuterThisField() {
val fieldSymbol = context.descriptorsFactory.getOuterThisFieldSymbol(irClass)
irClass.declarations.add(
IrFieldImpl(
irClass.startOffset, irClass.endOffset,
FIELD_FOR_OUTER_THIS,
fieldSymbol,
irClass.defaultType
).also {
outerThisField = it
}
)
val field = context.declarationFactory.getOuterThisField(irClass)
outerThisField = field
irClass.declarations += field
}
private fun lowerConstructors() {
@@ -96,42 +64,31 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
val startOffset = irConstructor.startOffset
val endOffset = irConstructor.endOffset
val newSymbol = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(irConstructor)
val loweredConstructor = IrConstructorImpl(
startOffset, endOffset,
irConstructor.origin, // TODO special origin for lowered inner class constructors?
newSymbol,
null
).apply {
parent = irConstructor.parent
returnType = irConstructor.returnType
}
loweredConstructor.createParameterDeclarations()
val loweredConstructor = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(irConstructor)
val outerThisValueParameter = loweredConstructor.valueParameters[0].symbol
irConstructor.descriptor.valueParameters.forEach { oldValueParameter ->
oldConstructorParameterToNew[oldValueParameter] = loweredConstructor.valueParameters[oldValueParameter.index + 1]
irConstructor.valueParameters.forEach { old ->
oldConstructorParameterToNew[old] = loweredConstructor.valueParameters[old.index + 1]
}
val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}")
val instanceInitializerIndex = blockBody.statements.indexOfFirst { it is IrInstanceInitializerCall }
if (instanceInitializerIndex >= 0) {
// Initializing constructor: initialize 'this.this$0' with '$outer'
blockBody.statements.add(
instanceInitializerIndex,
IrSetFieldImpl(
startOffset, endOffset, outerThisField.symbol,
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
IrGetValueImpl(startOffset, endOffset, outerThisValueParameter),
context.irBuiltIns.unitType
)
// Initializing constructor: initialize 'this.this$0' with '$outer'
blockBody.statements.add(
0,
IrSetFieldImpl(
startOffset, endOffset, outerThisField.symbol,
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
IrGetValueImpl(startOffset, endOffset, outerThisValueParameter),
context.irBuiltIns.unitType
)
} else {
)
if (instanceInitializerIndex < 0) {
// Delegating constructor: invoke old constructor with dispatch receiver '$outer'
val delegatingConstructorCall = (blockBody.statements.find { it is IrDelegatingConstructorCall }
?: throw AssertionError("Delegating constructor call expected: ${irConstructor.dump()}")
?: throw AssertionError("Delegating constructor call expected: ${irConstructor.dump()}")
) as IrDelegatingConstructorCall
delegatingConstructorCall.dispatchReceiver = IrGetValueImpl(
delegatingConstructorCall.startOffset, delegatingConstructorCall.endOffset, outerThisValueParameter
@@ -175,8 +132,15 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
return expression
}
val outerThisField = context.descriptorsFactory.getOuterThisFieldSymbol(innerClass)
irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, innerClass.defaultType, irThis, origin)
val outerThisField = context.declarationFactory.getOuterThisField(innerClass)
irThis = IrGetFieldImpl(
startOffset,
endOffset,
outerThisField.symbol,
innerClass.defaultType,
irThis,
origin
)
val outer = innerClass.parent
innerClass = outer as? IrClass ?:
@@ -189,11 +153,13 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
}
private fun IrValueSymbol.getClassForImplicitThis(): IrClass? {
val descriptor1 = this.descriptor
if (descriptor1 is ReceiverParameterDescriptor) {
val receiverValue = descriptor1.value
if (receiverValue is ImplicitClassReceiver) {
return class2Symbol[receiverValue.classDescriptor]
//TODO: is it correct way to get class
if (this is IrValueParameterSymbol) {
val declaration = owner
if (declaration.index == -1) { // means value is either IMPLICIT or EXTENSION receiver
if (declaration.name.isSpecial) { // whether name is <this>
return owner.type.classifierOrNull?.owner as IrClass
}
}
}
return null
@@ -212,15 +178,15 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
val parent = callee.owner.parent as? IrClass ?: return expression
if (!parent.isInner) return expression
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner)
val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner)
val newCall = IrCallImpl(
expression.startOffset, expression.endOffset, expression.type, newCallee, newCallee.descriptor,
expression.startOffset, expression.endOffset, expression.type, newCallee.symbol, newCallee.descriptor,
0, // TODO type arguments map
expression.origin
)
newCall.putValueArgument(0, dispatchReceiver)
for (i in 1..newCallee.descriptor.valueParameters.lastIndex) {
for (i in 1..newCallee.valueParameters.lastIndex) {
newCall.putValueArgument(i, expression.getValueArgument(i - 1))
}
@@ -234,14 +200,14 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
val classConstructor = expression.symbol.owner
if (!(classConstructor.parent as IrClass).isInner) return expression
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(classConstructor)
val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(classConstructor)
val newCall = IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, newCallee, newCallee.descriptor,
expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, newCallee.symbol, newCallee.descriptor,
classConstructor.typeParameters.size
).apply { copyTypeArgumentsFrom(expression) }
newCall.putValueArgument(0, dispatchReceiver)
for (i in 1..newCallee.descriptor.valueParameters.lastIndex) {
for (i in 1..newCallee.valueParameters.lastIndex) {
newCall.putValueArgument(i, expression.getValueArgument(i - 1))
}
@@ -255,9 +221,19 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
val parent = callee.owner.parent as? IrClass ?: return expression
if (!parent.isInner) return expression
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner)
val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner)
val newReference = expression.run { IrFunctionReferenceImpl(startOffset, endOffset, type, newCallee, newCallee.descriptor, typeArgumentsCount, origin) }
val newReference = expression.run {
IrFunctionReferenceImpl(
startOffset,
endOffset,
type,
newCallee.symbol,
newCallee.descriptor,
typeArgumentsCount,
origin
)
}
newReference.let {
it.dispatchReceiver = expression.dispatchReceiver
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
@@ -31,7 +30,6 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.types.KotlinType
class LateinitLowering(
val context: CommonBackendContext,
@@ -26,17 +26,17 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.utils.Printer
@@ -55,16 +55,16 @@ class DeclarationIrBuilder(
)
abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
protected abstract fun remapVariable(value: ValueDescriptor): IrValueParameter?
protected abstract fun remapVariable(value: IrValueDeclaration): IrValueParameter?
override fun visitGetValue(expression: IrGetValue): IrExpression =
remapVariable(expression.descriptor)?.let {
remapVariable(expression.symbol.owner)?.let {
IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.origin)
} ?: expression
}
class VariableRemapper(val mapping: Map<ValueDescriptor, IrValueParameter>) : AbstractVariableRemapper() {
override fun remapVariable(value: ValueDescriptor): IrValueParameter? =
class VariableRemapper(val mapping: Map<IrValueParameter, IrValueParameter>) : AbstractVariableRemapper() {
override fun remapVariable(value: IrValueDeclaration): IrValueParameter? =
mapping[value]
}
@@ -157,35 +157,6 @@ open class IrBuildingTransformer(private val context: BackendContext) : IrElemen
}
}
fun computeOverrides(current: ClassDescriptor, functionsFromCurrent: List<CallableMemberDescriptor>): List<DeclarationDescriptor> {
val result = mutableListOf<DeclarationDescriptor>()
val allSuperDescriptors = current.typeConstructor.supertypes
.flatMap { it.memberScope.getContributedDescriptors() }
.filterIsInstance<CallableMemberDescriptor>()
for ((name, group) in allSuperDescriptors.groupBy { it.name }) {
OverridingUtil.generateOverridesInFunctionGroup(
name,
/* membersFromSupertypes = */ group,
/* membersFromCurrent = */ functionsFromCurrent.filter { it.name == name },
current,
object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
result.add(fakeOverride)
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
error("Conflict in scope of $current: $fromSuper vs $fromCurrent")
}
}
)
}
return result
}
class SimpleMemberScope(val members: List<DeclarationDescriptor>) : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
@@ -207,12 +178,14 @@ class SimpleMemberScope(val members: List<DeclarationDescriptor>) : MemberScopeI
members.filter { kindFilter.accepts(it) && nameFilter(it.name) }
override fun printScopeStructure(p: Printer) = TODO("not implemented")
}
fun IrConstructor.callsSuper(): Boolean {
val constructedClass = descriptor.constructedClass
val superClass = constructedClass.getSuperClassOrAny()
fun IrConstructor.callsSuper(irBuiltIns: IrBuiltIns): Boolean {
val constructedClass = parent as IrClass
val superClass = constructedClass.superTypes
.mapNotNull { it as? IrSimpleType }
.firstOrNull { (it.classifier.owner as IrClass).run { kind == ClassKind.CLASS || kind == ClassKind.ANNOTATION_CLASS || kind == ClassKind.ANNOTATION_CLASS } }
?: irBuiltIns.anyType
var callsSuper = false
var numberOfCalls = 0
acceptChildrenVoid(object : IrElementVisitorVoid {
@@ -225,17 +198,18 @@ fun IrConstructor.callsSuper(): Boolean {
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
assert(++numberOfCalls == 1, { "More than one delegating constructor call: $descriptor" })
if (expression.descriptor.constructedClass == superClass)
assert(++numberOfCalls == 1) { "More than one delegating constructor call: ${symbol.owner}" }
val delegatingClass = expression.symbol.owner.parent as IrClass
if (delegatingClass == superClass.classifierOrFail.owner)
callsSuper = true
else if (expression.descriptor.constructedClass != constructedClass)
else if (delegatingClass != constructedClass)
throw AssertionError(
"Expected either call to another constructor of the class being constructed or" +
" call to super class constructor. But was: ${expression.descriptor.constructedClass}"
" call to super class constructor. But was: $delegatingClass"
)
}
})
assert(numberOfCalls == 1, { "Expected exactly one delegating constructor call but none encountered: $descriptor" })
assert(numberOfCalls == 1) { "Expected exactly one delegating constructor call but none encountered: ${symbol.owner}" }
return callsSuper
}
@@ -73,7 +73,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
it.valueParameters.size == 0 && it.name == nameToString
}
private val defaultAppendFunction = stringBuilder.functions.single {
it.descriptor.name == nameAppend &&
it.name == nameAppend &&
it.valueParameters.size == 1 &&
it.valueParameters.single().type.isNullableAny()
}
@@ -82,7 +82,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
private val appendFunctions: Map<KotlinType, IrSimpleFunction?> =
typesWithSpecialAppendFunction.map { type ->
type to stringBuilder.functions.toList().atMostOne {
it.descriptor.name == nameAppend &&
it.name == nameAppend &&
it.valueParameters.size == 1 &&
it.valueParameters.single().type.toKotlinType() == type
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.common.utils
import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.toIrType
@@ -20,24 +19,34 @@ import org.jetbrains.kotlin.types.typeUtil.isInterface
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
// TODO: implement pure Ir-based function (see IrTypeUtils.kt)
@Deprecated("Use pure Ir helper")
fun IrType.isNullable() = toKotlinType().isNullable()
@Deprecated("Use pure Ir helper")
fun IrType.isInterface() = toKotlinType().isInterface()
@Deprecated("Use pure Ir helper")
fun IrType.isPrimitiveArray() = KotlinBuiltIns.isPrimitiveArray(toKotlinType())
@Deprecated("Use pure Ir helper")
fun IrType.getPrimitiveArrayElementType() = KotlinBuiltIns.getPrimitiveArrayElementType(toKotlinType())
@Deprecated("Use pure Ir helper")
fun IrType.isTypeParameter() = toKotlinType().isTypeParameter()
@Deprecated("Use pure Ir helper")
fun IrType.isFunctionOrKFunction() = toKotlinType().isFunctionOrKFunctionType
fun IrType.isFunctionTypeOrSubtype() = toKotlinType().isFunctionTypeOrSubtype
@Deprecated("Use pure Ir helper")
fun List<IrType>.commonSupertype() = CommonSupertypes.commonSupertype(map(IrType::toKotlinType)).toIrType()!!
@Deprecated("Use pure Ir helper")
fun IrType.isSubtypeOf(superType: IrType) = toKotlinType().isSubtypeOf(superType.toKotlinType())
@Deprecated("Use pure Ir helper")
fun IrType.isSubtypeOfClass(superClass: IrClassSymbol) = DescriptorUtils.isSubtypeOfClass(toKotlinType(), superClass.descriptor)
@Deprecated("Use pure Ir helper")
fun IrType.isBuiltinFunctionalTypeOrSubtype() = toKotlinType().isBuiltinFunctionalTypeOrSubtype
@@ -0,0 +1,41 @@
/*
* 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.utils.DFS
fun IrType.isFunctionTypeOrSubtype(): Boolean {
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
fun checkType(irType: IrType): Boolean {
val classifier = irType.classifierOrNull ?: return false
val name = classifier.descriptor.name.asString()
if (!name.startsWith("Function")) return false
val declaration = classifier.owner as IrDeclaration
val parent = declaration.parent as? IrPackageFragment ?: return false
return parent.fqName == kotlinPackageFqn
}
fun superTypes(irType: IrType): List<IrType> {
val classifier = irType.classifierOrNull?.owner ?: return emptyList()
return when(classifier) {
is IrClass -> classifier.superTypes
is IrTypeParameter -> classifier.superTypes
else -> throw IllegalStateException()
}
}
return DFS.ifAny(listOf(this), ::superTypes, ::checkType)
}