Skip to content

Commit b206bf1

Browse files
committed
Add type operand symbol for type operator expression
1 parent e89047d commit b206bf1

File tree

65 files changed

+443
-62
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+443
-62
lines changed

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
5555
}
5656

5757
private fun postprocess(context: GeneratorContext, irElement: IrElement) {
58-
insertImplicitCasts(context.builtIns, irElement)
58+
insertImplicitCasts(context.builtIns, irElement, context.symbolTable)
5959

6060
postprocessingSteps.forEach { it.postprocess(context, irElement) }
6161

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.jetbrains.kotlin.psi2ir.generators
1818

19+
import org.jetbrains.kotlin.backend.common.descriptors.substitute
1920
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
2021
import org.jetbrains.kotlin.descriptors.*
2122
import org.jetbrains.kotlin.ir.declarations.*
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
3334
import org.jetbrains.kotlin.resolve.BindingContext
3435
import org.jetbrains.kotlin.resolve.DescriptorUtils
3536
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
37+
import org.jetbrains.kotlin.types.KotlinType
3638
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
3739
import java.lang.AssertionError
3840

@@ -94,18 +96,17 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
9496
}
9597

9698
private fun generateMembersDeclaredInSupertypeList(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
97-
ktClassOrObject.getSuperTypeList()?.let { ktSuperTypeList ->
98-
val delegatedMembers = irClass.descriptor.unsubstitutedMemberScope
99-
.getContributedDescriptors(DescriptorKindFilter.CALLABLES)
100-
.filterIsInstance<CallableMemberDescriptor>()
101-
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
102-
.sortedWith(StableDescriptorsComparator)
103-
if (delegatedMembers.isEmpty()) return
104-
105-
for (ktEntry in ktSuperTypeList.entries) {
106-
if (ktEntry is KtDelegatedSuperTypeEntry) {
107-
generateDelegatedImplementationMembers(irClass, ktEntry, delegatedMembers)
108-
}
99+
val ktSuperTypeList = ktClassOrObject.getSuperTypeList() ?: return
100+
val delegatedMembers = irClass.descriptor.unsubstitutedMemberScope
101+
.getContributedDescriptors(DescriptorKindFilter.CALLABLES)
102+
.filterIsInstance<CallableMemberDescriptor>()
103+
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
104+
.sortedWith(StableDescriptorsComparator)
105+
if (delegatedMembers.isEmpty()) return
106+
107+
for (ktEntry in ktSuperTypeList.entries) {
108+
if (ktEntry is KtDelegatedSuperTypeEntry) {
109+
generateDelegatedImplementationMembers(irClass, ktEntry, delegatedMembers)
109110
}
110111
}
111112
}
@@ -139,8 +140,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
139140
}
140141

141142
private fun generateDelegatedMember(
142-
irClass: IrClass, irDelegate: IrField,
143-
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor
143+
irClass: IrClass,
144+
irDelegate: IrField,
145+
delegatedMember: CallableMemberDescriptor,
146+
overriddenMember: CallableMemberDescriptor
144147
) {
145148
when (delegatedMember) {
146149
is FunctionDescriptor ->
@@ -198,15 +201,22 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
198201
}
199202

200203
private fun generateDelegateFunctionBody(
201-
irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
204+
irDelegate: IrField,
205+
delegated: FunctionDescriptor,
206+
overridden: FunctionDescriptor,
202207
irDelegatedFunction: IrSimpleFunction
203208
): IrBlockBodyImpl {
204209
val startOffset = irDelegate.startOffset
205210
val endOffset = irDelegate.endOffset
206211
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
207-
val returnType = overridden.returnType!!
208-
val irCall =
209-
IrCallImpl(startOffset, endOffset, returnType, context.symbolTable.referenceFunction(overridden.original), overridden, null)
212+
val substitutedOverridden = substituteOverriddenDescriptorForDelegate(delegated, overridden)
213+
val returnType = substitutedOverridden.returnType!!
214+
val irCall = IrCallImpl(
215+
startOffset, endOffset, returnType,
216+
context.symbolTable.referenceFunction(overridden.original),
217+
substitutedOverridden,
218+
null
219+
)
210220
irCall.dispatchReceiver =
211221
IrGetFieldImpl(
212222
startOffset, endOffset, irDelegate.symbol,
@@ -230,6 +240,20 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
230240
return irBlockBody
231241
}
232242

243+
private fun substituteOverriddenDescriptorForDelegate(
244+
delegated: FunctionDescriptor,
245+
overridden: FunctionDescriptor
246+
): FunctionDescriptor {
247+
// TODO PropertyAccessorDescriptor doesn't support 'substitute' right now :(
248+
if (overridden is PropertyAccessorDescriptor) return overridden
249+
250+
val typeArguments = HashMap<TypeParameterDescriptor, KotlinType>()
251+
for ((i, overriddenTypeParameter) in overridden.typeParameters.withIndex()) {
252+
typeArguments[overriddenTypeParameter] = delegated.typeParameters[i].defaultType
253+
}
254+
return overridden.substitute(typeArguments)
255+
}
256+
233257
private fun generateAdditionalMembersForDataClass(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
234258
DataClassMembersGenerator(declarationGenerator).generate(ktClassOrObject, irClass)
235259
}

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
135135
override fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
136136
buildMember(function, declaration) {
137137
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
138-
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType))
139-
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
138+
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType, irClass.symbol))
139+
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType, irClass.symbol), "other_with_cast")
140140
for (property in properties) {
141141
val arg1 = irGet(irThis(), getPropertyGetterSymbol(property))
142142
val arg2 = irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
9292

9393
return IrTypeOperatorCallImpl(
9494
expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
95-
expression.left.genExpr()
95+
expression.left.genExpr(),
96+
context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!)
9697
)
9798
}
9899

