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.name.Name
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset 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.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.KotlinType 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 IrExpression.isNullConst() = this is IrConst<*> && this.kind == IrConstKind.Null
fun IrCall.usesDefaultArguments(): Boolean = fun IrMemberAccessExpression.usesDefaultArguments(): Boolean =
this.descriptor.valueParameters.any { this.getValueArgument(it) == null } this.descriptor.valueParameters.any { this.getValueArgument(it) == null && !it.isVararg}
fun IrFunction.createParameterDeclarations() { fun IrFunction.createParameterDeclarations() {
fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl( fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl(
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.backend.jvm.codegen 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.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering
import org.jetbrains.kotlin.codegen.* 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) 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( val flags = calculateMethodFlags(isStatic)
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 methodVisitor = createMethod(flags, signature) val methodVisitor = createMethod(flags, signature)
FunctionCodegen.generateMethodAnnotations(descriptor, signature.asmMethod, methodVisitor, classCodegen, state.typeMapper) 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() 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 { open protected fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor {
return classCodegen.visitor.newMethod(irFunction.OtherOrigin, return classCodegen.visitor.newMethod(irFunction.OtherOrigin,
flags, flags,
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol 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.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils 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 { fun createSyntheticAccessorCallForFunction(superResult: IrElement, expression: IrMemberAccessExpression, codegenContext: CodegenContext<*>?, context: JvmBackendContext): IrElement {
val descriptor = expression.descriptor 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 directAccessor = codegenContext!!.accessibleDescriptor(JvmCodegenUtil.getDirectMember(descriptor), (expression as? IrCall)?.superQualifier)
val accessor = Companion.actualAccessor(descriptor, directAccessor) val accessor = Companion.actualAccessor(descriptor, directAccessor)