diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index f9358b79b25..d9396631935 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -258,13 +258,18 @@ public class AsmUtil { return specialCase; } Visibility visibility = descriptor.getVisibility(); - Integer defaultMapping = visibilityToAccessFlag.get(visibility); + Integer defaultMapping = getVisibilityAccessFlag(visibility); if (defaultMapping == null) { throw new IllegalStateException(visibility + " is not a valid visibility in backend for " + DescriptorRenderer.DEBUG_TEXT.render(descriptor)); } return defaultMapping; } + @Nullable + public static Integer getVisibilityAccessFlag(Visibility visibility) { + return visibilityToAccessFlag.get(visibility); + } + /* Use this method to get visibility flag for class to define it in byte code (v.defineClass method). For other cases use getVisibilityAccessFlag(MemberDescriptor descriptor) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index 08ff0e79951..15cd7087a28 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -27,9 +27,11 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.types.KotlinType @@ -276,4 +278,11 @@ val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY val IrClass.isInterface get() = kind == ClassKind.INTERFACE val IrClass.isClass get() = kind == ClassKind.CLASS -val IrClass.isObject get() = kind == ClassKind.OBJECT \ No newline at end of file +val IrClass.isObject get() = kind == ClassKind.OBJECT + +val IrDeclaration.parentAsClass get() = parent as IrClass + +fun IrAnnotationContainer.hasAnnotation(name: FqName) = + annotations.any { + it.symbol.owner.parentAsClass.descriptor.fqNameSafe == name + } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index 037647685fe..78856567486 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -18,13 +18,14 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags -import org.jetbrains.kotlin.backend.common.lower.InitializersLowering import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.FunctionCodegen import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.psi.KtParameter @@ -77,15 +78,26 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class } } - var flags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, state).or(if (isStatic) Opcodes.ACC_STATIC else 0).xor( - if (classCodegen.irClass.isAnnotationClass) Opcodes.ACC_FINAL else 0/*TODO*/ - ).or(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0) - - if (classCodegen.irClass.isJvmInterface && InitializersLowering.clinitName == irFunction.name) { - //reset abstract flag for - flags = flags.xor(Opcodes.ACC_ABSTRACT) + val visibility = AsmUtil.getVisibilityAccessFlag(irFunction.visibility) ?: error("Unmapped visibility ${irFunction.visibility}") + val staticFlag = if (isStatic) Opcodes.ACC_STATIC else 0 + val varargFlag = if (irFunction.valueParameters.any { it.varargElementType != null }) Opcodes.ACC_VARARGS else 0 + val deprecation = 0 //TODO + val bridgeFlag = 0 //TODO + val modalityFlag = when ((irFunction as? IrSimpleFunction)?.modality) { + Modality.FINAL -> if (!classCodegen.irClass.isAnnotationClass) Opcodes.ACC_FINAL else 0 + Modality.ABSTRACT -> Opcodes.ACC_ABSTRACT + else -> if (classCodegen.irClass.isJvmInterface) Opcodes.ACC_ABSTRACT else 0 //TODO transform interface modality on lowering to DefaultImpls } - return flags + val nativeFlag = if (irFunction.isExternal) Opcodes.ACC_NATIVE else 0 + + return visibility or + modalityFlag or + staticFlag or + varargFlag or + deprecation or + nativeFlag or + bridgeFlag or + (if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0) } protected open fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index 9e29f392171..2eeed8fa4d8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -11,14 +11,15 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.isAnnotationClass -import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.org.objectweb.asm.Type class IrFrameMap : FrameMapBase() internal val IrFunction.isStatic - get() = this.dispatchReceiverParameter == null && this !is IrConstructor + get() = (this.dispatchReceiverParameter == null && this !is IrConstructor) || + (parentAsClass.isObject && this.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)) //TODO add lowering fun IrFrameMap.enter(irDeclaration: IrSymbolOwner, type: Type): Int { return enter(irDeclaration.symbol, type) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index d1885e3e514..1e7b29ae8c6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -69,6 +69,7 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper) members.add(functionDescriptorImpl.createFunctionAndMapVariables(it, it.visibility)) it.body = null + //TODO reset modality to abstract } }