Minor: reformat code

This commit is contained in:
Dmitry Petrov
2018-02-07 14:45:57 +03:00
parent b1419e2a8c
commit e23a48e8d0
3 changed files with 194 additions and 188 deletions
@@ -13,20 +13,20 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
abstract class NumberLikeCompare( abstract class NumberLikeCompare(
left: StackValue, left: StackValue,
right: StackValue, right: StackValue,
operandType: Type, operandType: Type,
private val opToken: IElementType private val opToken: IElementType
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) { ) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int = override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
NumberCompare.patchOpcode(opcode, v, opToken, operandType) NumberCompare.patchOpcode(opcode, v, opToken, operandType)
} }
abstract class SafeCallFusedWithPrimitiveEqualityBase( abstract class SafeCallFusedWithPrimitiveEqualityBase(
opToken: IElementType, opToken: IElementType,
operandType: Type, operandType: Type,
left: StackValue, left: StackValue,
right: StackValue right: StackValue
) : NumberLikeCompare(left, right, operandType, opToken) { ) : NumberLikeCompare(left, right, operandType, opToken) {
private val trueIfEqual = opToken == KtTokens.EQEQ || opToken == KtTokens.EQEQEQ private val trueIfEqual = opToken == KtTokens.EQEQ || opToken == KtTokens.EQEQEQ
@@ -80,12 +80,12 @@ abstract class SafeCallFusedWithPrimitiveEqualityBase(
class SafeCallToPrimitiveEquality( class SafeCallToPrimitiveEquality(
opToken: IElementType, opToken: IElementType,
operandType: Type, operandType: Type,
left: StackValue, left: StackValue,
right: StackValue, right: StackValue,
private val safeReceiverType: Type, private val safeReceiverType: Type,
private val safeReceiverIsNull: Label private val safeReceiverIsNull: Label
) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) { ) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) {
override fun cleanupOnNullReceiver(v: InstructionAdapter) { override fun cleanupOnNullReceiver(v: InstructionAdapter) {
v.mark(safeReceiverIsNull) v.mark(safeReceiverIsNull)
@@ -95,12 +95,12 @@ class SafeCallToPrimitiveEquality(
class PrimitiveToSafeCallEquality( class PrimitiveToSafeCallEquality(
opToken: IElementType, opToken: IElementType,
operandType: Type, operandType: Type,
left: StackValue, left: StackValue,
right: StackValue, right: StackValue,
private val safeReceiverType: Type, private val safeReceiverType: Type,
private val safeReceiverIsNull: Label private val safeReceiverIsNull: Label
) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) { ) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) {
override fun cleanupOnNullReceiver(v: InstructionAdapter) { override fun cleanupOnNullReceiver(v: InstructionAdapter) {
v.mark(safeReceiverIsNull) v.mark(safeReceiverIsNull)
@@ -111,10 +111,10 @@ class PrimitiveToSafeCallEquality(
class BoxedToPrimitiveEquality private constructor( class BoxedToPrimitiveEquality private constructor(
leftBoxed: StackValue, leftBoxed: StackValue,
rightPrimitive: StackValue, rightPrimitive: StackValue,
primitiveType: Type, primitiveType: Type,
private val frameMap: FrameMap private val frameMap: FrameMap
) : NumberLikeCompare(leftBoxed, rightPrimitive, primitiveType, KtTokens.EQEQ) { ) : NumberLikeCompare(leftBoxed, rightPrimitive, primitiveType, KtTokens.EQEQ) {
private val boxedType = arg1.type private val boxedType = arg1.type
@@ -122,31 +122,30 @@ class BoxedToPrimitiveEquality private constructor(
if (arg2!!.canHaveSideEffects()) { if (arg2!!.canHaveSideEffects()) {
val tmp = frameMap.enterTemp(operandType) val tmp = frameMap.enterTemp(operandType)
doJump( doJump(
v, jumpLabel, jumpIfFalse, v, jumpLabel, jumpIfFalse,
{ {
arg1.put(boxedType, v) arg1.put(boxedType, v)
arg2.put(operandType, v) arg2.put(operandType, v)
v.store(tmp, operandType) v.store(tmp, operandType)
}, },
{ v.load(tmp, operandType) } { v.load(tmp, operandType) }
) )
frameMap.leaveTemp(operandType) frameMap.leaveTemp(operandType)
} } else {
else {
doJump( doJump(
v, jumpLabel, jumpIfFalse, v, jumpLabel, jumpIfFalse,
{ arg1.put(boxedType, v) }, { arg1.put(boxedType, v) },
{ arg2.put(operandType, v) } { arg2.put(operandType, v) }
) )
} }
} }
private inline fun doJump( private inline fun doJump(
v: InstructionAdapter, v: InstructionAdapter,
jumpLabel: Label, jumpLabel: Label,
jumpIfFalse: Boolean, jumpIfFalse: Boolean,
putArg1: () -> Unit, putArg1: () -> Unit,
putArg2: () -> Unit putArg2: () -> Unit
) { ) {
val notNullLabel = Label() val notNullLabel = Label()
val endLabel = Label() val endLabel = Label()
@@ -169,34 +168,34 @@ class BoxedToPrimitiveEquality private constructor(
companion object { companion object {
@JvmStatic @JvmStatic
fun create( fun create(
opToken: IElementType, opToken: IElementType,
left: StackValue, left: StackValue,
leftType: Type, leftType: Type,
right: StackValue, right: StackValue,
rightType: Type, rightType: Type,
frameMap: FrameMap frameMap: FrameMap
): BranchedValue = ): BranchedValue =
if (!isApplicable(opToken, leftType, rightType)) if (!isApplicable(opToken, leftType, rightType))
throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType") throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType")
else when (opToken) { else when (opToken) {
KtTokens.EQEQ -> BoxedToPrimitiveEquality(left, right, rightType, frameMap) KtTokens.EQEQ -> BoxedToPrimitiveEquality(left, right, rightType, frameMap)
KtTokens.EXCLEQ -> Invert(BoxedToPrimitiveEquality(left, right, rightType, frameMap)) KtTokens.EXCLEQ -> Invert(BoxedToPrimitiveEquality(left, right, rightType, frameMap))
else -> throw AssertionError("Unexpected opToken: $opToken") else -> throw AssertionError("Unexpected opToken: $opToken")
} }
@JvmStatic @JvmStatic
fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) = fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) =
(opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) && (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) &&
AsmUtil.isIntOrLongPrimitive(rightType) && AsmUtil.isIntOrLongPrimitive(rightType) &&
AsmUtil.isBoxedTypeOf(leftType, rightType) AsmUtil.isBoxedTypeOf(leftType, rightType)
} }
} }
abstract class PrimitiveToSomethingEquality abstract class PrimitiveToSomethingEquality
protected constructor( protected constructor(
leftPrimitive: StackValue, leftPrimitive: StackValue,
right: StackValue, right: StackValue,
primitiveType: Type primitiveType: Type
) : NumberLikeCompare(leftPrimitive, right, primitiveType, KtTokens.EQEQ) { ) : NumberLikeCompare(leftPrimitive, right, primitiveType, KtTokens.EQEQ) {
protected val primitiveType = leftPrimitive.type protected val primitiveType = leftPrimitive.type
protected val rightType = right.type protected val rightType = right.type
@@ -227,9 +226,9 @@ protected constructor(
class PrimitiveToBoxedEquality private constructor( class PrimitiveToBoxedEquality private constructor(
leftPrimitive: StackValue, leftPrimitive: StackValue,
rightBoxed: StackValue, rightBoxed: StackValue,
primitiveType: Type primitiveType: Type
) : PrimitiveToSomethingEquality(leftPrimitive, rightBoxed, primitiveType) { ) : PrimitiveToSomethingEquality(leftPrimitive, rightBoxed, primitiveType) {
private val boxedType = rightBoxed.type private val boxedType = rightBoxed.type
@@ -244,27 +243,27 @@ class PrimitiveToBoxedEquality private constructor(
companion object { companion object {
@JvmStatic @JvmStatic
fun create(opToken: IElementType, left: StackValue, leftType: Type, right: StackValue, rightType: Type): BranchedValue = fun create(opToken: IElementType, left: StackValue, leftType: Type, right: StackValue, rightType: Type): BranchedValue =
if (!isApplicable(opToken, leftType, rightType)) if (!isApplicable(opToken, leftType, rightType))
throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType") throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType")
else when (opToken) { else when (opToken) {
KtTokens.EQEQ -> PrimitiveToBoxedEquality(left, right, leftType) KtTokens.EQEQ -> PrimitiveToBoxedEquality(left, right, leftType)
KtTokens.EXCLEQ -> Invert(PrimitiveToBoxedEquality(left, right, leftType)) KtTokens.EXCLEQ -> Invert(PrimitiveToBoxedEquality(left, right, leftType))
else -> throw AssertionError("Unexpected opToken: $opToken") else -> throw AssertionError("Unexpected opToken: $opToken")
} }
@JvmStatic @JvmStatic
fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) = fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) =
(opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) && (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) &&
AsmUtil.isIntOrLongPrimitive(leftType) && AsmUtil.isIntOrLongPrimitive(leftType) &&
AsmUtil.isBoxedTypeOf(rightType, leftType) AsmUtil.isBoxedTypeOf(rightType, leftType)
} }
} }
class PrimitiveToObjectEquality private constructor( class PrimitiveToObjectEquality private constructor(
leftPrimitive: StackValue, leftPrimitive: StackValue,
rightObject: StackValue, rightObject: StackValue,
primitiveType: Type primitiveType: Type
) : PrimitiveToSomethingEquality(leftPrimitive, rightObject, primitiveType) { ) : PrimitiveToSomethingEquality(leftPrimitive, rightObject, primitiveType) {
private val boxedType = AsmUtil.boxType(primitiveType) private val boxedType = AsmUtil.boxType(primitiveType)
@@ -281,18 +280,18 @@ class PrimitiveToObjectEquality private constructor(
companion object { companion object {
@JvmStatic @JvmStatic
fun create(opToken: IElementType, left: StackValue, leftType: Type, right: StackValue, rightType: Type): BranchedValue = fun create(opToken: IElementType, left: StackValue, leftType: Type, right: StackValue, rightType: Type): BranchedValue =
if (!isApplicable(opToken, leftType, rightType)) if (!isApplicable(opToken, leftType, rightType))
throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType") throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType")
else when (opToken) { else when (opToken) {
KtTokens.EQEQ -> PrimitiveToObjectEquality(left, right, leftType) KtTokens.EQEQ -> PrimitiveToObjectEquality(left, right, leftType)
KtTokens.EXCLEQ -> Invert(PrimitiveToObjectEquality(left, right, leftType)) KtTokens.EXCLEQ -> Invert(PrimitiveToObjectEquality(left, right, leftType))
else -> throw AssertionError("Unexpected opToken: $opToken") else -> throw AssertionError("Unexpected opToken: $opToken")
} }
@JvmStatic @JvmStatic
fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) = fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) =
(opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) && (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) &&
AsmUtil.isIntOrLongPrimitive(leftType) && AsmUtil.isIntOrLongPrimitive(leftType) &&
rightType.sort == Type.OBJECT rightType.sort == Type.OBJECT
} }
} }
@@ -16,10 +16,10 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
open class BranchedValue( open class BranchedValue(
val arg1: StackValue, val arg1: StackValue,
val arg2: StackValue? = null, val arg2: StackValue? = null,
val operandType: Type, val operandType: Type,
val opcode: Int val opcode: Int
) : StackValue(Type.BOOLEAN_TYPE) { ) : StackValue(Type.BOOLEAN_TYPE) {
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) { override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
@@ -59,8 +59,7 @@ open class BranchedValue(
override fun loopJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun loopJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
if (!jumpIfFalse) { if (!jumpIfFalse) {
v.fakeAlwaysTrueIfeq(jumpLabel) v.fakeAlwaysTrueIfeq(jumpLabel)
} } else {
else {
v.fakeAlwaysFalseIfeq(jumpLabel) v.fakeAlwaysFalseIfeq(jumpLabel)
} }
} }
@@ -81,8 +80,7 @@ open class BranchedValue(
override fun loopJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun loopJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
if (jumpIfFalse) { if (jumpIfFalse) {
v.fakeAlwaysTrueIfeq(jumpLabel) v.fakeAlwaysTrueIfeq(jumpLabel)
} } else {
else {
v.fakeAlwaysFalseIfeq(jumpLabel) v.fakeAlwaysFalseIfeq(jumpLabel)
} }
} }
@@ -121,23 +119,23 @@ open class BranchedValue(
} }
fun condJump(condition: StackValue): CondJump = fun condJump(condition: StackValue): CondJump =
CondJump( CondJump(
condition as? BranchedValue ?: BranchedValue(condition, null, Type.BOOLEAN_TYPE, IFEQ), condition as? BranchedValue ?: BranchedValue(condition, null, Type.BOOLEAN_TYPE, IFEQ),
IFEQ IFEQ
) )
fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue = fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
if (operandType.sort == Type.OBJECT) if (operandType.sort == Type.OBJECT)
ObjectCompare(opToken, operandType, left, right) ObjectCompare(opToken, operandType, left, right)
else else
NumberCompare(opToken, operandType, left, right) NumberCompare(opToken, operandType, left, right)
} }
} }
class And( class And(
arg1: StackValue, arg1: StackValue,
arg2: StackValue arg2: StackValue
) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) { ) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
@@ -149,8 +147,8 @@ class And(
} }
class Or( class Or(
arg1: StackValue, arg1: StackValue,
arg2: StackValue arg2: StackValue
) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) { ) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
@@ -184,14 +182,14 @@ class CondJump(val condition: BranchedValue, op: Int) : BranchedValue(condition,
} }
class NumberCompare( class NumberCompare(
private val opToken: IElementType, private val opToken: IElementType,
operandType: Type, operandType: Type,
left: StackValue, left: StackValue,
right: StackValue right: StackValue
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) { ) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int = override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
patchOpcode(opcode, v, opToken, operandType) patchOpcode(opcode, v, opToken, operandType)
companion object { companion object {
fun getNumberCompareOpcode(opToken: IElementType): Int = when (opToken) { fun getNumberCompareOpcode(opToken: IElementType): Int = when (opToken) {
@@ -230,10 +228,10 @@ class NumberCompare(
} }
class ObjectCompare( class ObjectCompare(
opToken: IElementType, opToken: IElementType,
operandType: Type, operandType: Type,
left: StackValue, left: StackValue,
right: StackValue right: StackValue
) : BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) { ) : BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) {
companion object { companion object {
@@ -57,9 +57,9 @@ import org.jetbrains.org.objectweb.asm.commons.Method
import java.util.* import java.util.*
fun generateIsCheck( fun generateIsCheck(
v: InstructionAdapter, v: InstructionAdapter,
kotlinType: KotlinType, kotlinType: KotlinType,
asmType: Type asmType: Type
) { ) {
if (TypeUtils.isNullableType(kotlinType)) { if (TypeUtils.isNullableType(kotlinType)) {
val nope = Label() val nope = Label()
@@ -80,24 +80,22 @@ fun generateIsCheck(
mark(end) mark(end)
} }
} } else {
else {
TypeIntrinsics.instanceOf(v, kotlinType, asmType) TypeIntrinsics.instanceOf(v, kotlinType, asmType)
} }
} }
fun generateAsCast( fun generateAsCast(
v: InstructionAdapter, v: InstructionAdapter,
kotlinType: KotlinType, kotlinType: KotlinType,
asmType: Type, asmType: Type,
isSafe: Boolean isSafe: Boolean
) { ) {
if (!isSafe) { if (!isSafe) {
if (!TypeUtils.isNullableType(kotlinType)) { if (!TypeUtils.isNullableType(kotlinType)) {
generateNullCheckForNonSafeAs(v, kotlinType) generateNullCheckForNonSafeAs(v, kotlinType)
} }
} } else {
else {
with(v) { with(v) {
dup() dup()
TypeIntrinsics.instanceOf(v, kotlinType, asmType) TypeIntrinsics.instanceOf(v, kotlinType, asmType)
@@ -113,22 +111,30 @@ fun generateAsCast(
} }
private fun generateNullCheckForNonSafeAs( private fun generateNullCheckForNonSafeAs(
v: InstructionAdapter, v: InstructionAdapter,
type: KotlinType type: KotlinType
) { ) {
with(v) { with(v) {
dup() dup()
val nonnull = Label() val nonnull = Label()
ifnonnull(nonnull) ifnonnull(nonnull)
AsmUtil.genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)) AsmUtil.genThrow(
v,
"kotlin/TypeCastException",
"null cannot be cast to non-null type " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type)
)
mark(nonnull) mark(nonnull)
} }
} }
fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String? fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String? =
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") } valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }
fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) { fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(
companion: KtObjectDeclaration,
outerContext: FieldOwnerContext<*>,
state: GenerationState
) {
val descriptor = state.bindingContext.get(BindingContext.CLASS, companion) val descriptor = state.bindingContext.get(BindingContext.CLASS, companion)
if (descriptor == null || ErrorUtils.isError(descriptor)) { if (descriptor == null || ErrorUtils.isError(descriptor)) {
@@ -150,16 +156,20 @@ fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObject
} }
// TODO: inline and remove then ScriptCodegen is converted to Kotlin // TODO: inline and remove then ScriptCodegen is converted to Kotlin
fun mapSupertypesNames(typeMapper: KotlinTypeMapper, supertypes: List<ClassDescriptor>, signatureVisitor: JvmSignatureWriter?): Array<String> = fun mapSupertypesNames(
supertypes.map { typeMapper.mapSupertype(it.defaultType, signatureVisitor).internalName }.toTypedArray() typeMapper: KotlinTypeMapper,
supertypes: List<ClassDescriptor>,
signatureVisitor: JvmSignatureWriter?
): Array<String> =
supertypes.map { typeMapper.mapSupertype(it.defaultType, signatureVisitor).internalName }.toTypedArray()
// Top level subclasses of a sealed class should be generated before that sealed class, // Top level subclasses of a sealed class should be generated before that sealed class,
// so that we'd generate the necessary accessor for its constructor afterwards // so that we'd generate the necessary accessor for its constructor afterwards
fun sortTopLevelClassesAndPrepareContextForSealedClasses( fun sortTopLevelClassesAndPrepareContextForSealedClasses(
classOrObjects: List<KtClassOrObject>, classOrObjects: List<KtClassOrObject>,
packagePartContext: PackageContext, packagePartContext: PackageContext,
state: GenerationState state: GenerationState
): List<KtClassOrObject> { ): List<KtClassOrObject> {
fun prepareContextIfNeeded(descriptor: ClassDescriptor?) { fun prepareContextIfNeeded(descriptor: ClassDescriptor?) {
if (DescriptorUtils.isSealedClass(descriptor)) { if (DescriptorUtils.isSealedClass(descriptor)) {
@@ -183,8 +193,7 @@ fun sortTopLevelClassesAndPrepareContextForSealedClasses(
val descriptor = state.bindingContext.get(BindingContext.CLASS, classOrObject) val descriptor = state.bindingContext.get(BindingContext.CLASS, classOrObject)
if (descriptor == null) { if (descriptor == null) {
result.add(classOrObject) result.add(classOrObject)
} } else {
else {
prepareContextIfNeeded(descriptor) prepareContextIfNeeded(descriptor)
descriptorToPsi[descriptor] = classOrObject descriptorToPsi[descriptor] = classOrObject
} }
@@ -199,17 +208,17 @@ fun sortTopLevelClassesAndPrepareContextForSealedClasses(
} }
fun CallableMemberDescriptor.isDefinitelyNotDefaultImplsMethod() = fun CallableMemberDescriptor.isDefinitelyNotDefaultImplsMethod() =
this is JavaCallableMemberDescriptor || this.annotations.hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME) this is JavaCallableMemberDescriptor || this.annotations.hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME)
fun ClassBuilder.generateMethod( fun ClassBuilder.generateMethod(
debugString: String, debugString: String,
access: Int, access: Int,
method: Method, method: Method,
element: PsiElement?, element: PsiElement?,
origin: JvmDeclarationOrigin, origin: JvmDeclarationOrigin,
state: GenerationState, state: GenerationState,
generate: InstructionAdapter.() -> Unit generate: InstructionAdapter.() -> Unit
) { ) {
val mv = this.newMethod(origin, access, method.name, method.descriptor, null, null) val mv = this.newMethod(origin, access, method.name, method.descriptor, null, null)
@@ -224,44 +233,44 @@ fun ClassBuilder.generateMethod(
fun reportTarget6InheritanceErrorIfNeeded( fun reportTarget6InheritanceErrorIfNeeded(
classDescriptor: ClassDescriptor, classElement: PsiElement, restrictedInheritance: List<FunctionDescriptor>, state:GenerationState classDescriptor: ClassDescriptor, classElement: PsiElement, restrictedInheritance: List<FunctionDescriptor>, state: GenerationState
) { ) {
if (!restrictedInheritance.isEmpty()) { if (!restrictedInheritance.isEmpty()) {
val groupBy = restrictedInheritance.groupBy { descriptor -> descriptor.containingDeclaration as ClassDescriptor } val groupBy = restrictedInheritance.groupBy { descriptor -> descriptor.containingDeclaration as ClassDescriptor }
for ((key, value) in groupBy) { for ((key, value) in groupBy) {
state.diagnostics.report( state.diagnostics.report(
ErrorsJvm.TARGET6_INTERFACE_INHERITANCE.on( ErrorsJvm.TARGET6_INTERFACE_INHERITANCE.on(
classElement, classDescriptor, key, classElement, classDescriptor, key,
value.joinToString(separator = "\n", prefix = "\n") { value.joinToString(separator = "\n", prefix = "\n") {
Renderers.COMPACT.render(JvmCodegenUtil.getDirectMember(it), RenderingContext.Empty) Renderers.COMPACT.render(JvmCodegenUtil.getDirectMember(it), RenderingContext.Empty)
} }
) )
) )
} }
} }
} }
fun CallableDescriptor.isJvmStaticInObjectOrClassOrInterface(): Boolean = fun CallableDescriptor.isJvmStaticInObjectOrClassOrInterface(): Boolean =
isJvmStaticIn { isJvmStaticIn {
DescriptorUtils.isNonCompanionObject(it) || DescriptorUtils.isNonCompanionObject(it) ||
// This is necessary because for generation of @JvmStatic methods from companion of class A // This is necessary because for generation of @JvmStatic methods from companion of class A
// we create a synthesized descriptor containing in class A // we create a synthesized descriptor containing in class A
DescriptorUtils.isClassOrEnumClass(it) || DescriptorUtils.isInterface(it) DescriptorUtils.isClassOrEnumClass(it) || DescriptorUtils.isInterface(it)
} }
fun CallableDescriptor.isJvmStaticInCompanionObject(): Boolean = fun CallableDescriptor.isJvmStaticInCompanionObject(): Boolean =
isJvmStaticIn { DescriptorUtils.isCompanionObject(it) } isJvmStaticIn { DescriptorUtils.isCompanionObject(it) }
private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor) -> Boolean): Boolean = private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor) -> Boolean): Boolean =
when (this) { when (this) {
is PropertyAccessorDescriptor -> { is PropertyAccessorDescriptor -> {
val propertyDescriptor = correspondingProperty val propertyDescriptor = correspondingProperty
predicate(propertyDescriptor.containingDeclaration) && predicate(propertyDescriptor.containingDeclaration) &&
(hasJvmStaticAnnotation() || propertyDescriptor.hasJvmStaticAnnotation()) (hasJvmStaticAnnotation() || propertyDescriptor.hasJvmStaticAnnotation())
}
else -> predicate(containingDeclaration) && hasJvmStaticAnnotation()
} }
else -> predicate(containingDeclaration) && hasJvmStaticAnnotation()
}
fun Collection<VariableDescriptor>.filterOutDescriptorsWithSpecialNames() = filterNot { it.name.isSpecial } fun Collection<VariableDescriptor>.filterOutDescriptorsWithSpecialNames() = filterNot { it.name.isSpecial }
@@ -271,10 +280,10 @@ class TypeAndNullability(@JvmField val type: Type, @JvmField val isNullable: Boo
class JvmKotlinType(val type: Type, val kotlinType: KotlinType?) class JvmKotlinType(val type: Type, val kotlinType: KotlinType?)
fun calcTypeForIEEE754ArithmeticIfNeeded( fun calcTypeForIEEE754ArithmeticIfNeeded(
expression: KtExpression?, expression: KtExpression?,
bindingContext: BindingContext, bindingContext: BindingContext,
descriptor: DeclarationDescriptor, descriptor: DeclarationDescriptor,
languageVersionSettings: LanguageVersionSettings languageVersionSettings: LanguageVersionSettings
): TypeAndNullability? { ): TypeAndNullability? {
val ktType = expression.kotlinType(bindingContext) ?: return null val ktType = expression.kotlinType(bindingContext) ?: return null
@@ -300,7 +309,7 @@ fun calcTypeForIEEE754ArithmeticIfNeeded(
fun KotlinType.asmType(typeMapper: KotlinTypeMapper) = typeMapper.mapType(this) fun KotlinType.asmType(typeMapper: KotlinTypeMapper) = typeMapper.mapType(this)
fun KtExpression?.asmType(typeMapper: KotlinTypeMapper, bindingContext: BindingContext): Type = fun KtExpression?.asmType(typeMapper: KotlinTypeMapper, bindingContext: BindingContext): Type =
this.kotlinType(bindingContext)?.asmType(typeMapper) ?: Type.VOID_TYPE this.kotlinType(bindingContext)?.asmType(typeMapper) ?: Type.VOID_TYPE
fun KtExpression?.kotlinType(bindingContext: BindingContext) = this?.let(bindingContext::getType) fun KtExpression?.kotlinType(bindingContext: BindingContext) = this?.let(bindingContext::getType)
@@ -322,7 +331,7 @@ fun FunctionDescriptor.isGenericToArray(): Boolean {
val elementType = typeParameters[0].defaultType val elementType = typeParameters[0].defaultType
return KotlinTypeChecker.DEFAULT.equalTypes(elementType, builtIns.getArrayElementType(returnType)) && return KotlinTypeChecker.DEFAULT.equalTypes(elementType, builtIns.getArrayElementType(returnType)) &&
KotlinTypeChecker.DEFAULT.equalTypes(elementType, builtIns.getArrayElementType(paramType)) KotlinTypeChecker.DEFAULT.equalTypes(elementType, builtIns.getArrayElementType(paramType))
} }
fun FunctionDescriptor.isNonGenericToArray(): Boolean { fun FunctionDescriptor.isNonGenericToArray(): Boolean {
@@ -361,13 +370,13 @@ fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodege
} }
val destructuringDeclaration = val destructuringDeclaration =
(DescriptorToSourceUtils.descriptorToDeclaration(parameterDescriptor) as? KtParameter)?.destructuringDeclaration (DescriptorToSourceUtils.descriptorToDeclaration(parameterDescriptor) as? KtParameter)?.destructuringDeclaration
?: error("Destructuring declaration for descriptor $parameterDescriptor not found") ?: error("Destructuring declaration for descriptor $parameterDescriptor not found")
codegen.initializeDestructuringDeclarationVariables( codegen.initializeDestructuringDeclarationVariables(
destructuringDeclaration, destructuringDeclaration,
TransientReceiver(parameterDescriptor.type), TransientReceiver(parameterDescriptor.type),
codegen.findLocalOrCapturedValue(parameterDescriptor) ?: error("Local var not found for parameter $parameterDescriptor") codegen.findLocalOrCapturedValue(parameterDescriptor) ?: error("Local var not found for parameter $parameterDescriptor")
) )
} }
@@ -383,9 +392,9 @@ inline fun FrameMap.useTmpVar(type: Type, block: (index: Int) -> Unit) {
} }
fun InstructionAdapter.generateNewInstanceDupAndPlaceBeforeStackTop( fun InstructionAdapter.generateNewInstanceDupAndPlaceBeforeStackTop(
frameMap: FrameMap, frameMap: FrameMap,
topStackType: Type, topStackType: Type,
newInstanceInternalName: String newInstanceInternalName: String
) { ) {
frameMap.useTmpVar(topStackType) { index -> frameMap.useTmpVar(topStackType) { index ->
store(index, topStackType) store(index, topStackType)
@@ -410,17 +419,17 @@ fun extractReificationArgument(type: KotlinType): Pair<TypeParameterDescriptor,
} }
fun unwrapInitialSignatureDescriptor(function: FunctionDescriptor): FunctionDescriptor = fun unwrapInitialSignatureDescriptor(function: FunctionDescriptor): FunctionDescriptor =
function.initialSignatureDescriptor ?: function function.initialSignatureDescriptor ?: function
fun ExpressionCodegen.generateCallReceiver(call: ResolvedCall<out CallableDescriptor>): StackValue = fun ExpressionCodegen.generateCallReceiver(call: ResolvedCall<out CallableDescriptor>): StackValue =
generateReceiverValue(call.extensionReceiver ?: call.dispatchReceiver!!, false) generateReceiverValue(call.extensionReceiver ?: call.dispatchReceiver!!, false)
fun ExpressionCodegen.generateCallSingleArgument(call: ResolvedCall<out CallableDescriptor>): StackValue = fun ExpressionCodegen.generateCallSingleArgument(call: ResolvedCall<out CallableDescriptor>): StackValue =
gen(call.getFirstArgumentExpression()!!) gen(call.getFirstArgumentExpression()!!)
fun ClassDescriptor.isPossiblyUninitializedSingleton() = fun ClassDescriptor.isPossiblyUninitializedSingleton() =
DescriptorUtils.isEnumEntry(this) || DescriptorUtils.isEnumEntry(this) ||
DescriptorUtils.isCompanionObject(this) && JvmCodegenUtil.isJvmInterface(this.containingDeclaration) DescriptorUtils.isCompanionObject(this) && JvmCodegenUtil.isJvmInterface(this.containingDeclaration)
val CodegenContext<*>.parentContextsWithSelf val CodegenContext<*>.parentContextsWithSelf
get() = generateSequence(this) { it.parentContext } get() = generateSequence(this) { it.parentContext }