[IR] Fixed fake override builder for lowerings

This commit is contained in:
Igor Chevdar
2020-09-04 22:26:12 +05:00
parent 7f4bda0d52
commit e39ce91253
13 changed files with 167 additions and 141 deletions
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
@@ -25,8 +24,11 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
@@ -438,63 +440,41 @@ val IrFunction.allParameters: List<IrValueParameter>
explicitParameters explicitParameters
} }
fun IrClass.addFakeOverridesViaIncorrectHeuristic(implementedMembers: List<IrSimpleFunction> = emptyList()) { private object FakeOverrideBuilder : FakeOverrideBuilderStrategy() {
fun IrDeclaration.toList() = when (this) { override fun linkFakeOverride(fakeOverride: IrOverridableMember) {
is IrSimpleFunction -> listOf(this) when (fakeOverride) {
is IrProperty -> listOfNotNull(getter, setter) is IrFakeOverrideFunction -> linkFunctionFakeOverride(fakeOverride)
else -> emptyList() is IrFakeOverrideProperty -> linkPropertyFakeOverride(fakeOverride)
else -> error("Unexpected fake override: $fakeOverride")
}
} }
val overriddenFunctions = (declarations + implementedMembers) private fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) {
.flatMap { it.toList() } declaration.acquireSymbol(IrSimpleFunctionSymbolImpl(WrappedSimpleFunctionDescriptor()))
.flatMap { it.overriddenSymbols.map { it.owner } }
.toSet()
val unoverriddenSuperFunctions = superTypes
.map { it.getClass()!! }
.flatMap { irClass ->
irClass.declarations
.flatMap { it.toList() }
.filter { it !in overriddenFunctions }
.filter { it.visibility != DescriptorVisibilities.PRIVATE }
}
.toMutableSet()
// TODO: A dirty hack.
val groupedUnoverriddenSuperFunctions = unoverriddenSuperFunctions.groupBy { it.name.asString() + it.allParameters.size }
fun createFakeOverride(overriddenFunctions: List<IrSimpleFunction>) =
overriddenFunctions.first().let { irFunction ->
irFunction.factory.buildFun {
origin = IrDeclarationOrigin.FAKE_OVERRIDE
name = irFunction.name
visibility = DescriptorVisibilities.PUBLIC
modality = irFunction.modality
returnType = irFunction.returnType
isInline = irFunction.isInline
isExternal = irFunction.isExternal
isTailrec = irFunction.isTailrec
isSuspend = irFunction.isSuspend
isOperator = irFunction.isOperator
isInfix = irFunction.isInfix
isExpect = irFunction.isExpect
isFakeOverride = true
}.apply {
parent = this@addFakeOverridesViaIncorrectHeuristic
overriddenSymbols = overriddenFunctions.map { it.symbol }
copyParameterDeclarationsFrom(irFunction)
copyAttributes(irFunction)
}
}
val fakeOverriddenFunctions = groupedUnoverriddenSuperFunctions
.asSequence()
.associate { it.value.first() to createFakeOverride(it.value) }
.toMutableMap()
for (fo in fakeOverriddenFunctions.values) {
addChild(fo)
} }
private fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) {
val propertySymbol = IrPropertySymbolImpl(WrappedPropertyDescriptor())
declaration.getter?.let { it.correspondingPropertySymbol = propertySymbol }
declaration.setter?.let { it.correspondingPropertySymbol = propertySymbol }
declaration.acquireSymbol(propertySymbol)
declaration.getter?.let {
it.correspondingPropertySymbol = declaration.symbol
linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it"))
}
declaration.setter?.let {
it.correspondingPropertySymbol = declaration.symbol
linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it"))
}
}
}
fun IrClass.addFakeOverrides(irBuiltIns: IrBuiltIns, implementedMembers: List<IrOverridableMember> = emptyList()) {
IrOverridingUtil(irBuiltIns, FakeOverrideBuilder)
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers)
.forEach { addChild(it) }
} }
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
@@ -354,7 +354,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
} }
coroutineClass.superTypes += superTypes coroutineClass.superTypes += superTypes
coroutineClass.addFakeOverridesViaIncorrectHeuristic() coroutineClass.addFakeOverrides(context.irBuiltIns)
initializeStateMachine(coroutineConstructors, coroutineClassThis) initializeStateMachine(coroutineConstructors, coroutineClassThis)
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.ScopeWithIr import org.jetbrains.kotlin.backend.common.ScopeWithIr
import org.jetbrains.kotlin.backend.common.ir.addFakeOverridesViaIncorrectHeuristic import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
@@ -225,7 +225,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
if (superType.needEqualsHashCodeMethods) if (superType.needEqualsHashCodeMethods)
generateEqualsHashCode(subclass, superType, field) generateEqualsHashCode(subclass, superType, field)
subclass.addFakeOverridesViaIncorrectHeuristic() subclass.addFakeOverrides(context.irBuiltIns)
return subclass return subclass
} }
@@ -5,9 +5,8 @@
package org.jetbrains.kotlin.backend.common.lower.inline package org.jetbrains.kotlin.backend.common.lower.inline
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.ir.util.DescriptorsToIrRemapper
import org.jetbrains.kotlin.backend.common.DescriptorsToIrRemapper import org.jetbrains.kotlin.ir.util.WrappedDescriptorPatcher
import org.jetbrains.kotlin.backend.common.WrappedDescriptorPatcher
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
@@ -438,7 +438,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
coroutineClass.superTypes += coroutineBaseClass.defaultType coroutineClass.superTypes += coroutineBaseClass.defaultType
} }
coroutineClass.addFakeOverridesViaIncorrectHeuristic(implementedMembers) coroutineClass.addFakeOverrides(context.irBuiltIns, implementedMembers)
// TODO: find out whether Kotlin/Native needs this call // TODO: find out whether Kotlin/Native needs this call
initializeStateMachine(listOf(coroutineConstructor), coroutineClassThis) initializeStateMachine(listOf(coroutineConstructor), coroutineClassThis)
@@ -221,7 +221,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
generateSamEqualsHashCodeMethods(boundReceiverVar) generateSamEqualsHashCodeMethods(boundReceiverVar)
} }
if (isKotlinFunInterface) { if (isKotlinFunInterface) {
functionReferenceClass.addFakeOverridesViaIncorrectHeuristic() functionReferenceClass.addFakeOverrides(context.irBuiltIns)
} }
+functionReferenceClass +functionReferenceClass
@@ -1,7 +1,12 @@
package org.jetbrains.kotlin.backend.common.overrides /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
import org.jetbrains.kotlin.backend.common.DescriptorsToIrRemapper package org.jetbrains.kotlin.ir.overrides
import org.jetbrains.kotlin.backend.common.WrappedDescriptorPatcher
import org.jetbrains.kotlin.ir.util.DescriptorsToIrRemapper
import org.jetbrains.kotlin.ir.util.WrappedDescriptorPatcher
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
@@ -84,10 +89,14 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParamet
} }
} }
private val symbolRemapper = FakeOverrideSymbolRemapperImpl(typeArguments, DescriptorsToIrRemapper) private val symbolRemapper =
private val copier = FakeOverrideCopier( FakeOverrideSymbolRemapperImpl(
symbolRemapper, typeArguments,
FakeOverrideTypeRemapper(symbolRemapper, typeArguments), DescriptorsToIrRemapper
SymbolRenamer.DEFAULT
) )
private val copier = FakeOverrideCopier(
symbolRemapper,
FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
SymbolRenamer.DEFAULT
)
} }
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.overrides package org.jetbrains.kotlin.ir.overrides
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* 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.
*/ */
package org.jetbrains.kotlin.backend.common.overrides package org.jetbrains.kotlin.ir.overrides
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -22,27 +11,54 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrDynamicType import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.isReal import org.jetbrains.kotlin.ir.util.isReal
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.incompatible import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.incompatible
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.types.Variance
interface FakeOverrideBuilderStrategy { abstract class FakeOverrideBuilderStrategy {
fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember{
require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
val typeParameters = extractTypeParameters(classifier.owner)
val superArguments = superType.arguments
assert(typeParameters.size == superArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $superArguments size "
}
val substitutionMap = mutableMapOf<IrTypeParameterSymbol, IrType>()
for (i in typeParameters.indices) {
val tp = typeParameters[i]
val ta = superArguments[i]
require(ta is IrTypeProjection) { "Unexpected super type argument: $ta @ $i" }
assert(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
substitutionMap[tp.symbol] = ta.type
}
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz
return deepCopyFakeOverride
}
// TODO: this one doesn't belong here. IrOverridingUtil shouldn't know about symbol table. // TODO: this one doesn't belong here. IrOverridingUtil shouldn't know about symbol table.
fun linkFakeOverride(fakeOverride: IrOverridableMember) abstract fun linkFakeOverride(fakeOverride: IrOverridableMember)
// TODO: need to make IrProperty carry overriddenSymbols. // TODO: need to make IrProperty carry overriddenSymbols.
val propertyOverriddenSymbols: MutableMap<IrOverridableMember, List<IrSymbol>> val propertyOverriddenSymbols: MutableMap<IrOverridableMember, List<IrSymbol>> = mutableMapOf()
} }
// TODO: // TODO:
@@ -127,6 +143,45 @@ class IrOverridingUtil(
} }
} }
fun buildFakeOverridesForClassUsingOverriddenSymbols(
clazz: IrClass,
implementedMembers: List<IrOverridableMember> = emptyList()
): List<IrOverridableMember> {
fakeOverrideBuilder.propertyOverriddenSymbols.clear()
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
.flatMap {
when (it) {
is IrSimpleFunction -> it.overriddenSymbols.map { it.owner }
is IrProperty -> (it.getter ?: it.setter)?.overriddenSymbols
?.map { it.owner.correspondingPropertySymbol!!.owner }
?: emptyList()
else -> error("Unexpected IrOverridableMember: $it")
}
}
.toSet()
val unoverriddenSuperMembers = clazz.superTypes.flatMap { superType ->
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
superClass.declarations
.filterIsInstance<IrOverridableMember>()
.filter { it !in overriddenMembers }
.map { overridenMember ->
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overridenMember, clazz)
originals[fakeOverride] = overridenMember
originalSuperTypes[fakeOverride] = superType
fakeOverride
}
}
val unoverriddenSuperMembersGroupedByName = unoverriddenSuperMembers.groupBy { it.name }
val fakeOverrides = mutableListOf<IrOverridableMember>()
for (group in unoverriddenSuperMembersGroupedByName.values) {
createAndBindFakeOverrides(clazz, group, fakeOverrides)
}
return fakeOverrides
}
private fun generateOverridesInFunctionGroup( private fun generateOverridesInFunctionGroup(
membersFromSupertypes: List<IrOverridableMember>, membersFromSupertypes: List<IrOverridableMember>,
membersFromCurrent: List<IrOverridableMember>, membersFromCurrent: List<IrOverridableMember>,
@@ -139,7 +194,9 @@ class IrOverridingUtil(
notOverridden.removeAll(bound) notOverridden.removeAll(bound)
} }
createAndBindFakeOverrides(current, notOverridden) val addedFakeOverrides = mutableListOf<IrOverridableMember>()
createAndBindFakeOverrides(current, notOverridden, addedFakeOverrides)
current.declarations.addAll(addedFakeOverrides)
} }
private fun extractAndBindOverridesForMember( private fun extractAndBindOverridesForMember(
@@ -150,7 +207,8 @@ class IrOverridingUtil(
val overridden = mutableSetOf<IrOverridableMember>() val overridden = mutableSetOf<IrOverridableMember>()
for (fromSupertype in descriptorsFromSuper) { for (fromSupertype in descriptorsFromSuper) {
val result = isOverridableBy(fromSupertype, fromCurrent/*, current*/).result val result = isOverridableBy(fromSupertype, fromCurrent/*, current*/).result
val isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype.original) val isVisibleForOverride =
isVisibleForOverride(fromCurrent, fromSupertype.original)
when (result) { when (result) {
OverrideCompatibilityInfo.Result.OVERRIDABLE -> { OverrideCompatibilityInfo.Result.OVERRIDABLE -> {
if (isVisibleForOverride) { if (isVisibleForOverride) {
@@ -178,7 +236,8 @@ class IrOverridingUtil(
private fun createAndBindFakeOverrides( private fun createAndBindFakeOverrides(
current: IrClass, current: IrClass,
notOverridden: Collection<IrOverridableMember> notOverridden: Collection<IrOverridableMember>,
addedFakeOverrides: MutableList<IrOverridableMember>
) { ) {
val fromSuper = notOverridden.toMutableSet() val fromSuper = notOverridden.toMutableSet()
while (fromSuper.isNotEmpty()) { while (fromSuper.isNotEmpty()) {
@@ -187,7 +246,7 @@ class IrOverridingUtil(
notOverriddenFromSuper, notOverriddenFromSuper,
fromSuper fromSuper
) )
createAndBindFakeOverride(overridables, current) createAndBindFakeOverride(overridables, current, addedFakeOverrides)
} }
} }
@@ -292,7 +351,8 @@ class IrOverridingUtil(
private fun createAndBindFakeOverride( private fun createAndBindFakeOverride(
overridables: Collection<IrOverridableMember>, overridables: Collection<IrOverridableMember>,
current: IrClass current: IrClass,
addedFakeOverrides: MutableList<IrOverridableMember>
) { ) {
val effectiveOverridden = filterVisibleFakeOverrides(overridables) val effectiveOverridden = filterVisibleFakeOverrides(overridables)
@@ -327,7 +387,7 @@ class IrOverridingUtil(
) { "Overridden symbols should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE } ) { "Overridden symbols should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE }
fakeOverrideBuilder.linkFakeOverride(fakeOverride) fakeOverrideBuilder.linkFakeOverride(fakeOverride)
current.declarations.add(fakeOverride) addedFakeOverrides.add(fakeOverride)
} }
private fun isVisibilityMoreSpecific( private fun isVisibilityMoreSpecific(
@@ -582,7 +642,11 @@ class IrOverridingUtil(
} }
val typeCheckerContext = val typeCheckerContext =
IrTypeCheckerContextWithAdditionalAxioms(irBuiltIns, superTypeParameters, subTypeParameters) IrTypeCheckerContextWithAdditionalAxioms(
irBuiltIns,
superTypeParameters,
subTypeParameters
)
/* TODO: check the bounds. See OverridingUtil.areTypeParametersEquivalent() /* TODO: check the bounds. See OverridingUtil.areTypeParametersEquivalent()
superTypeParameters.forEachIndexed { index, parameter -> superTypeParameters.forEachIndexed { index, parameter ->
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.overrides package org.jetbrains.kotlin.ir.overrides
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility
@@ -1,8 +1,12 @@
package org.jetbrains.kotlin.backend.common.overrides /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.types.IrTypeCheckerContext
import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker
open class IrTypeCheckerContextWithAdditionalAxioms( open class IrTypeCheckerContextWithAdditionalAxioms(
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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 package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
@@ -21,6 +21,9 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.overrides.DeepCopyIrTreeWithSymbolsForFakeOverrides
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
@@ -55,43 +58,10 @@ class FakeOverrideBuilder(
val signaturer: IdSignatureSerializer, val signaturer: IdSignatureSerializer,
val irBuiltIns: IrBuiltIns, val irBuiltIns: IrBuiltIns,
val platformSpecificClassFilter: PlatformFakeOverrideClassFilter = DefaultFakeOverrideClassFilter val platformSpecificClassFilter: PlatformFakeOverrideClassFilter = DefaultFakeOverrideClassFilter
) : FakeOverrideBuilderStrategy { ) : FakeOverrideBuilderStrategy() {
private val haveFakeOverrides = mutableSetOf<IrClass>() private val haveFakeOverrides = mutableSetOf<IrClass>()
override val propertyOverriddenSymbols = mutableMapOf<IrOverridableMember, List<IrSymbol>>()
private val irOverridingUtil = IrOverridingUtil(irBuiltIns, this) private val irOverridingUtil = IrOverridingUtil(irBuiltIns, this)
override fun fakeOverrideMember(
superType: IrType,
member: IrOverridableMember,
clazz: IrClass
): IrOverridableMember {
require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
val typeParameters = extractTypeParameters(classifier.owner)
val superArguments = superType.arguments
assert(typeParameters.size == superArguments.size) {
"typeParameters = $typeParameters size != typeArguments = $superArguments size "
}
val substitutionMap = mutableMapOf<IrTypeParameterSymbol, IrType>()
for (i in typeParameters.indices) {
val tp = typeParameters[i]
val ta = superArguments[i]
require(ta is IrTypeProjection) { "Unexpected super type argument: $ta @ $i" }
assert(ta.variance == Variance.INVARIANT) { "Unexpected variance in super type argument: ${ta.variance} @$i" }
substitutionMap[tp.symbol] = ta.type
}
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz
return deepCopyFakeOverride
}
fun buildFakeOverrideChainsForClass(clazz: IrClass) { fun buildFakeOverrideChainsForClass(clazz: IrClass) {
if (haveFakeOverrides.contains(clazz)) return if (haveFakeOverrides.contains(clazz)) return
if (!platformSpecificClassFilter.constructFakeOverrides(clazz) || !clazz.symbol.isPublicApi) return if (!platformSpecificClassFilter.constructFakeOverrides(clazz) || !clazz.symbol.isPublicApi) return