@@ -103,7 +104,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
103104

104105
return IrTypeOperatorCallImpl(
105106
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
106-
againstType, expression.leftHandSide.genExpr()
107+
againstType, expression.leftHandSide.genExpr(),
108+
context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!)
107109
)
108110
}
109111

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
2424
import org.jetbrains.kotlin.ir.declarations.IrVariable
2525
import org.jetbrains.kotlin.ir.expressions.*
2626
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
27+
import org.jetbrains.kotlin.ir.util.SymbolTable
2728
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
2829
import org.jetbrains.kotlin.psi2ir.containsNull
2930
import org.jetbrains.kotlin.types.KotlinType
@@ -33,11 +34,11 @@ import org.jetbrains.kotlin.types.isNullabilityFlexible
3334
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
3435
import org.jetbrains.kotlin.types.upperIfFlexible
3536

36-
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) {
37-
element.transformChildren(InsertImplicitCasts(builtIns), null)
37+
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement, symbolTable: SymbolTable) {
38+
element.transformChildren(InsertImplicitCasts(builtIns, symbolTable), null)
3839
}
3940

40-
class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVoid() {
41+
class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symbolTable: SymbolTable) : IrElementTransformerVoid() {
4142
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
4243
expression.transformPostfix {
4344
transformReceiverArguments()
@@ -175,31 +176,39 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVo
175176

176177
valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.containsNull() -> {
177178
val nonNullValueType = valueType.upperIfFlexible().makeNotNullable()
178-
IrTypeOperatorCallImpl(
179-
startOffset, endOffset, nonNullValueType,
180-
IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this
181-
).cast(expectedType)
179+
implicitCast(nonNullValueType, IrTypeOperator.IMPLICIT_NOTNULL).cast(expectedType)
182180
}
183181

184182
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) ->
185183
this
186184

187185
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
188-
IrTypeOperatorCallImpl(
189-
startOffset, endOffset, notNullableExpectedType,
190-
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this
191-
)
186+
implicitCast(notNullableExpectedType, IrTypeOperator.IMPLICIT_INTEGER_COERCION)
187+
188+
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType) ->
189+
this
192190

193191
else -> {
194192
val targetType = if (!valueType.containsNull()) notNullableExpectedType else expectedType
195-
IrTypeOperatorCallImpl(
196-
startOffset, endOffset, targetType,
197-
IrTypeOperator.IMPLICIT_CAST, targetType, this
198-
)
193+
implicitCast(targetType, IrTypeOperator.IMPLICIT_CAST)
199194
}
200195
}
201196
}
202197

198+
private fun IrExpression.implicitCast(
199+
targetType: KotlinType,
200+
typeOperator: IrTypeOperator
201+
): IrExpression {
202+
val typeDescriptor = targetType.constructor.declarationDescriptor
203+
?: throw AssertionError("No declaration for target type: $targetType")
204+
205+
return IrTypeOperatorCallImpl(
206+
startOffset, endOffset,
207+
targetType, typeOperator, targetType, this,
208+
symbolTable.referenceClassifier(typeDescriptor)
209+
)
210+
}
211+
203212
private fun IrExpression.coerceToUnit(): IrExpression {
204213
val valueType = this.type
205214

@@ -208,7 +217,8 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVo
208217
else
209218
IrTypeOperatorCallImpl(
210219
startOffset, endOffset, builtIns.unitType,
211-
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this
220+
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this,
221+
symbolTable.referenceClass(builtIns.unit)
212222
)
213223
}
214224

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.IrElement
2121
import org.jetbrains.kotlin.ir.declarations.IrVariable
2222
import org.jetbrains.kotlin.ir.expressions.*
2323
import org.jetbrains.kotlin.ir.expressions.impl.*
24+
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
2425
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
2526
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
2627
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
@@ -168,18 +169,42 @@ fun IrBuilderWithScope.irCallOp(
168169
putValueArgument(0, argument)
169170
}
170171

172+
@Deprecated("Creates unbound symbol")
171173
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType) =
172174
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument)
173175

176+
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
177+
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument, typeClassifier)
178+
179+
180+
@Deprecated("Creates unbound symbol")
174181
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType) =
175182
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.NOT_INSTANCEOF, type, argument)
176183

