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:
Dmitry Petrov
2018-03-02 13:12:01 +03:00
parent 31996f1139
commit 13a7270129
16 changed files with 473 additions and 44 deletions
@@ -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) {
@@ -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)
@@ -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)
}
@@ -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 ->
@@ -29,18 +29,27 @@ FILE fqName:<root> fileName:/propertyAccessors.kt
VALUE_PARAMETER name:value index:0 type:kotlin.Int flags:
BLOCK_BODY
PROPERTY name:testExt3 type:kotlin.Int visibility:public modality:FINAL flags:val
FUN name:<get-testExt3> visibility:public modality:FINAL <> ($receiver:T) returnType:Int flags:
FUN name:<get-testExt3> visibility:public modality:FINAL <T> ($receiver:T) returnType:Int flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:T flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-testExt3>() on T: Int'
CONST Int type=kotlin.Int value=42
PROPERTY name:testExt4 type:kotlin.Int visibility:public modality:FINAL flags:var
FUN name:<get-testExt4> visibility:public modality:FINAL <> ($receiver:T) returnType:Int flags:
FUN name:<get-testExt4> visibility:public modality:FINAL <T> ($receiver:T) returnType:Int flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:T flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-testExt4>() on T: Int'
CONST Int type=kotlin.Int value=42
FUN name:<set-testExt4> visibility:public modality:FINAL <> ($receiver:T, value:kotlin.Int) returnType:Unit flags:
FUN name:<set-testExt4> visibility:public modality:FINAL <T> ($receiver:T, value:kotlin.Int) returnType:Unit flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:T flags:
VALUE_PARAMETER name:value index:0 type:kotlin.Int flags:
BLOCK_BODY
@@ -91,20 +100,29 @@ FILE fqName:<root> fileName:/propertyAccessors.kt
VALUE_PARAMETER name:value index:0 type:kotlin.Int flags:
BLOCK_BODY
PROPERTY name:testMemExt3 type:kotlin.Int visibility:public modality:FINAL flags:val
FUN name:<get-testMemExt3> visibility:public modality:FINAL <> ($this:Host<T>, $receiver:TT) returnType:Int flags:
FUN name:<get-testMemExt3> visibility:public modality:FINAL <TT> ($this:Host<T>, $receiver:TT) returnType:Int flags:
TYPE_PARAMETER name:TT index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:TT flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-testMemExt3>() on TT: Int'
CONST Int type=kotlin.Int value=42
PROPERTY name:testMemExt4 type:kotlin.Int visibility:public modality:FINAL flags:var
FUN name:<get-testMemExt4> visibility:public modality:FINAL <> ($this:Host<T>, $receiver:TT) returnType:Int flags:
FUN name:<get-testMemExt4> visibility:public modality:FINAL <TT> ($this:Host<T>, $receiver:TT) returnType:Int flags:
TYPE_PARAMETER name:TT index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:TT flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-testMemExt4>() on TT: Int'
CONST Int type=kotlin.Int value=42
FUN name:<set-testMemExt4> visibility:public modality:FINAL <> ($this:Host<T>, $receiver:TT, value:kotlin.Int) returnType:Unit flags:
FUN name:<set-testMemExt4> visibility:public modality:FINAL <TT> ($this:Host<T>, $receiver:TT, value:kotlin.Int) returnType:Unit flags:
TYPE_PARAMETER name:TT index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:TT flags:
VALUE_PARAMETER name:value index:0 type:kotlin.Int flags:
@@ -0,0 +1,24 @@
fun <T> castFun(x: Any) = x as T
fun <T> Any.castExtFun() = this as T
val <T> T.castExtVal
get() = this as T
class Host<T> {
fun castMemberFun(x: Any) = x as T
fun <TF> castGenericMemberFun(x: Any) = x as TF
fun Any.castMemberExtFun() = this as T
fun <TF> Any.castGenericMemberExtFun() = this as TF
val Any.castMemberExtVal
get() = this as T
val <TV> TV.castGenericMemberExtVal
get() = this as TV
}
@@ -0,0 +1,115 @@
FILE fqName:<root> fileName:/castToTypeParameter.kt
FUN name:castFun visibility:public modality:FINAL <T> (x:kotlin.Any) returnType:T flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
VALUE_PARAMETER name:x index:0 type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='castFun(Any): T'
TYPE_OP type=T origin=CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null
FUN name:castExtFun visibility:public modality:FINAL <T> ($receiver:kotlin.Any) returnType:T flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='castExtFun() on Any: T'
TYPE_OP type=T origin=CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'this@castExtFun: Any' type=kotlin.Any origin=null
PROPERTY name:castExtVal type:T visibility:public modality:FINAL flags:val
FUN name:<get-castExtVal> visibility:public modality:FINAL <T> ($receiver:T) returnType:T flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:T flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-castExtVal>() on T: T'
TYPE_OP type=T origin=CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'this@castExtVal: T' type=T origin=null
CLASS CLASS name:Host modality:FINAL visibility:public flags:
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:Host<T> flags:
superClasses:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
CONSTRUCTOR visibility:public <> () returnType:Host<T> flags:
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='Host'
FUN name:castMemberFun visibility:public modality:FINAL <> ($this:Host<T>, x:kotlin.Any) returnType:T flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
VALUE_PARAMETER name:x index:0 type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='castMemberFun(Any): T'
TYPE_OP type=T origin=CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null
FUN name:castGenericMemberFun visibility:public modality:FINAL <TF> ($this:Host<T>, x:kotlin.Any) returnType:TF flags:
TYPE_PARAMETER name:TF index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
VALUE_PARAMETER name:x index:0 type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='castGenericMemberFun(Any): TF'
TYPE_OP type=TF origin=CAST typeOperand=TF
typeOperand: TYPE_PARAMETER name:TF index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null
FUN name:castMemberExtFun visibility:public modality:FINAL <> ($this:Host<T>, $receiver:kotlin.Any) returnType:T flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='castMemberExtFun() on Any: T'
TYPE_OP type=T origin=CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'this@castMemberExtFun: Any' type=kotlin.Any origin=null
FUN name:castGenericMemberExtFun visibility:public modality:FINAL <TF> ($this:Host<T>, $receiver:kotlin.Any) returnType:TF flags:
TYPE_PARAMETER name:TF index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='castGenericMemberExtFun() on Any: TF'
TYPE_OP type=TF origin=CAST typeOperand=TF
typeOperand: TYPE_PARAMETER name:TF index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'this@castGenericMemberExtFun: Any' type=kotlin.Any origin=null
PROPERTY name:castMemberExtVal type:T visibility:public modality:FINAL flags:val
FUN name:<get-castMemberExtVal> visibility:public modality:FINAL <> ($this:Host<T>, $receiver:kotlin.Any) returnType:T flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-castMemberExtVal>() on Any: T'
TYPE_OP type=T origin=CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'this@castMemberExtVal: Any' type=kotlin.Any origin=null
PROPERTY name:castGenericMemberExtVal type:TV visibility:public modality:FINAL flags:val
FUN name:<get-castGenericMemberExtVal> visibility:public modality:FINAL <TV> ($this:Host<T>, $receiver:TV) returnType:TV flags:
TYPE_PARAMETER name:TV index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host<T> flags:
$receiver: VALUE_PARAMETER name:<this> type:TV flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-castGenericMemberExtVal>() on TV: TV'
TYPE_OP type=TV origin=CAST typeOperand=TV
typeOperand: TYPE_PARAMETER name:TV index:0 variance: upperBounds:[kotlin.Any?]
GET_VAR 'this@castGenericMemberExtVal: TV' type=TV origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:Boolean flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> (other:kotlin.Any?) returnType:Boolean flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags:
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:Int flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> () returnType:Int flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:String flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> () returnType:String flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
@@ -1,6 +1,9 @@
FILE fqName:<root> fileName:/genericPropertyCall.kt
PROPERTY name:id type:T visibility:public modality:FINAL flags:val
FUN name:<get-id> visibility:public modality:FINAL <> ($receiver:T) returnType:T flags:
FUN name:<get-id> visibility:public modality:FINAL <T> ($receiver:T) returnType:T flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:T flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-id>() on T: T'
@@ -0,0 +1,7 @@
inline fun <reified T : Any> Any.test1(): T? =
if (this is T) this else null
interface Foo<T>
inline val <reified T : Any> Foo<T>.asT: T?
get() = if (this is T) this else null
@@ -0,0 +1,58 @@
FILE fqName:<root> fileName:/implicitCastToTypeParameter.kt
FUN name:test1 visibility:public modality:FINAL <T> ($receiver:kotlin.Any) returnType:T? flags:inline
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='test1() on Any: T?'
WHEN type=T? origin=null
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
GET_VAR 'this@test1: Any' type=kotlin.Any origin=null
then: TYPE_OP type=T origin=IMPLICIT_CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
GET_VAR 'this@test1: Any' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Null type=kotlin.Nothing? value=null
CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public flags:
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:Foo<T> flags:
superClasses:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:Boolean flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> (other:kotlin.Any?) returnType:Boolean flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags:
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:Int flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> () returnType:Int flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:String flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> () returnType:String flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
PROPERTY name:asT type:T? visibility:public modality:FINAL flags:val
FUN name:<get-asT> visibility:public modality:FINAL <T> ($receiver:Foo<T>) returnType:T? flags:inline
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:Foo<T> flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-asT>() on Foo<T>: T?'
WHEN type=T? origin=null
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
GET_VAR 'this@asT: Foo<T>' type=Foo<T> origin=null
then: TYPE_OP type=T origin=IMPLICIT_CAST typeOperand=T
typeOperand: TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
GET_VAR 'this@asT: Foo<T>' type=Foo<T> origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Null type=kotlin.Nothing? value=null
@@ -0,0 +1,17 @@
inline fun <reified T : Any> classRefFun() = T::class
inline fun <reified T : Any> Any.classRefExtFun() = T::class
inline val <reified T : Any> T.classRefExtVal
get() = T::class
class Host {
inline fun <reified TF : Any> classRefGenericMemberFun() = TF::class
inline fun <reified TF : Any> Any.classRefGenericMemberExtFun() = TF::class
inline val <reified TV : Any> TV.classRefGenericMemberExtVal
get() = TV::class
}
@@ -0,0 +1,73 @@
FILE fqName:<root> fileName:/typeParameterClassLiteral.kt
FUN name:classRefFun visibility:public modality:FINAL <T> () returnType:KClass<T> flags:inline
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='classRefFun(): KClass<T>'
CLASS_REFERENCE '<reified T : Any>' type=kotlin.reflect.KClass<T>
FUN name:classRefExtFun visibility:public modality:FINAL <T> ($receiver:kotlin.Any) returnType:KClass<T> flags:inline
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='classRefExtFun() on Any: KClass<T>'
CLASS_REFERENCE '<reified T : Any>' type=kotlin.reflect.KClass<T>
PROPERTY name:classRefExtVal type:kotlin.reflect.KClass<T> visibility:public modality:FINAL flags:val
FUN name:<get-classRefExtVal> visibility:public modality:FINAL <T> ($receiver:T) returnType:KClass<T> flags:inline
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:T flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-classRefExtVal>() on T: KClass<T>'
CLASS_REFERENCE '<reified T : Any>' type=kotlin.reflect.KClass<T>
CLASS CLASS name:Host modality:FINAL visibility:public flags:
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:Host flags:
superClasses:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
CONSTRUCTOR visibility:public <> () returnType:Host flags:
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='Host'
FUN name:classRefGenericMemberFun visibility:public modality:FINAL <TF> ($this:Host) returnType:KClass<TF> flags:inline
TYPE_PARAMETER name:TF index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='classRefGenericMemberFun(): KClass<TF>'
CLASS_REFERENCE '<reified TF : Any>' type=kotlin.reflect.KClass<TF>
FUN name:classRefGenericMemberExtFun visibility:public modality:FINAL <TF> ($this:Host, $receiver:kotlin.Any) returnType:KClass<TF> flags:inline
TYPE_PARAMETER name:TF index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host flags:
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='classRefGenericMemberExtFun() on Any: KClass<TF>'
CLASS_REFERENCE '<reified TF : Any>' type=kotlin.reflect.KClass<TF>
PROPERTY name:classRefGenericMemberExtVal type:kotlin.reflect.KClass<TV> visibility:public modality:FINAL flags:val
FUN name:<get-classRefGenericMemberExtVal> visibility:public modality:FINAL <TV> ($this:Host, $receiver:TV) returnType:KClass<TV> flags:inline
TYPE_PARAMETER name:TV index:0 variance: upperBounds:[kotlin.Any]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
$this: VALUE_PARAMETER name:<this> type:Host flags:
$receiver: VALUE_PARAMETER name:<this> type:TV flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-classRefGenericMemberExtVal>() on TV: KClass<TV>'
CLASS_REFERENCE '<reified TV : Any>' type=kotlin.reflect.KClass<TV>
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:Boolean flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> (other:kotlin.Any?) returnType:Boolean flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags:
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:Int flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> () returnType:Int flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:String flags:
overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> () returnType:String flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
@@ -50,12 +50,18 @@ FILE fqName:<root> fileName:/integerCoercionToT.kt
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
TYPEALIAS typealias CInt32Var = CInt32VarX<Int> type=CInt32VarX<kotlin.Int>
PROPERTY name:value type:T_INT visibility:public modality:FINAL flags:var
FUN name:<get-value> visibility:public modality:FINAL <> ($receiver:CInt32VarX<T_INT>) returnType:T_INT flags:
FUN name:<get-value> visibility:public modality:FINAL <T_INT> ($receiver:CInt32VarX<T_INT>) returnType:T_INT flags:
TYPE_PARAMETER name:T_INT index:0 variance: upperBounds:[kotlin.Int]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:CInt32VarX<T_INT> flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-value>() on CInt32VarX<T_INT>: T_INT'
CALL 'TODO(): Nothing' type=kotlin.Nothing origin=null
FUN name:<set-value> visibility:public modality:FINAL <> ($receiver:CInt32VarX<T_INT>, value:T_INT) returnType:Unit flags:
FUN name:<set-value> visibility:public modality:FINAL <T_INT> ($receiver:CInt32VarX<T_INT>, value:T_INT) returnType:Unit flags:
TYPE_PARAMETER name:T_INT index:0 variance: upperBounds:[kotlin.Int]
superClassifiers:
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Int modality:FINAL visibility:public flags:
$receiver: VALUE_PARAMETER name:<this> type:CInt32VarX<T_INT> flags:
VALUE_PARAMETER name:value index:0 type:T_INT flags:
BLOCK_BODY
@@ -621,6 +621,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("castToTypeParameter.kt")
public void testCastToTypeParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/castToTypeParameter.kt");
doTest(fileName);
}
@TestMetadata("catchParameterAccess.kt")
public void testCatchParameterAccess() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/catchParameterAccess.kt");
@@ -765,6 +771,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("implicitCastToTypeParameter.kt")
public void testImplicitCastToTypeParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/implicitCastToTypeParameter.kt");
doTest(fileName);
}
@TestMetadata("in.kt")
public void testIn() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/in.kt");
@@ -981,6 +993,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("typeParameterClassLiteral.kt")
public void testTypeParameterClassLiteral() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/typeParameterClassLiteral.kt");
doTest(fileName);
}
@TestMetadata("values.kt")
public void testValues() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/values.kt");