Generate type parameter declarations for property accessors
This requires "scoped" type parameter symbols, because in the ugly world of descriptors property accessors have no type parameters of their own.
This commit is contained in:
@@ -59,7 +59,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
irClass.descriptor.thisAsReceiverParameter
|
||||
)
|
||||
|
||||
declarationGenerator.generateTypeParameterDeclarations(irClass, descriptor.declaredTypeParameters)
|
||||
declarationGenerator.generateGlobalTypeParametersDeclarations(irClass, descriptor.declaredTypeParameters)
|
||||
|
||||
val irPrimaryConstructor = generatePrimaryConstructor(irClass, ktClassOrObject)
|
||||
if (irPrimaryConstructor != null) {
|
||||
|
||||
+45
-13
@@ -75,31 +75,63 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
)
|
||||
|
||||
|
||||
fun generateTypeParameterDeclarations(
|
||||
fun generateGlobalTypeParametersDeclarations(
|
||||
irTypeParametersOwner: IrTypeParametersContainer,
|
||||
from: List<TypeParameterDescriptor>
|
||||
) {
|
||||
generateTypeParameterDeclarations(irTypeParametersOwner, from) { startOffset, endOffset, typeParameterDescriptor ->
|
||||
context.symbolTable.declareGlobalTypeParameter(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
typeParameterDescriptor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateScopedTypeParameterDeclarations(
|
||||
irTypeParametersOwner: IrTypeParametersContainer,
|
||||
from: List<TypeParameterDescriptor>
|
||||
) {
|
||||
generateTypeParameterDeclarations(irTypeParametersOwner, from) { startOffset, endOffset, typeParameterDescriptor ->
|
||||
context.symbolTable.declareScopedTypeParameter(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
typeParameterDescriptor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateTypeParameterDeclarations(
|
||||
irTypeParametersOwner: IrTypeParametersContainer,
|
||||
from: List<TypeParameterDescriptor>,
|
||||
declareTypeParameter: (Int, Int, TypeParameterDescriptor) -> IrTypeParameter
|
||||
) {
|
||||
from.mapTo(irTypeParametersOwner.typeParameters) { typeParameterDescriptor ->
|
||||
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
|
||||
val startOffset = ktTypeParameterDeclaration.startOffsetOrUndefined
|
||||
val endOffset = ktTypeParameterDeclaration.endOffsetOrUndefined
|
||||
declareTypeParameterWithSuperClassifiers(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
|
||||
declareTypeParameter(
|
||||
startOffset,
|
||||
endOffset,
|
||||
typeParameterDescriptor
|
||||
).also { irTypeParameter ->
|
||||
mapSuperClassifiers(typeParameterDescriptor, irTypeParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun declareTypeParameterWithSuperClassifiers(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: TypeParameterDescriptor
|
||||
) =
|
||||
context.symbolTable.declareTypeParameter(startOffset, endOffset, origin, descriptor).also { irTypeParameter ->
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irTypeParameter.superClassifiers) {
|
||||
it.constructor.declarationDescriptor?.let {
|
||||
context.symbolTable.referenceClassifier(it)
|
||||
}
|
||||
private fun mapSuperClassifiers(
|
||||
descriptor: TypeParameterDescriptor,
|
||||
irTypeParameter: IrTypeParameter
|
||||
) {
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irTypeParameter.superClassifiers) {
|
||||
it.constructor.declarationDescriptor?.let {
|
||||
context.symbolTable.referenceClassifier(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generateInitializerBody(scopeOwnerSymbol: IrSymbol, ktBody: KtExpression): IrExpressionBody =
|
||||
createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody)
|
||||
|
||||
+4
-3
@@ -83,7 +83,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
ktParameterOwner: KtElement?,
|
||||
ktReceiverParameterElement: KtElement?
|
||||
) {
|
||||
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
generateValueParameterDeclarations(irFunction, ktParameterOwner, ktReceiverParameterElement)
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irAccessor, descriptor.correspondingProperty.typeParameters)
|
||||
generateFunctionParameterDeclarations(irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference)
|
||||
val ktBodyExpression = ktAccessor?.bodyExpression
|
||||
irAccessor.body =
|
||||
@@ -117,7 +118,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
descriptor
|
||||
).buildWithScope { irAccessor ->
|
||||
declarationGenerator.generateTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
|
||||
declarationGenerator.generateScopedTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
|
||||
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
|
||||
irAccessor.body = generateDefaultAccessorBody(ktParameter, descriptor, irAccessor)
|
||||
}
|
||||
@@ -229,7 +230,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
||||
}
|
||||
|
||||
fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
declarationGenerator.generateGlobalTypeParametersDeclarations(irFunction, irFunction.descriptor.typeParameters)
|
||||
generateValueParameterDeclarations(irFunction, null, null, withDefaultValues = false)
|
||||
}
|
||||
|
||||
|
||||
+41
-4
@@ -17,13 +17,17 @@
|
||||
package org.jetbrains.kotlin.psi2ir.transformations
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.psi2ir.containsNull
|
||||
@@ -33,12 +37,43 @@ import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.isNullabilityFlexible
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.upperIfFlexible
|
||||
import java.util.*
|
||||
|
||||
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement, symbolTable: SymbolTable) {
|
||||
element.transformChildren(InsertImplicitCasts(builtIns, symbolTable), null)
|
||||
}
|
||||
|
||||
class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symbolTable: SymbolTable) : IrElementTransformerVoid() {
|
||||
private val typeParameterScopes = ArrayDeque<Map<TypeParameterDescriptor, IrTypeParameterSymbol>>()
|
||||
|
||||
private inline fun <T> runInTypeParameterScope(typeParametersContainer: IrTypeParametersContainer, fn: () -> T): T {
|
||||
enterTypeParameterScope(typeParametersContainer)
|
||||
val result = fn()
|
||||
leaveTypeParameterScope()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer) {
|
||||
typeParameterScopes.addFirst(
|
||||
typeParametersContainer.typeParameters.associate {
|
||||
it.descriptor to it.symbol
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun leaveTypeParameterScope() {
|
||||
typeParameterScopes.removeFirst()
|
||||
}
|
||||
|
||||
private fun resolveScopedTypeParameter(classifier: ClassifierDescriptor): IrTypeParameterSymbol? {
|
||||
if (classifier !is TypeParameterDescriptor) return null
|
||||
for (scope in typeParameterScopes) {
|
||||
val local = scope[classifier]
|
||||
if (local != null) return local
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
||||
expression.transformPostfix {
|
||||
transformReceiverArguments()
|
||||
@@ -110,9 +145,11 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement =
|
||||
declaration.transformPostfix {
|
||||
valueParameters.forEach {
|
||||
it.defaultValue?.coerceInnerExpression(it.descriptor.type)
|
||||
runInTypeParameterScope(declaration) {
|
||||
declaration.transformPostfix {
|
||||
valueParameters.forEach {
|
||||
it.defaultValue?.coerceInnerExpression(it.descriptor.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +242,7 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
|
||||
return IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset,
|
||||
targetType, typeOperator, targetType, this,
|
||||
symbolTable.referenceClassifier(typeDescriptor)
|
||||
resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -154,9 +154,15 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.getTypeParametersToTransform() =
|
||||
when {
|
||||
this is PropertyAccessorDescriptor -> correspondingProperty.typeParameters
|
||||
else -> typeParameters
|
||||
}
|
||||
|
||||
protected fun <T : IrFunction> T.transformParameters(original: T): T =
|
||||
apply {
|
||||
transformTypeParameters(original, descriptor.typeParameters)
|
||||
transformTypeParameters(original, descriptor.getTypeParametersToTransform())
|
||||
transformValueParameters(original)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class SymbolTable {
|
||||
private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
|
||||
val unboundSymbols = linkedSetOf<S>()
|
||||
|
||||
protected abstract fun get(d: D): S?
|
||||
abstract fun get(d: D): S?
|
||||
protected abstract fun set(d: D, s: S)
|
||||
|
||||
inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
|
||||
@@ -45,10 +45,10 @@ class SymbolTable {
|
||||
return createOwner(symbol)
|
||||
}
|
||||
|
||||
inline fun referenced(d: D, createSymbol: () -> S): S {
|
||||
inline fun referenced(d: D, orElse: () -> S): S {
|
||||
val s = get(d)
|
||||
if (s == null) {
|
||||
val new = createSymbol()
|
||||
val new = orElse()
|
||||
assert(unboundSymbols.add(new)) {
|
||||
"Symbol for ${new.descriptor} was already referenced"
|
||||
}
|
||||
@@ -149,10 +149,11 @@ class SymbolTable {
|
||||
private val fieldSymbolTable = FlatSymbolTable<PropertyDescriptor, IrField, IrFieldSymbol>()
|
||||
private val simpleFunctionSymbolTable = FlatSymbolTable<FunctionDescriptor, IrSimpleFunction, IrSimpleFunctionSymbol>()
|
||||
|
||||
private val typeParameterSymbolTable = FlatSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
|
||||
private val globalTypeParameterSymbolTable = FlatSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
|
||||
private val scopedTypeParameterSymbolTable = ScopedSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
|
||||
private val valueParameterSymbolTable = ScopedSymbolTable<ParameterDescriptor, IrValueParameter, IrValueParameterSymbol>()
|
||||
private val variableSymbolTable = ScopedSymbolTable<VariableDescriptor, IrVariable, IrVariableSymbol>()
|
||||
private val scopedSymbolTables = listOf(valueParameterSymbolTable, variableSymbolTable)
|
||||
private val scopedSymbolTables = listOf(valueParameterSymbolTable, variableSymbolTable, scopedTypeParameterSymbolTable)
|
||||
|
||||
fun declareFile(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor): IrFile =
|
||||
IrFileImpl(fileEntry, IrFileSymbolImpl(packageFragmentDescriptor))
|
||||
@@ -250,22 +251,31 @@ class SymbolTable {
|
||||
|
||||
val unboundSimpleFunctions: Set<IrSimpleFunctionSymbol> get() = simpleFunctionSymbolTable.unboundSymbols
|
||||
|
||||
fun declareTypeParameter(
|
||||
fun declareGlobalTypeParameter(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: TypeParameterDescriptor
|
||||
): IrTypeParameter =
|
||||
typeParameterSymbolTable.declare(
|
||||
globalTypeParameterSymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrTypeParameterSymbolImpl(descriptor) },
|
||||
{ IrTypeParameterImpl(startOffset, endOffset, origin, it) }
|
||||
)
|
||||
|
||||
fun referenceTypeParameter(descriptor: TypeParameterDescriptor) =
|
||||
typeParameterSymbolTable.referenced(descriptor) { throw AssertionError("Undefined type parameter referenced: $descriptor") }
|
||||
fun declareScopedTypeParameter(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: TypeParameterDescriptor
|
||||
): IrTypeParameter =
|
||||
scopedTypeParameterSymbolTable.declare(
|
||||
descriptor,
|
||||
{ IrTypeParameterSymbolImpl(descriptor) },
|
||||
{ IrTypeParameterImpl(startOffset, endOffset, origin, it) }
|
||||
)
|
||||
|
||||
val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = typeParameterSymbolTable.unboundSymbols
|
||||
val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = globalTypeParameterSymbolTable.unboundSymbols
|
||||
|
||||
fun declareValueParameter(
|
||||
startOffset: Int,
|
||||
@@ -288,6 +298,12 @@ class SymbolTable {
|
||||
throw AssertionError("Undefined parameter referenced: $descriptor\n${valueParameterSymbolTable.dump()}")
|
||||
}
|
||||
|
||||
fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol =
|
||||
scopedTypeParameterSymbolTable.get(classifier)
|
||||
?: globalTypeParameterSymbolTable.referenced(classifier) {
|
||||
throw AssertionError("Undefined type parameter referenced: $classifier")
|
||||
}
|
||||
|
||||
val unboundValueParameters: Set<IrValueParameterSymbol> get() = valueParameterSymbolTable.unboundSymbols
|
||||
|
||||
fun declareVariable(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor): IrVariable =
|
||||
@@ -342,9 +358,7 @@ class SymbolTable {
|
||||
fun referenceClassifier(classifier: ClassifierDescriptor): IrClassifierSymbol =
|
||||
when (classifier) {
|
||||
is TypeParameterDescriptor ->
|
||||
typeParameterSymbolTable.referenced(classifier) {
|
||||
throw AssertionError("Undefined type parameter referenced: $classifier")
|
||||
}
|
||||
referenceTypeParameter(classifier)
|
||||
is ClassDescriptor ->
|
||||
classSymbolTable.referenced(classifier) { IrClassSymbolImpl(classifier) }
|
||||
else ->
|
||||
|
||||
Reference in New Issue
Block a user