184+
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
185+
IrTypeOperatorCallImpl(
186+
startOffset, endOffset,
187+
context.builtIns.booleanType,
188+
IrTypeOperator.NOT_INSTANCEOF,
189+
type, argument, typeClassifier
190+
)
191+
192+
193+
@Deprecated("Creates unbound symbol")
177194
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType) =
178195
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument)
179196

197+
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
198+
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument, typeClassifier)
199+
200+
@Deprecated("Creates unbound symbol")
180201
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType) =
181202
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument)
182203

204+
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
205+
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument, typeClassifier)
206+
207+
183208
fun IrBuilderWithScope.irInt(value: Int) =
184209
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
185210

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorCall.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.jetbrains.kotlin.ir.expressions
1818

19+
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
1920
import org.jetbrains.kotlin.types.KotlinType
2021

2122
enum class IrTypeOperator {
@@ -33,5 +34,6 @@ interface IrTypeOperatorCall : IrExpression {
3334
val operator: IrTypeOperator
3435
var argument: IrExpression
3536
val typeOperand: KotlinType
37+
val typeOperandClassifier: IrClassifierSymbol
3638
}
3739

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrClassReferenceImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ class IrClassReferenceImpl(
4444
type: KotlinType,
4545
descriptor: ClassifierDescriptor,
4646
classType: KotlinType
47-
) : this(startOffset, endOffset, type, createClassifierSymbolForClassReference(descriptor), classType)
47+
) : this(startOffset, endOffset, type, createClassifierSymbol(descriptor), classType)
4848

4949
override val descriptor: ClassifierDescriptor get() = symbol.descriptor
5050

5151
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
5252
visitor.visitClassReference(this, data)
5353
}
5454

55-
internal fun createClassifierSymbolForClassReference(descriptor: ClassifierDescriptor): IrClassifierSymbol =
55+
internal fun createClassifierSymbol(descriptor: ClassifierDescriptor): IrClassifierSymbol =
5656
when (descriptor) {
5757
is ClassDescriptor -> IrClassSymbolImpl(descriptor)
5858
is TypeParameterDescriptor -> IrTypeParameterSymbolImpl(descriptor)

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTypeOperatorCallImpl.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
1919
import org.jetbrains.kotlin.ir.expressions.IrExpression
2020
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
2121
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
22+
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
2223
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
2324
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
2425
import org.jetbrains.kotlin.types.KotlinType
@@ -30,6 +31,7 @@ class IrTypeOperatorCallImpl(
3031
override val operator: IrTypeOperator,
3132
override val typeOperand: KotlinType
3233
) : IrExpressionBase(startOffset, endOffset, type), IrTypeOperatorCall {
34+
@Deprecated("Creates unbound symbol")
3335
constructor(
3436
startOffset: Int,
3537
endOffset: Int,
@@ -39,9 +41,28 @@ class IrTypeOperatorCallImpl(
3941
argument: IrExpression
4042
) : this(startOffset, endOffset, type, operator, typeOperand) {
4143
this.argument = argument
44+
45+
val typeOperandDescriptor = typeOperand.constructor.declarationDescriptor
46+
if (typeOperandDescriptor != null) {
47+
this.typeOperandClassifier = createClassifierSymbol(typeOperandDescriptor)
48+
}
49+
}
50+
51+
constructor(
52+
startOffset: Int,
53+
endOffset: Int,
54+
type: KotlinType,
55+
operator: IrTypeOperator,
56+
typeOperand: KotlinType,
57+
argument: IrExpression,
58+
typeOperandClassifier: IrClassifierSymbol
59+
) : this(startOffset, endOffset, type, operator, typeOperand) {
60+
this.argument = argument
61+
this.typeOperandClassifier = typeOperandClassifier
4262
}
4363

4464
override lateinit var argument: IrExpression
65+
override lateinit var typeOperandClassifier: IrClassifierSymbol
4566

4667
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
4768
visitor.visitTypeOperator(this, data)

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,15 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
506506
expression.type,
507507
expression.operator,
508508
expression.typeOperand,
509-
expression.argument.transform()
509+
expression.argument.transform(),
510+
run {
511+
val oldTypeDescriptor = expression.typeOperandClassifier.descriptor
512+
val newTypeDescriptor = mapClassifierReference(oldTypeDescriptor)
513+
if (newTypeDescriptor == oldTypeDescriptor)
514+
expression.typeOperandClassifier
515+
else
516+
createUnboundClassifierSymbol(newTypeDescriptor)
517+
}
510518
)
511519

512520
override fun visitWhen(expression: IrWhen): IrWhen =

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
437437
expression.type,
438438
expression.operator,
439439
expression.typeOperand,
440-
expression.argument.transform()
440+
expression.argument.transform(),
441+
symbolRemapper.getReferencedClassifier(expression.typeOperandClassifier)
441442
)
442443

443444
override fun visitWhen(expression: IrWhen): IrWhen =

0 commit comments

Comments
 (0)