Fix default methods visibility

This commit is contained in:
Mikhael Bogdanov
2017-11-30 17:28:59 +01:00
parent 9365d1d859
commit be18cb9b16
3 changed files with 24 additions and 12 deletions
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.symbols.*
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.calls.components.isVararg
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.KotlinType
@@ -118,8 +119,8 @@ fun IrMemberAccessExpression.addArguments(args: List<Pair<ParameterDescriptor, I
fun IrExpression.isNullConst() = this is IrConst<*> && this.kind == IrConstKind.Null
fun IrCall.usesDefaultArguments(): Boolean =
this.descriptor.valueParameters.any { this.getValueArgument(it) == null }
fun IrMemberAccessExpression.usesDefaultArguments(): Boolean =
this.descriptor.valueParameters.any { this.getValueArgument(it) == null && !it.isVararg}
fun IrFunction.createParameterDeclarations() {
fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl(
@@ -16,6 +16,7 @@
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.jvm.lower.InitializersLowering
import org.jetbrains.kotlin.codegen.*
@@ -57,15 +58,7 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class
val frameMap = createFrameMapWithReceivers(classCodegen.state, descriptor, signature, isStatic)
var flags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, state).or(if (isStatic) Opcodes.ACC_STATIC else 0).xor(
if (DescriptorUtils.isAnnotationClass(descriptor.containingDeclaration)) Opcodes.ACC_FINAL else 0/*TODO*/
).or(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0)
val interfaceClInit = JvmCodegenUtil.isJvmInterface(classCodegen.descriptor) && InitializersLowering.clinitName == descriptor.name
if (interfaceClInit) {
//reset abstract flag
flags = flags.xor(Opcodes.ACC_ABSTRACT)
}
val flags = calculateMethodFlags(isStatic)
val methodVisitor = createMethod(flags, signature)
FunctionCodegen.generateMethodAnnotations(descriptor, signature.asmMethod, methodVisitor, classCodegen, state.typeMapper)
@@ -80,6 +73,23 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class
ExpressionCodegen(irFunction, frameMap, InstructionAdapter(methodVisitor), classCodegen).generate()
}
private fun calculateMethodFlags(isStatic: Boolean): Int {
var flags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, state).or(if (isStatic) Opcodes.ACC_STATIC else 0).xor(
if (DescriptorUtils.isAnnotationClass(descriptor.containingDeclaration)) Opcodes.ACC_FINAL else 0/*TODO*/
).or(if (descriptor is JvmDescriptorWithExtraFlags) descriptor.extraFlags else 0)
if (irFunction.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER) {
flags = flags.xor(AsmUtil.getVisibilityAccessFlag(descriptor)).or(Opcodes.ACC_PUBLIC)
}
val interfaceClInit = JvmCodegenUtil.isJvmInterface(classCodegen.descriptor) && InitializersLowering.clinitName == descriptor.name
if (interfaceClInit) {
//reset abstract flag
flags = flags.xor(Opcodes.ACC_ABSTRACT)
}
return flags
}
open protected fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor {
return classCodegen.visitor.newMethod(irFunction.OtherOrigin,
flags,
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.util.usesDefaultArguments
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -156,7 +157,7 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
fun createSyntheticAccessorCallForFunction(superResult: IrElement, expression: IrMemberAccessExpression, codegenContext: CodegenContext<*>?, context: JvmBackendContext): IrElement {
val descriptor = expression.descriptor
if (descriptor is FunctionDescriptor) {
if (descriptor is FunctionDescriptor && !expression.usesDefaultArguments()) {
val directAccessor = codegenContext!!.accessibleDescriptor(JvmCodegenUtil.getDirectMember(descriptor), (expression as? IrCall)?.superQualifier)
val accessor = Companion.actualAccessor(descriptor, directAccessor)