Fix type of super

This commit is contained in:
Steven Schäfer
2019-04-30 14:01:17 +02:00
committed by max-kammerer
parent 209a5d8464
commit f5a78213b2
6 changed files with 43 additions and 38 deletions
@@ -16,21 +16,19 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Opcodes
object Clone : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature.newReturnType(AsmTypes.OBJECT_TYPE), context) {
val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
}
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo) = with(codegen) {
val result = expression.dispatchReceiver!!.accept(this, data).materialized
assert(!AsmUtil.isPrimitive(result.type)) { "clone() of primitive type" }
val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
mv.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
MaterialValue(codegen.mv, AsmTypes.OBJECT_TYPE)
}
}
@@ -136,7 +136,8 @@ private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverVal
val expressionReceiver = receiver as? ExpressionReceiver
?: throw AssertionError("'this' or 'super' receiver should be an expression receiver")
val ktReceiver = expressionReceiver.expression
return generateThisReceiver(ktReceiver.startOffsetSkippingComments, ktReceiver.endOffset, expressionReceiver.type, classDescriptor)
val type = if (receiver is SuperCallReceiverValue) receiver.thisType else expressionReceiver.type
return generateThisReceiver(ktReceiver.startOffsetSkippingComments, ktReceiver.endOffset, type, classDescriptor)
}
fun StatementGenerator.generateBackingFieldReceiver(
@@ -62,9 +62,9 @@ FILE fqName:<root> fileName:/qualifiedSuperCalls.kt
$this: VALUE_PARAMETER name:<this> type:<root>.CBoth
BLOCK_BODY
CALL 'public open fun foo (): kotlin.Unit declared in <root>.ILeft' superQualifier='CLASS INTERFACE name:ILeft modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.foo' type=<root>.ILeft origin=null
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.foo' type=<root>.CBoth origin=null
CALL 'public open fun foo (): kotlin.Unit declared in <root>.IRight' superQualifier='CLASS INTERFACE name:IRight modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.foo' type=<root>.IRight origin=null
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.foo' type=<root>.CBoth origin=null
PROPERTY name:bar visibility:public modality:OPEN [val]
FUN name:<get-bar> visibility:public modality:OPEN <> ($this:<root>.CBoth) returnType:kotlin.Int
correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [val]
@@ -76,9 +76,9 @@ FILE fqName:<root> fileName:/qualifiedSuperCalls.kt
RETURN type=kotlin.Nothing from='public open fun <get-bar> (): kotlin.Int declared in <root>.CBoth'
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=PLUS
$this: CALL 'public open fun <get-bar> (): kotlin.Int declared in <root>.ILeft' superQualifier='CLASS INTERFACE name:ILeft modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.<get-bar>' type=<root>.ILeft origin=null
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.<get-bar>' type=<root>.CBoth origin=null
other: CALL 'public open fun <get-bar> (): kotlin.Int declared in <root>.IRight' superQualifier='CLASS INTERFACE name:IRight modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.<get-bar>' type=<root>.IRight origin=null
$this: GET_VAR '<this>: <root>.CBoth declared in <root>.CBoth.<get-bar>' type=<root>.CBoth origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in <root>.ILeft
+13 -13
View File
@@ -19,15 +19,16 @@ FILE fqName:<root> fileName:/superCalls.kt
RETURN type=kotlin.Nothing from='public open fun <get-bar> (): kotlin.String declared in <root>.Base'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:bar type:kotlin.String visibility:public [final] ' type=kotlin.String origin=null
receiver: GET_VAR '<this>: <root>.Base declared in <root>.Base.<get-bar>' type=<root>.Base origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
FUN name:hashCode visibility:public modality:OPEN <> ($this:<root>.Base) returnType:kotlin.Int
$this: VALUE_PARAMETER name:<this> type:<root>.Base
BLOCK_BODY
RETURN type=kotlin.Nothing from='public open fun hashCode (): kotlin.Int declared in <root>.Base'
CALL 'public open fun hashCode (): kotlin.Int declared in kotlin.Any' type=kotlin.Int origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
@@ -49,17 +50,16 @@ FILE fqName:<root> fileName:/superCalls.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-bar> (): kotlin.String declared in <root>.Derived'
CALL 'public open fun <get-bar> (): kotlin.String declared in <root>.Base' type=kotlin.String origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:<root>.Base) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in <root>.Base
$this: VALUE_PARAMETER name:<this> type:<root>.Base
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
+2
View File
@@ -2,6 +2,8 @@ open class Base {
open fun foo() {}
open val bar: String = ""
override fun hashCode() = super.hashCode()
}
class Derived : Base() {
+14 -10
View File
@@ -19,15 +19,19 @@ FILE fqName:<root> fileName:/superCalls.kt
RETURN type=kotlin.Nothing from='public open fun <get-bar> (): kotlin.String declared in <root>.Base'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:bar type:kotlin.String visibility:public [final] ' type=kotlin.String origin=null
receiver: GET_VAR '<this>: <root>.Base declared in <root>.Base.<get-bar>' type=<root>.Base origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
FUN name:hashCode visibility:public modality:OPEN <> ($this:<root>.Base) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:<root>.Base
BLOCK_BODY
RETURN type=kotlin.Nothing from='public open fun hashCode (): kotlin.Int declared in <root>.Base'
CALL 'public open fun hashCode (): kotlin.Int declared in kotlin.Any' superQualifier='CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public superTypes:[]' type=kotlin.Int origin=null
$this: GET_VAR '<this>: <root>.Base declared in <root>.Base.hashCode' type=<root>.Base origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
@@ -44,7 +48,7 @@ FILE fqName:<root> fileName:/superCalls.kt
$this: VALUE_PARAMETER name:<this> type:<root>.Derived
BLOCK_BODY
CALL 'public open fun foo (): kotlin.Unit declared in <root>.Base' superQualifier='CLASS CLASS name:Base modality:OPEN visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit origin=null
$this: GET_VAR '<this>: <root>.Derived declared in <root>.Derived.foo' type=<root>.Base origin=null
$this: GET_VAR '<this>: <root>.Derived declared in <root>.Derived.foo' type=<root>.Derived origin=null
PROPERTY name:bar visibility:public modality:OPEN [val]
FUN name:<get-bar> visibility:public modality:OPEN <> ($this:<root>.Derived) returnType:kotlin.String
correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [val]
@@ -54,16 +58,16 @@ FILE fqName:<root> fileName:/superCalls.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public open fun <get-bar> (): kotlin.String declared in <root>.Derived'
CALL 'public open fun <get-bar> (): kotlin.String declared in <root>.Base' superQualifier='CLASS CLASS name:Base modality:OPEN visibility:public superTypes:[kotlin.Any]' type=kotlin.String origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.Derived declared in <root>.Derived.<get-bar>' type=<root>.Base origin=null
$this: GET_VAR '<this>: <root>.Derived declared in <root>.Derived.<get-bar>' type=<root>.Derived origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in <root>.Base
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:<root>.Base) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in <root>.Base
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
$this: VALUE_PARAMETER name:<this> type:<root>.Base
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in <root>.Base