backend: lower local classes
This commit is contained in:
committed by
SvyatoslavScherbina
parent
ead5f93a90
commit
26e1075893
+654
-119
@@ -21,15 +21,12 @@ import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.Closure
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
@@ -45,48 +42,135 @@ import java.util.*
|
||||
|
||||
class LocalDeclarationsLowering(val context: BackendContext): DeclarationContainerLoweringPass {
|
||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||
if (irDeclarationContainer is IrDeclaration &&
|
||||
irDeclarationContainer.descriptor.parents.any { it is CallableDescriptor }) {
|
||||
|
||||
// Lowering of non-local declarations handles all local declarations inside.
|
||||
// This declaration is local and shouldn't be considered.
|
||||
return
|
||||
}
|
||||
|
||||
// Continuous numbering across all declarations in the container.
|
||||
lambdasCount = 0
|
||||
objectsCount = 0
|
||||
|
||||
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
|
||||
if (memberDeclaration is IrFunction)
|
||||
LocalFunctionsTransformer(memberDeclaration).lowerLocalFunctions()
|
||||
LocalDeclarationsTransformer(memberDeclaration).lowerLocalDeclarations()
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalFunctionContext(val declaration: IrFunction) {
|
||||
private var lambdasCount = 0
|
||||
private var objectsCount = 0
|
||||
|
||||
private abstract class LocalContext {
|
||||
/**
|
||||
* @return the expression to get the value for given descriptor, or `null` if [IrGetValue] should be used.
|
||||
*/
|
||||
abstract fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression?
|
||||
}
|
||||
|
||||
private abstract class LocalContextWithClosureAsParameters : LocalContext() {
|
||||
|
||||
abstract val declaration: IrFunction
|
||||
open val descriptor: FunctionDescriptor
|
||||
get() = declaration.descriptor
|
||||
|
||||
abstract val transformedDescriptor: FunctionDescriptor
|
||||
|
||||
val capturedValueToParameter: MutableMap<ValueDescriptor, ValueParameterDescriptor> = HashMap()
|
||||
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val newDescriptor = capturedValueToParameter[descriptor] ?: return null
|
||||
|
||||
return IrGetValueImpl(startOffset, endOffset, newDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalFunctionContext(override val declaration: IrFunction) : LocalContextWithClosureAsParameters() {
|
||||
lateinit var closure: Closure
|
||||
|
||||
val closureParametersCount: Int get() = closure.capturedValues.size
|
||||
|
||||
lateinit var transformedDescriptor: FunctionDescriptor
|
||||
|
||||
val old2new: MutableMap<ValueDescriptor, ParameterDescriptor> = HashMap()
|
||||
override lateinit var transformedDescriptor: FunctionDescriptor
|
||||
|
||||
var index: Int = -1
|
||||
|
||||
override fun toString(): String =
|
||||
"LocalFunctionContext for ${declaration.descriptor}"
|
||||
"LocalFunctionContext for $descriptor"
|
||||
}
|
||||
|
||||
private inner class LocalFunctionsTransformer(val memberFunction: IrFunction) {
|
||||
val localFunctions: MutableMap<FunctionDescriptor, LocalFunctionContext> = LinkedHashMap()
|
||||
val new2old: MutableMap<ParameterDescriptor, ValueDescriptor> = HashMap()
|
||||
private class LocalClassConstructorContext(override val declaration: IrConstructor) : LocalContextWithClosureAsParameters() {
|
||||
override val descriptor: ClassConstructorDescriptor
|
||||
get() = declaration.descriptor
|
||||
|
||||
fun lowerLocalFunctions(): List<IrDeclaration>? {
|
||||
collectLocalFunctions()
|
||||
if (localFunctions.isEmpty()) return null
|
||||
override lateinit var transformedDescriptor: ClassConstructorDescriptor
|
||||
|
||||
override fun toString(): String =
|
||||
"LocalClassConstructorContext for $descriptor"
|
||||
}
|
||||
|
||||
private class LocalClassContext(val declaration: IrClass) : LocalContext() {
|
||||
lateinit var closure: Closure
|
||||
|
||||
lateinit var transformedDescriptor: ClassDescriptorImpl
|
||||
|
||||
val capturedValueToField: MutableMap<ValueDescriptor, PropertyDescriptor> = HashMap()
|
||||
|
||||
var index: Int = -1
|
||||
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val fieldDescriptor = capturedValueToField[descriptor] ?: return null
|
||||
|
||||
return IrGetFieldImpl(startOffset, endOffset, fieldDescriptor,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, transformedDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"LocalClassContext for ${declaration.descriptor}"
|
||||
}
|
||||
|
||||
private inner class LocalDeclarationsTransformer(val memberFunction: IrFunction) {
|
||||
val localFunctions: MutableMap<FunctionDescriptor, LocalFunctionContext> = LinkedHashMap()
|
||||
val localClasses: MutableMap<ClassDescriptor, LocalClassContext> = LinkedHashMap()
|
||||
val localClassConstructors: MutableMap<ClassConstructorDescriptor, LocalClassConstructorContext> = LinkedHashMap()
|
||||
val localClassMembers: MutableSet<MemberDescriptor> = LinkedHashSet()
|
||||
|
||||
val transformedDescriptors = mutableMapOf<DeclarationDescriptor, DeclarationDescriptor>()
|
||||
|
||||
val CallableDescriptor.transformed: CallableDescriptor?
|
||||
get() = transformedDescriptors[this] as CallableDescriptor?
|
||||
|
||||
val CallableMemberDescriptor.transformed: CallableMemberDescriptor?
|
||||
get() = transformedDescriptors[this] as CallableMemberDescriptor?
|
||||
|
||||
val FunctionDescriptor.transformed: FunctionDescriptor?
|
||||
get() = transformedDescriptors[this] as FunctionDescriptor?
|
||||
|
||||
val PropertyDescriptor.transformed: PropertyDescriptor?
|
||||
get() = transformedDescriptors[this] as PropertyDescriptor?
|
||||
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, ParameterDescriptor> = HashMap()
|
||||
val newParameterToOld: MutableMap<ParameterDescriptor, ParameterDescriptor> = HashMap()
|
||||
val newParameterToCaptured: MutableMap<ValueParameterDescriptor, ValueDescriptor> = HashMap()
|
||||
|
||||
fun lowerLocalDeclarations(): List<IrDeclaration>? {
|
||||
collectLocalDeclarations()
|
||||
if (localFunctions.isEmpty() && localClasses.isEmpty()) return null
|
||||
|
||||
collectClosures()
|
||||
|
||||
transformDescriptors()
|
||||
|
||||
rewriteBodies()
|
||||
rewriteDeclarations()
|
||||
|
||||
return collectRewrittenDeclarations()
|
||||
val result = collectRewrittenDeclarations()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun collectRewrittenDeclarations(): ArrayList<IrDeclaration> =
|
||||
ArrayList<IrDeclaration>(localFunctions.size + 1).apply {
|
||||
ArrayList<IrDeclaration>(localFunctions.size + localClasses.size + 1).apply {
|
||||
add(memberFunction)
|
||||
|
||||
localFunctions.values.mapTo(this) {
|
||||
@@ -97,53 +181,137 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
original.body
|
||||
)
|
||||
}
|
||||
|
||||
localClasses.values.mapTo(this) {
|
||||
val original = it.declaration
|
||||
IrClassImpl(
|
||||
original.startOffset, original.endOffset, original.origin,
|
||||
it.transformedDescriptor,
|
||||
original.declarations
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class FunctionBodiesRewriter(val localFunctionContext: LocalFunctionContext?) : IrElementTransformerVoid() {
|
||||
private inner class FunctionBodiesRewriter(val localContext: LocalContext?) : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
// ignore local classes for now
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
// replace local function definition with an empty composite
|
||||
// Replace local class definition with an empty composite.
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitProperty(declaration: IrProperty): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
val newDescriptor = declaration.descriptor.transformed ?: return declaration
|
||||
|
||||
return IrPropertyImpl(
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
declaration.origin, declaration.isDelegated, newDescriptor,
|
||||
declaration.backingField,
|
||||
declaration.getter, declaration.setter
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitField(declaration: IrField): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
val newDescriptor = declaration.descriptor.transformed ?: return declaration
|
||||
|
||||
return IrFieldImpl(
|
||||
declaration.startOffset, declaration.endOffset, declaration.origin,
|
||||
newDescriptor,
|
||||
declaration.initializer
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val newDescriptor = expression.descriptor.transformed ?: return expression
|
||||
|
||||
return IrGetFieldImpl(
|
||||
expression.startOffset, expression.endOffset, newDescriptor,
|
||||
expression.receiver, expression.origin, expression.superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val newDescriptor = expression.descriptor.transformed ?: return expression
|
||||
|
||||
return IrSetFieldImpl(
|
||||
expression.startOffset, expression.endOffset, newDescriptor,
|
||||
expression.receiver, expression.value,
|
||||
expression.origin, expression.superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
if (declaration.descriptor in localFunctions) {
|
||||
// Replace local function definition with an empty composite.
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
} else if (declaration.descriptor in localClassMembers){
|
||||
declaration.transformChildrenVoid(this)
|
||||
|
||||
val transformedDescriptor = declaration.descriptor.transformed!!
|
||||
|
||||
return IrFunctionImpl(declaration.startOffset, declaration.endOffset, declaration.origin,
|
||||
transformedDescriptor, declaration.body)
|
||||
} else {
|
||||
throw AssertionError("the function is neither local itself nor member of a local class")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor): IrStatement {
|
||||
// Body is transformed separately.
|
||||
|
||||
val transformedDescriptor = localClassConstructors[declaration.descriptor]!!.transformedDescriptor
|
||||
|
||||
return IrConstructorImpl(declaration.startOffset, declaration.endOffset, declaration.origin,
|
||||
transformedDescriptor, declaration.body!!)
|
||||
}
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
val remapped = localFunctionContext?.let { it.old2new[expression.descriptor] }
|
||||
return if (remapped == null)
|
||||
expression
|
||||
else
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, remapped, expression.origin)
|
||||
val descriptor = expression.descriptor
|
||||
|
||||
localContext?.irGet(expression.startOffset, expression.endOffset, descriptor)?.let {
|
||||
return it
|
||||
}
|
||||
|
||||
oldParameterToNew[descriptor]?.let {
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it)
|
||||
}
|
||||
|
||||
return expression
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
||||
val newCallee = oldCallee.transformed ?: return expression
|
||||
|
||||
val newCallee = localFunctionData.transformedDescriptor
|
||||
|
||||
val newCall = createNewCall(expression, newCallee).fillArguments(localFunctionData, expression)
|
||||
val newCall = createNewCall(expression, newCallee).fillArguments(expression)
|
||||
|
||||
return newCall
|
||||
}
|
||||
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(calleeContext: LocalFunctionContext, oldExpression: IrMemberAccessExpression): T {
|
||||
val closureParametersCount = calleeContext.closureParametersCount
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(oldExpression: IrMemberAccessExpression): T {
|
||||
|
||||
mapValueParametersIndexed { index, newValueParameterDescriptor ->
|
||||
val capturedValueDescriptor = new2old[newValueParameterDescriptor] ?:
|
||||
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
if (index >= closureParametersCount)
|
||||
oldExpression.getValueArgument(capturedValueDescriptor as ValueParameterDescriptor)
|
||||
else {
|
||||
val remappedValueDescriptor = localFunctionContext?.let { it.old2new[capturedValueDescriptor] }
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset,
|
||||
remappedValueDescriptor ?: capturedValueDescriptor)
|
||||
mapValueParameters { newValueParameterDescriptor ->
|
||||
val oldParameter = newParameterToOld[newValueParameterDescriptor]
|
||||
|
||||
if (oldParameter != null) {
|
||||
oldExpression.getValueArgument(oldParameter as ValueParameterDescriptor)
|
||||
} else {
|
||||
// The callee expects captured value as argument.
|
||||
val capturedValueDescriptor =
|
||||
newParameterToCaptured[newValueParameterDescriptor] ?:
|
||||
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
|
||||
localContext?.irGet(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
capturedValueDescriptor
|
||||
) ?:
|
||||
// Captured value is directly available for the caller.
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset, capturedValueDescriptor)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -158,8 +326,7 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
||||
val newCallee = localFunctionData.transformedDescriptor
|
||||
val newCallee = oldCallee.transformed ?: return expression
|
||||
|
||||
val newCallableReference = IrCallableReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
@@ -167,7 +334,7 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
newCallee,
|
||||
remapTypeArguments(expression, newCallee),
|
||||
expression.origin
|
||||
).fillArguments(localFunctionData, expression)
|
||||
).fillArguments(expression)
|
||||
|
||||
return newCallableReference
|
||||
}
|
||||
@@ -176,26 +343,77 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldReturnTarget = expression.returnTarget
|
||||
val localFunctionData = localFunctions[oldReturnTarget] ?: return expression
|
||||
val newReturnTarget = localFunctionData.transformedDescriptor
|
||||
val newReturnTarget = oldReturnTarget.transformed ?: return expression
|
||||
|
||||
return IrReturnImpl(expression.startOffset, expression.endOffset, newReturnTarget, expression.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun rewriteFunctionDeclaration(irFunction: IrFunction, localFunctionContext: LocalFunctionContext?) {
|
||||
irFunction.transformChildrenVoid(FunctionBodiesRewriter(localFunctionContext))
|
||||
}
|
||||
|
||||
private fun rewriteBodies() {
|
||||
localFunctions.values.forEach {
|
||||
rewriteFunctionDeclaration(it.declaration, it)
|
||||
override fun visitDeclarationReference(expression: IrDeclarationReference): IrExpression {
|
||||
if (expression.descriptor in transformedDescriptors) {
|
||||
TODO()
|
||||
}
|
||||
return super.visitDeclarationReference(expression)
|
||||
}
|
||||
|
||||
rewriteFunctionDeclaration(memberFunction, null)
|
||||
override fun visitDeclaration(declaration: IrDeclaration): IrStatement {
|
||||
if (declaration.descriptor in transformedDescriptors) {
|
||||
TODO()
|
||||
}
|
||||
return super.visitDeclaration(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: FunctionDescriptor) =
|
||||
private fun rewriteFunctionBody(irFunction: IrFunction, localContext: LocalContext?) {
|
||||
irFunction.transformChildrenVoid(FunctionBodiesRewriter(localContext))
|
||||
}
|
||||
|
||||
private object DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE :
|
||||
IrDeclarationOriginImpl("FIELD_FOR_CAPTURED_VALUE") {}
|
||||
|
||||
private fun rewriteClassMembers(irClass: IrClass, localClassContext: LocalClassContext) {
|
||||
irClass.transformChildrenVoid(FunctionBodiesRewriter(localClassContext))
|
||||
|
||||
val primaryConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?:
|
||||
TODO("local classes without primary constructor")
|
||||
|
||||
val primaryConstructorContext = localClassConstructors[primaryConstructor]!!
|
||||
|
||||
localClassContext.capturedValueToField.forEach { capturedValue, fieldDescriptor ->
|
||||
|
||||
val capturedValueExpression =
|
||||
primaryConstructorContext.irGet(irClass.startOffset, irClass.endOffset, capturedValue)!!
|
||||
|
||||
irClass.declarations.add(
|
||||
IrFieldImpl(
|
||||
irClass.startOffset, irClass.endOffset,
|
||||
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
|
||||
fieldDescriptor,
|
||||
IrExpressionBodyImpl(
|
||||
irClass.startOffset, irClass.endOffset,
|
||||
capturedValueExpression
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun rewriteDeclarations() {
|
||||
localFunctions.values.forEach {
|
||||
rewriteFunctionBody(it.declaration, it)
|
||||
}
|
||||
|
||||
localClassConstructors.values.forEach {
|
||||
rewriteFunctionBody(it.declaration, it)
|
||||
}
|
||||
|
||||
localClasses.values.forEach {
|
||||
rewriteClassMembers(it.declaration, it)
|
||||
}
|
||||
|
||||
rewriteFunctionBody(memberFunction, null)
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: CallableDescriptor) =
|
||||
if (oldCall is IrCallWithShallowCopy)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifier)
|
||||
else
|
||||
@@ -206,7 +424,7 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
oldCall.origin, oldCall.superQualifier
|
||||
)
|
||||
|
||||
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: FunctionDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: CallableDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
val oldCallee = oldExpression.descriptor
|
||||
|
||||
return if (oldCallee.typeParameters.isEmpty())
|
||||
@@ -219,64 +437,78 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
|
||||
private fun transformDescriptors() {
|
||||
localFunctions.values.forEach {
|
||||
it.transformedDescriptor = createTransformedDescriptor(it)
|
||||
createLiftedDescriptor(it)
|
||||
}
|
||||
|
||||
localClasses.values.forEach {
|
||||
createLiftedDescriptor(it)
|
||||
}
|
||||
|
||||
localClassConstructors.values.forEach {
|
||||
createTransformedConstructorDescriptor(it)
|
||||
}
|
||||
|
||||
localClassMembers.forEach {
|
||||
createTransformedMemberDescriptor(it)
|
||||
}
|
||||
|
||||
localClasses.values.forEach {
|
||||
initializeClassDescriptor(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun suggestLocalName(descriptor: DeclarationDescriptor): String {
|
||||
val localFunctionContext = localFunctions[descriptor]
|
||||
return if (localFunctionContext != null && localFunctionContext.index >= 0)
|
||||
"lambda-${localFunctionContext.index}"
|
||||
else
|
||||
descriptor.name.asString()
|
||||
localFunctions[descriptor]?.let {
|
||||
if (it.index >= 0)
|
||||
return "lambda-${it.index}"
|
||||
}
|
||||
|
||||
localClasses[descriptor]?.let {
|
||||
if (it.index >= 0)
|
||||
return "object-${it.index}"
|
||||
}
|
||||
|
||||
return descriptor.name.asString()
|
||||
}
|
||||
|
||||
private fun generateNameForLiftedFunction(functionDescriptor: FunctionDescriptor): Name =
|
||||
private fun generateNameForLiftedDeclaration(descriptor: DeclarationDescriptor,
|
||||
newOwner: DeclarationDescriptor): Name =
|
||||
Name.identifier(
|
||||
functionDescriptor.parentsWithSelf
|
||||
.takeWhile { it is FunctionDescriptor }
|
||||
descriptor.parentsWithSelf
|
||||
.takeWhile { it != newOwner }
|
||||
.toList().reversed()
|
||||
.map { suggestLocalName(it) }
|
||||
.joinToString(separator = "$")
|
||||
)
|
||||
|
||||
private fun createTransformedDescriptor(localFunctionContext: LocalFunctionContext): FunctionDescriptor {
|
||||
val oldDescriptor = localFunctionContext.declaration.descriptor
|
||||
private fun createLiftedDescriptor(localFunctionContext: LocalFunctionContext) {
|
||||
val oldDescriptor = localFunctionContext.descriptor
|
||||
|
||||
val memberOwner = memberFunction.descriptor.containingDeclaration
|
||||
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
memberOwner,
|
||||
oldDescriptor.annotations,
|
||||
generateNameForLiftedFunction(oldDescriptor),
|
||||
generateNameForLiftedDeclaration(oldDescriptor, memberOwner),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
oldDescriptor.source
|
||||
)
|
||||
|
||||
val closureParametersCount = localFunctionContext.closureParametersCount
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
localFunctionContext.transformedDescriptor = newDescriptor
|
||||
transformedDescriptors[oldDescriptor] = newDescriptor
|
||||
|
||||
val newDispatchReceiverParameter =
|
||||
if (memberOwner is ClassDescriptor && oldDescriptor.dispatchReceiverParameter != null)
|
||||
memberOwner.thisAsReceiverParameter
|
||||
else
|
||||
null
|
||||
if (oldDescriptor.dispatchReceiverParameter != null) {
|
||||
throw AssertionError("local functions must not have dispatch receiver")
|
||||
}
|
||||
|
||||
val newDispatchReceiverParameter = null
|
||||
|
||||
// Do not substitute type parameters for now.
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
localFunctionContext.closure.capturedValues.mapIndexedTo(this) { i, capturedValueDescriptor ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValueDescriptor, i).apply {
|
||||
localFunctionContext.recordRemapped(capturedValueDescriptor, this)
|
||||
}
|
||||
}
|
||||
// TODO: consider using fields to access the closure of enclosing class.
|
||||
val capturedValues = localFunctionContext.closure.capturedValues
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
localFunctionContext.recordRemapped(oldValueParameterDescriptor, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
val newValueParameters = createTransformedValueParameters(localFunctionContext, capturedValues)
|
||||
|
||||
newDescriptor.initialize(
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
@@ -289,19 +521,282 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
)
|
||||
|
||||
oldDescriptor.extensionReceiverParameter?.let {
|
||||
localFunctionContext.recordRemapped(it, newDescriptor.extensionReceiverParameter!!)
|
||||
recordRemappedParameter(it, newDescriptor.extensionReceiverParameter!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTransformedValueParameters(localContext: LocalContextWithClosureAsParameters,
|
||||
capturedValues: List<ValueDescriptor>
|
||||
): List<ValueParameterDescriptor> {
|
||||
|
||||
val oldDescriptor = localContext.descriptor
|
||||
val newDescriptor = localContext.transformedDescriptor
|
||||
|
||||
val closureParametersCount = capturedValues.size
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
capturedValues.mapIndexedTo(this) { i, capturedValueDescriptor ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValueDescriptor, i).apply {
|
||||
localContext.recordCapturedAsParameter(capturedValueDescriptor, this)
|
||||
}
|
||||
}
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
recordRemappedParameter(oldValueParameterDescriptor, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
return newValueParameters
|
||||
}
|
||||
|
||||
private fun createTransformedMemberDescriptor(oldDescriptor: MemberDescriptor) {
|
||||
when (oldDescriptor) {
|
||||
is PropertyDescriptor -> createTransformedMemberPropertyDescriptor(oldDescriptor)
|
||||
is PropertyAccessorDescriptor -> {
|
||||
// Transformed along with the property.
|
||||
}
|
||||
is FunctionDescriptor -> createTransformedMemberFunctionDescriptor(oldDescriptor)
|
||||
|
||||
else -> TODO(oldDescriptor.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTransformedMemberFunctionDescriptor(oldDescriptor: FunctionDescriptor) {
|
||||
val memberOwner = localClasses[oldDescriptor.containingDeclaration]!!.transformedDescriptor
|
||||
|
||||
val copyBuilder = oldDescriptor.newCopyBuilder()
|
||||
|
||||
copyBuilder.setOwner(memberOwner)
|
||||
copyBuilder.setDispatchReceiverParameter(memberOwner.thisAsReceiverParameter)
|
||||
|
||||
val newDescriptor = copyBuilder.build()!!
|
||||
|
||||
recordTransformedMemberDescriptor(oldDescriptor, newDescriptor)
|
||||
}
|
||||
|
||||
private fun createTransformedMemberPropertyDescriptor(oldDescriptor: PropertyDescriptor) {
|
||||
val memberOwner = localClasses[oldDescriptor.containingDeclaration]!!.transformedDescriptor
|
||||
|
||||
val newDescriptor = PropertyDescriptorImpl.create(
|
||||
memberOwner,
|
||||
oldDescriptor.annotations,
|
||||
oldDescriptor.modality,
|
||||
oldDescriptor.visibility,
|
||||
oldDescriptor.isVar,
|
||||
oldDescriptor.name,
|
||||
oldDescriptor.kind,
|
||||
oldDescriptor.source,
|
||||
oldDescriptor.isLateInit,
|
||||
oldDescriptor.isConst,
|
||||
oldDescriptor.isHeader,
|
||||
oldDescriptor.isImpl,
|
||||
oldDescriptor.isExternal
|
||||
)
|
||||
|
||||
val newDispatchReceiver = memberOwner.thisAsReceiverParameter
|
||||
|
||||
newDescriptor.setType(oldDescriptor.type, oldDescriptor.typeParameters,
|
||||
newDispatchReceiver, oldDescriptor.extensionReceiverParameter?.type)
|
||||
|
||||
val oldGetter = oldDescriptor.getter
|
||||
val newGetter = if (oldGetter == null) {
|
||||
null
|
||||
} else {
|
||||
PropertyGetterDescriptorImpl(
|
||||
newDescriptor, oldGetter.annotations,
|
||||
oldGetter.modality, oldGetter.visibility, oldGetter.isDefault,
|
||||
oldGetter.isExternal, oldGetter.isInline, oldGetter.kind,
|
||||
/* original = */ oldGetter,
|
||||
oldGetter.source
|
||||
).apply {
|
||||
this.initialize(oldGetter.returnType)
|
||||
recordTransformedMemberDescriptor(oldGetter, this)
|
||||
}
|
||||
}
|
||||
|
||||
return newDescriptor
|
||||
val oldSetter = oldDescriptor.setter
|
||||
val newSetter = if (oldSetter == null) {
|
||||
null
|
||||
} else {
|
||||
PropertySetterDescriptorImpl(
|
||||
newDescriptor, oldSetter.annotations,
|
||||
oldSetter.modality, oldSetter.visibility, oldSetter.isDefault,
|
||||
oldSetter.isExternal, oldSetter.isInline, oldSetter.kind,
|
||||
/* original = */ oldSetter,
|
||||
oldSetter.source
|
||||
).apply {
|
||||
val parameter = PropertySetterDescriptorImpl.createSetterParameter(this,
|
||||
oldSetter.valueParameters.single().type)
|
||||
|
||||
this.initialize(parameter)
|
||||
recordTransformedMemberDescriptor(oldSetter, this)
|
||||
}
|
||||
}
|
||||
|
||||
newDescriptor.initialize(newGetter, newSetter)
|
||||
|
||||
recordTransformedMemberDescriptor(oldDescriptor, newDescriptor)
|
||||
}
|
||||
|
||||
private fun LocalFunctionContext.recordRemapped(oldDescriptor: ValueDescriptor, newDescriptor: ParameterDescriptor): ParameterDescriptor {
|
||||
old2new[oldDescriptor] = newDescriptor
|
||||
new2old[newDescriptor] = oldDescriptor
|
||||
return newDescriptor
|
||||
private fun recordTransformedMemberDescriptor(oldDescriptor: CallableDescriptor,
|
||||
newDescriptor: CallableDescriptor
|
||||
) {
|
||||
|
||||
transformedDescriptors[oldDescriptor] = newDescriptor
|
||||
|
||||
if (oldDescriptor.valueParameters.size != newDescriptor.valueParameters.size) throw AssertionError()
|
||||
|
||||
oldDescriptor.valueParameters.forEach {
|
||||
recordRemappedParameter(it, newDescriptor.valueParameters[it.index])
|
||||
}
|
||||
|
||||
val oldDispatchReceiverParameter = oldDescriptor.dispatchReceiverParameter ?:
|
||||
throw AssertionError("members of local classes must have dispatch receiver")
|
||||
|
||||
recordRemappedParameter(oldDispatchReceiverParameter, newDescriptor.dispatchReceiverParameter!!)
|
||||
|
||||
oldDescriptor.extensionReceiverParameter?.let {
|
||||
recordRemappedParameter(it, newDescriptor.extensionReceiverParameter!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun suggestNameForCapturedValueParameter(valueDescriptor: ValueDescriptor): Name =
|
||||
private fun createTransformedConstructorDescriptor(localFunctionContext: LocalClassConstructorContext) {
|
||||
val oldDescriptor = localFunctionContext.descriptor
|
||||
val localClassContext = localClasses[oldDescriptor.containingDeclaration]!!
|
||||
val newDescriptor = ClassConstructorDescriptorImpl.create(
|
||||
localClassContext.transformedDescriptor,
|
||||
Annotations.EMPTY, oldDescriptor.isPrimary, oldDescriptor.source)
|
||||
|
||||
localFunctionContext.transformedDescriptor = newDescriptor
|
||||
transformedDescriptors[oldDescriptor] = newDescriptor
|
||||
|
||||
// Do not substitute type parameters for now.
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
|
||||
val capturedValues = localClassContext.closure.capturedValues
|
||||
|
||||
val newValueParameters = createTransformedValueParameters(localFunctionContext, capturedValues)
|
||||
|
||||
newDescriptor.initialize(
|
||||
newValueParameters,
|
||||
Visibilities.PRIVATE,
|
||||
newTypeParameters
|
||||
)
|
||||
|
||||
oldDescriptor.dispatchReceiverParameter?.let {
|
||||
recordRemappedParameter(it, newDescriptor.dispatchReceiverParameter!!)
|
||||
}
|
||||
|
||||
oldDescriptor.extensionReceiverParameter?.let {
|
||||
throw AssertionError("constructors can't have extension receiver")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createLiftedDescriptor(localClassContext: LocalClassContext) {
|
||||
val irClass = localClassContext.declaration
|
||||
val oldDescriptor = irClass.descriptor
|
||||
|
||||
val memberOwner = memberFunction.descriptor.containingDeclaration
|
||||
val newDescriptor = ClassDescriptorImpl(memberOwner,
|
||||
generateNameForLiftedDeclaration(oldDescriptor, memberOwner),
|
||||
oldDescriptor.modality,
|
||||
oldDescriptor.kind,
|
||||
oldDescriptor.typeConstructor.supertypes,
|
||||
oldDescriptor.source,
|
||||
oldDescriptor.isExternal)
|
||||
|
||||
localClassContext.transformedDescriptor = newDescriptor
|
||||
transformedDescriptors[oldDescriptor] = newDescriptor
|
||||
|
||||
createFieldsForCapturedValues(localClassContext)
|
||||
}
|
||||
|
||||
private fun createFieldsForCapturedValues(localClassContext: LocalClassContext) {
|
||||
val newDescriptor = localClassContext.transformedDescriptor
|
||||
|
||||
localClassContext.closure.capturedValues.forEach { capturedValue ->
|
||||
val fieldDescriptor = PropertyDescriptorImpl.create(
|
||||
newDescriptor,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE,
|
||||
/* isVar = */ false,
|
||||
suggestNameForCapturedValue(capturedValue),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE,
|
||||
/* lateInit = */ false,
|
||||
/* isConst = */ false,
|
||||
/* isHeader = */ false,
|
||||
/* isImpl = */ false,
|
||||
/* isExternal = */ false)
|
||||
|
||||
fieldDescriptor.initialize(/* getter = */ null, /* setter = */ null)
|
||||
|
||||
val extensionReceiverParameter: ReceiverParameterDescriptor? = null
|
||||
|
||||
fieldDescriptor.setType(
|
||||
capturedValue.type,
|
||||
emptyList<TypeParameterDescriptor>(),
|
||||
newDescriptor.thisAsReceiverParameter,
|
||||
extensionReceiverParameter)
|
||||
|
||||
localClassContext.capturedValueToField[capturedValue] = fieldDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeClassDescriptor(localClassContext: LocalClassContext) {
|
||||
val oldDescriptor = localClassContext.declaration.descriptor
|
||||
|
||||
val constructors = oldDescriptor.constructors.map {
|
||||
localClassConstructors[it]!!.transformedDescriptor
|
||||
}.toSet()
|
||||
|
||||
val newPrimaryConstructor = oldDescriptor.unsubstitutedPrimaryConstructor?.let {
|
||||
localClassConstructors[it]!!.transformedDescriptor
|
||||
}
|
||||
|
||||
val newDescriptor = localClassContext.transformedDescriptor
|
||||
|
||||
val oldContributedDescriptors = oldDescriptor.unsubstitutedMemberScope.getContributedDescriptors()
|
||||
val callableMembers = oldContributedDescriptors
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.kind.isReal }
|
||||
.map { it.transformed ?: TODO(it.toString()) }
|
||||
|
||||
val otherMembers = oldContributedDescriptors.filter { it !is CallableMemberDescriptor }
|
||||
|
||||
val fakeOverrides = computeOverrides(newDescriptor, callableMembers)
|
||||
val newUnsubstitutedMemberScope = SimpleMemberScope(otherMembers + callableMembers + fakeOverrides)
|
||||
|
||||
newDescriptor.initialize(newUnsubstitutedMemberScope, constructors, newPrimaryConstructor)
|
||||
}
|
||||
|
||||
private fun LocalContextWithClosureAsParameters.recordCapturedAsParameter(
|
||||
oldDescriptor: ValueDescriptor,
|
||||
newDescriptor: ValueParameterDescriptor
|
||||
) {
|
||||
|
||||
capturedValueToParameter[oldDescriptor] = newDescriptor
|
||||
newParameterToCaptured[newDescriptor] = oldDescriptor
|
||||
|
||||
}
|
||||
|
||||
private fun <K, V> MutableMap<K, V>.putAbsentOrSame(key: K, value: V) {
|
||||
val current = this.getOrPut(key, { value })
|
||||
|
||||
if (current != value) {
|
||||
error("$current != $value")
|
||||
}
|
||||
}
|
||||
|
||||
private fun recordRemappedParameter(oldDescriptor: ParameterDescriptor, newDescriptor: ParameterDescriptor) {
|
||||
oldParameterToNew.putAbsentOrSame(oldDescriptor, newDescriptor)
|
||||
newParameterToOld.putAbsentOrSame(newDescriptor, oldDescriptor)
|
||||
}
|
||||
|
||||
private fun suggestNameForCapturedValue(valueDescriptor: ValueDescriptor): Name =
|
||||
if (valueDescriptor.name.isSpecial) {
|
||||
val oldNameStr = valueDescriptor.name.asString()
|
||||
Name.identifier("$" + oldNameStr.substring(1, oldNameStr.length - 1))
|
||||
@@ -317,7 +812,7 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
ValueParameterDescriptorImpl(
|
||||
newParameterOwner, null, index,
|
||||
valueDescriptor.annotations,
|
||||
suggestNameForCapturedValueParameter(valueDescriptor),
|
||||
suggestNameForCapturedValue(valueDescriptor),
|
||||
valueDescriptor.type,
|
||||
false, false, false, null, valueDescriptor.source
|
||||
)
|
||||
@@ -332,40 +827,80 @@ class LocalDeclarationsLowering(val context: BackendContext): DeclarationContain
|
||||
|
||||
private fun collectClosures() {
|
||||
memberFunction.acceptChildrenVoid(object : AbstractClosureAnnotator() {
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
// ignore local classes for now
|
||||
return
|
||||
}
|
||||
|
||||
override fun recordFunctionClosure(functionDescriptor: FunctionDescriptor, closure: Closure) {
|
||||
localFunctions[functionDescriptor]?.closure = closure
|
||||
}
|
||||
|
||||
override fun recordClassClosure(classDescriptor: ClassDescriptor, closure: Closure) {
|
||||
// ignore local classes for now
|
||||
localClasses[classDescriptor]?.closure = closure
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun collectLocalFunctions() {
|
||||
private fun collectLocalDeclarations() {
|
||||
memberFunction.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||
var lambdasCount = 0
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.isClassMember() = when (this.containingDeclaration) {
|
||||
is CallableDescriptor -> false
|
||||
is ClassDescriptor -> true
|
||||
else -> TODO(this.toString())
|
||||
}
|
||||
|
||||
override fun visitProperty(declaration: IrProperty) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
assert (descriptor.isClassMember())
|
||||
localClassMembers.add(descriptor)
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
val localFunctionContext = LocalFunctionContext(declaration)
|
||||
localFunctions[declaration.descriptor] = localFunctionContext
|
||||
if (declaration.descriptor.name.isSpecial) {
|
||||
localFunctionContext.index = lambdasCount++
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
|
||||
if (descriptor.isClassMember()) {
|
||||
localClassMembers.add(descriptor)
|
||||
} else {
|
||||
val localFunctionContext = LocalFunctionContext(declaration)
|
||||
|
||||
localFunctions[descriptor] = localFunctionContext
|
||||
|
||||
if (descriptor.name.isSpecial) {
|
||||
localFunctionContext.index = lambdasCount++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
assert (descriptor.isClassMember())
|
||||
|
||||
localClassConstructors[descriptor] = LocalClassConstructorContext(declaration)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
// ignore local classes for now
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
|
||||
if (descriptor.isClassMember()) {
|
||||
assert (descriptor.isInner)
|
||||
localClassMembers.add(descriptor)
|
||||
} else {
|
||||
val localClassContext = LocalClassContext(declaration)
|
||||
localClasses[descriptor] = localClassContext
|
||||
if (descriptor.name.isSpecial) {
|
||||
localClassContext.index = objectsCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+54
-2
@@ -1,13 +1,20 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
|
||||
|
||||
@@ -33,4 +40,49 @@ inline fun FunctionIrGenerator.irBlock(expression: IrExpression, origin: IrState
|
||||
this.irBlock(expression.startOffset, expression.endOffset, origin, resultType, body)
|
||||
|
||||
inline fun FunctionIrGenerator.irBlockBody(irElement: IrElement, body: IrBlockBodyBuilder.() -> Unit) =
|
||||
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
||||
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
||||
|
||||
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? = TODO()
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = TODO()
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> = TODO()
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> =
|
||||
members.filter { kindFilter.accepts(it) && nameFilter(it.name) }
|
||||
|
||||
override fun printScopeStructure(p: Printer) = TODO("not implemented")
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user