[IR] Pass class Type Parameters into IrConstructorCall factory explicitly

to avoid unexpected crash on uninitialized parent in psi2ir phase
This commit is contained in:
Roman Artemev
2019-10-22 17:28:57 +03:00
committed by romanart
parent ba373c67d7
commit b391c066d6
11 changed files with 38 additions and 29 deletions
@@ -283,6 +283,7 @@ open class DefaultParameterInjector(
expression.endOffset, expression.endOffset,
expression.type, expression.type,
it as IrConstructorSymbol, it as IrConstructorSymbol,
it.owner.parentAsClass.typeParameters.size,
DEFAULT_DISPATCH_CALL DEFAULT_DISPATCH_CALL
) )
} }
@@ -128,8 +128,9 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : FileLowe
if (!parent.isInner) return expression if (!parent.isInner) return expression
val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner) val newCallee = context.declarationFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner)
val classTypeParametersCount = expression.typeArgumentsCount - expression.constructorTypeArgumentsCount
val newCall = IrConstructorCallImpl.fromSymbolOwner( val newCall = IrConstructorCallImpl.fromSymbolOwner(
expression.startOffset, expression.endOffset, expression.type, newCallee.symbol, expression.origin expression.startOffset, expression.endOffset, expression.type, newCallee.symbol, classTypeParametersCount, expression.origin
) )
newCall.copyTypeArgumentsFrom(expression) newCall.copyTypeArgumentsFrom(expression)
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.constructedClass import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -450,6 +451,7 @@ class LocalDeclarationsLowering(
oldCall.startOffset, oldCall.endOffset, oldCall.startOffset, oldCall.endOffset,
newCallee.returnType, newCallee.returnType,
newCallee.symbol, newCallee.symbol,
newCallee.parentAsClass.typeParameters.size,
oldCall.origin oldCall.origin
).also { ).also {
it.copyTypeArgumentsFrom(oldCall) it.copyTypeArgumentsFrom(oldCall)
@@ -202,9 +202,10 @@ class FunctionInlining(val context: CommonBackendContext) : IrElementTransformer
val valueParameters = expression.getArgumentsWithIr().drop(1) // Skip dispatch receiver. val valueParameters = expression.getArgumentsWithIr().drop(1) // Skip dispatch receiver.
val immediateCall = with(expression) { val immediateCall = with(expression) {
if (function is IrConstructor) if (function is IrConstructor) {
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, function.returnType, function.symbol) val classTypeParametersCount = function.parentAsClass.typeParameters.size
else IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, function.returnType, function.symbol, classTypeParametersCount)
} else
IrCallImpl(startOffset, endOffset, function.returnType, functionArgument.symbol) IrCallImpl(startOffset, endOffset, function.returnType, functionArgument.symbol)
}.apply { }.apply {
functionParameters.forEach { functionParameters.forEach {
@@ -79,7 +79,8 @@ private class VarargTransformer(
startOffset, startOffset,
endOffset, endOffset,
arrayInlineClass.defaultType, arrayInlineClass.defaultType,
arrayInlineClass.constructors.single { it.isPrimary }.symbol arrayInlineClass.constructors.single { it.isPrimary }.symbol,
arrayInlineClass.typeParameters.size
).also { ).also {
it.putValueArgument(0, array) it.putValueArgument(0, array)
} }
@@ -141,7 +141,7 @@ private class AdditionalClassAnnotationLowering(private val context: JvmBackendC
irClass.annotations.add( irClass.annotations.add(
IrConstructorCallImpl.fromSymbolOwner( IrConstructorCallImpl.fromSymbolOwner(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, documentedConstructor.returnType, documentedConstructor.symbol UNDEFINED_OFFSET, UNDEFINED_OFFSET, documentedConstructor.returnType, documentedConstructor.symbol, 0
) )
) )
} }
@@ -162,7 +162,7 @@ private class AdditionalClassAnnotationLowering(private val context: JvmBackendC
irClass.annotations.add( irClass.annotations.add(
IrConstructorCallImpl.fromSymbolOwner( IrConstructorCallImpl.fromSymbolOwner(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, retentionConstructor.returnType, retentionConstructor.symbol UNDEFINED_OFFSET, UNDEFINED_OFFSET, retentionConstructor.returnType, retentionConstructor.symbol, 0
).apply { ).apply {
putValueArgument( putValueArgument(
0, 0,
@@ -225,7 +225,7 @@ private class AdditionalClassAnnotationLowering(private val context: JvmBackendC
irClass.annotations.add( irClass.annotations.add(
IrConstructorCallImpl.fromSymbolOwner( IrConstructorCallImpl.fromSymbolOwner(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetConstructor.returnType, targetConstructor.symbol UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetConstructor.returnType, targetConstructor.symbol, 0
).apply { ).apply {
putValueArgument(0, vararg) putValueArgument(0, vararg)
} }
@@ -12,13 +12,13 @@ import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.irCallConstructor
import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irTemporary import org.jetbrains.kotlin.ir.builders.irTemporary
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.util.transform import org.jetbrains.kotlin.ir.util.transform
@@ -105,9 +105,13 @@ private class AnonymousObjectSuperConstructorLowering(val context: JvmBackendCon
} }
} }
val classTypeParametersCount = objectConstructorCall.typeArgumentsCount - objectConstructorCall.symbol.owner.typeParameters.size
context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run { context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run {
expression.statements[expression.statements.size - 1] = irBlock(objectConstructorCall) { expression.statements[expression.statements.size - 1] = irBlock(objectConstructorCall) {
+irCallConstructor(objectConstructor.symbol, listOf()).apply { +IrConstructorCallImpl.fromSymbolOwner(
objectConstructorCall.startOffset, objectConstructorCall.endOffset, objectConstructorCall.type,
objectConstructorCall.symbol, classTypeParametersCount, objectConstructorCall.origin
).apply {
for (i in 0 until objectConstructorCall.valueArgumentsCount) for (i in 0 until objectConstructorCall.valueArgumentsCount)
putValueArgument(i, objectConstructorCall.getValueArgument(i)) putValueArgument(i, objectConstructorCall.getValueArgument(i))
// Avoid complex expressions between `new` and `<init>`, as the inliner gets confused if // Avoid complex expressions between `new` and `<init>`, as the inliner gets confused if
@@ -248,7 +248,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val irType = constructorDescriptor.returnType.toIrType() val irType = constructorDescriptor.returnType.toIrType()
val originalSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original) val originalSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original)
IrConstructorCallImpl.fromSubstitutedDescriptor( IrConstructorCallImpl.fromSymbolDescriptor(
startOffset, endOffset, startOffset, endOffset,
irType, irType,
originalSymbol, originalSymbol,
@@ -232,7 +232,8 @@ fun IrBuilderWithScope.irCallConstructor(callee: IrConstructorSymbol, typeArgume
startOffset, startOffset,
endOffset, endOffset,
callee.owner.returnType, callee.owner.returnType,
callee callee,
typeArguments.size - callee.owner.typeParameters.size
).apply { ).apply {
typeArguments.forEachIndexed { index, irType -> typeArguments.forEachIndexed { index, irType ->
this.putTypeArgument(index, irType) this.putTypeArgument(index, irType)
@@ -33,18 +33,18 @@ class IrConstructorCallImpl(
override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor
companion object { companion object {
fun fromSubstitutedDescriptor(
fun fromSymbolDescriptor(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
type: IrType, type: IrType,
constructorSymbol: IrConstructorSymbol, constructorSymbol: IrConstructorSymbol,
constructorDescriptor: ClassConstructorDescriptor,
origin: IrStatementOrigin? = null origin: IrStatementOrigin? = null
): IrConstructorCallImpl { ): IrConstructorCallImpl {
val constructorDescriptor = constructorSymbol.descriptor
val classTypeParametersCount = constructorDescriptor.constructedClass.original.declaredTypeParameters.size val classTypeParametersCount = constructorDescriptor.constructedClass.original.declaredTypeParameters.size
val totalTypeParametersCount = constructorDescriptor.typeParameters.size val totalTypeParametersCount = constructorDescriptor.typeParameters.size
val valueParametersCount = constructorDescriptor.valueParameters.size val valueParametersCount = constructorDescriptor.valueParameters.size
return IrConstructorCallImpl( return IrConstructorCallImpl(
startOffset, endOffset, startOffset, endOffset,
type, type,
@@ -56,25 +56,15 @@ class IrConstructorCallImpl(
) )
} }
fun fromSymbolDescriptor(
startOffset: Int,
endOffset: Int,
type: IrType,
constructorSymbol: IrConstructorSymbol,
origin: IrStatementOrigin? = null
): IrConstructorCallImpl =
fromSubstitutedDescriptor(startOffset, endOffset, type, constructorSymbol, constructorSymbol.descriptor, origin)
fun fromSymbolOwner( fun fromSymbolOwner(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
type: IrType, type: IrType,
constructorSymbol: IrConstructorSymbol, constructorSymbol: IrConstructorSymbol,
classTypeParametersCount: Int,
origin: IrStatementOrigin? = null origin: IrStatementOrigin? = null
): IrConstructorCallImpl { ): IrConstructorCallImpl {
val constructor = constructorSymbol.owner val constructor = constructorSymbol.owner
val constructedClass = constructor.parentAsClass
val classTypeParametersCount = constructedClass.typeParameters.size
val constructorTypeParametersCount = constructor.typeParameters.size val constructorTypeParametersCount = constructor.typeParameters.size
val totalTypeParametersCount = classTypeParametersCount + constructorTypeParametersCount val totalTypeParametersCount = classTypeParametersCount + constructorTypeParametersCount
val valueParametersCount = constructor.valueParameters.size val valueParametersCount = constructor.valueParameters.size
@@ -91,11 +81,19 @@ class IrConstructorCallImpl(
} }
fun fromSymbolOwner( fun fromSymbolOwner(
startOffset: Int,
endOffset: Int,
type: IrType, type: IrType,
constructorSymbol: IrConstructorSymbol, constructorSymbol: IrConstructorSymbol,
origin: IrStatementOrigin? = null origin: IrStatementOrigin? = null
) = ): IrConstructorCallImpl {
fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, constructorSymbol, origin) val constructedClass = constructorSymbol.owner.parentAsClass
val classTypeParametersCount = constructedClass.typeParameters.size
return fromSymbolOwner(startOffset, endOffset, type, constructorSymbol, classTypeParametersCount, origin)
}
fun fromSymbolOwner(type: IrType, constructorSymbol: IrConstructorSymbol, origin: IrStatementOrigin? = null) =
fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, constructorSymbol, constructorSymbol.owner.parentAsClass.typeParameters.size, origin)
} }
} }
@@ -65,7 +65,7 @@ class SerializableCompanionIrGenerator(
val annotationType = compilerContext.externalSymbols.referenceClass(annotationMarkerClass).owner.defaultType val annotationType = compilerContext.externalSymbols.referenceClass(annotationMarkerClass).owner.defaultType
val irSerializableClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor).owner val irSerializableClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor).owner
val annotationCtorCall = IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, annotationType, annotationCtor).apply { val annotationCtorCall = IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, annotationType, annotationCtor, annotationMarkerClass.declaredTypeParameters.size).apply {
val serializerType = serializer.toSimpleType(false) val serializerType = serializer.toSimpleType(false)
putValueArgument( putValueArgument(
0, 0,