diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt index 5d76000576c..ae7f4e429ac 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.TargetId import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign @@ -86,6 +83,9 @@ internal class DeclarationsBuilderVisitor( for (propertyNode in node.properties) { packageMemberScopes += propertyNode.accept(this, packageFragments) } + for (functionNode in node.functions) { + packageMemberScopes += functionNode.accept(this, packageFragments) + } // initialize package fragments: packageFragments.forEachIndexed { index, packageFragment -> @@ -101,7 +101,14 @@ internal class DeclarationsBuilderVisitor( return propertyDescriptorsGroup.toList() } - + + override fun visitFunctionNode(node: FunctionNode, data: List): List { + val functionDescriptorsGroup = CommonizedGroup(node.dimension) + node.buildDescriptors(functionDescriptorsGroup, data) + + return functionDescriptorsGroup.toList() + } + companion object { inline fun noContainingDeclarations() = emptyList() inline fun noReturningDeclarations() = emptyList() diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt new file mode 100644 index 00000000000..4decd9924dd --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.builder + +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.SourceElement +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup +import org.jetbrains.kotlin.descriptors.commonizer.ir.Function +import org.jetbrains.kotlin.descriptors.commonizer.ir.FunctionNode +import org.jetbrains.kotlin.descriptors.commonizer.ir.ValueParameter +import org.jetbrains.kotlin.descriptors.commonizer.ir.indexOfCommon +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.resolve.DescriptorFactory +import org.jetbrains.kotlin.resolve.DescriptorUtils + +internal fun FunctionNode.buildDescriptors( + output: CommonizedGroup, + containingDeclarations: List +) { + val isCommonized = common != null + + target.forEachIndexed { index, function -> + function?.buildDescriptor(output, index, containingDeclarations, isActual = isCommonized) + } + + common?.buildDescriptor(output, indexOfCommon, containingDeclarations, isExpect = isCommonized) +} + +private fun Function.buildDescriptor( + output: CommonizedGroup, + index: Int, + containingDeclarations: List, + isExpect: Boolean = false, + isActual: Boolean = false +) { + val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for property $this") + + val functionDescriptor = SimpleFunctionDescriptorImpl.create( + containingDeclaration, + annotations, + name, + kind, + SourceElement.NO_SOURCE + ) + + functionDescriptor.isOperator = isOperator + functionDescriptor.isInfix = isInfix + functionDescriptor.isInline = isInline + functionDescriptor.isTailrec = isTailrec + functionDescriptor.isSuspend = isSuspend + functionDescriptor.isExternal = isExternal + + functionDescriptor.isExpect = isExpect + functionDescriptor.isActual = isActual + + val extensionReceiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( + functionDescriptor, + extensionReceiver?.type, + extensionReceiver?.annotations ?: Annotations.EMPTY + ) + + val dispatchReceiverDescriptor = DescriptorUtils.getDispatchReceiverParameterIfNeeded(containingDeclaration) + + functionDescriptor.initialize( + extensionReceiverDescriptor, + dispatchReceiverDescriptor, + emptyList(), // TODO: support type parameters + valueParameters.buildValueParameters(functionDescriptor), + returnType, + modality, + visibility + ) + + output[index] = functionDescriptor +} + +private fun List.buildValueParameters( + functionDescriptor: SimpleFunctionDescriptor +) = mapIndexed { index, param -> + ValueParameterDescriptorImpl( + functionDescriptor, + null, + index, + param.annotations, + param.name, + param.returnType, + param.declaresDefaultValue, + param.isCrossinline, + param.isNoinline, + param.varargElementType, + SourceElement.NO_SOURCE + ) +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt index b66c9e8d6e6..3aa575692d6 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt @@ -69,7 +69,7 @@ private fun Property.buildDescriptor( val dispatchReceiverDescriptor = DescriptorUtils.getDispatchReceiverParameterIfNeeded(containingDeclaration) propertyDescriptor.setType( - type, + returnType, emptyList(), // TODO: support type parameters dispatchReceiverDescriptor, extensionReceiverDescriptor diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CallableMemberCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CallableMemberCommonizer.kt new file mode 100644 index 00000000000..b0a2651f160 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CallableMemberCommonizer.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.CallableMember +import org.jetbrains.kotlin.name.Name + +abstract class CallableMemberCommonizer : Commonizer { + protected enum class State { + EMPTY, + ERROR, + IN_PROGRESS + } + + protected var name: Name? = null + protected val modality = ModalityCommonizer.default() + // TODO: visibility - what if virtual declaration? + protected val visibility = VisibilityCommonizer.lowering() + protected val extensionReceiver = ExtensionReceiverCommonizer.default() + protected val returnType = TypeCommonizer.default() + + protected var state = State.EMPTY + + final override fun commonizeWith(next: T): Boolean { + if (state == State.ERROR) + return false + + if (name == null) + name = next.name + + val result = canBeCommonized(next) + && modality.commonizeWith(next.modality) + && visibility.commonizeWith(next.visibility) + && extensionReceiver.commonizeWith(next.extensionReceiverParameter) + && returnType.commonizeWith(next.returnType!!) + && commonizeSpecifics(next) + + state = if (!result) State.ERROR else State.IN_PROGRESS + + return result + } + + protected abstract fun canBeCommonized(next: T): Boolean + protected abstract fun commonizeSpecifics(next: T): Boolean +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt new file mode 100644 index 00000000000..c5a9f71f183 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.CommonFunction +import org.jetbrains.kotlin.descriptors.commonizer.ir.ExtensionReceiver.Companion.toReceiverNoAnnotations +import org.jetbrains.kotlin.descriptors.commonizer.ir.Function + +class FunctionCommonizer : CallableMemberCommonizer() { + private val modifiers = FunctionModifiersCommonizer.default() + private val valueParameters = ValueParameterListCommonizer.default() + + override val result: Function + get() = when (state) { + State.EMPTY, State.ERROR -> error("Can't commonize function") + State.IN_PROGRESS -> CommonFunction( + name = name!!, + modality = modality.result, + visibility = visibility.result, + extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(), + returnType = returnType.result, + modifiers = modifiers.result, + valueParameters = valueParameters.result + ) + } + + override fun canBeCommonized(next: SimpleFunctionDescriptor) = true + + override fun commonizeSpecifics(next: SimpleFunctionDescriptor): Boolean { + + // TODO: type parameters (for functions???) + + return modifiers.commonizeWith(next) && valueParameters.commonizeWith(next.valueParameters) + } +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionModifiersCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionModifiersCommonizer.kt new file mode 100644 index 00000000000..7bcbe80d78f --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionModifiersCommonizer.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.FunctionModifiers + +interface FunctionModifiersCommonizer : Commonizer { + companion object { + fun default(): FunctionModifiersCommonizer = DefaultFunctionModifiersCommonizer() + } +} + +private class DefaultFunctionModifiersCommonizer : FunctionModifiersCommonizer { + private var modifiers: FunctionModifiersImpl? = null + private var error = false + + override val result: FunctionModifiers + get() = modifiers?.takeIf { !error } ?: error("Function modifiers setter can't be commonized") + + override fun commonizeWith(next: SimpleFunctionDescriptor): Boolean { + if (error) + return false + + val modifiers = modifiers + if (modifiers == null) + this.modifiers = FunctionModifiersImpl(next) + else { + if (modifiers.isSuspend != next.isSuspend) + error = true + else { + modifiers.isOperator = modifiers.isOperator && next.isOperator + modifiers.isInfix = modifiers.isInfix && next.isInfix + modifiers.isInline = modifiers.isInline && next.isInline + modifiers.isTailrec = modifiers.isTailrec && next.isTailrec + modifiers.isExternal = modifiers.isExternal && next.isExternal + } + } + + return !error + } + + private data class FunctionModifiersImpl( + override var isOperator: Boolean, + override var isInfix: Boolean, + override var isInline: Boolean, + override var isTailrec: Boolean, + override var isSuspend: Boolean, + override var isExternal: Boolean + ) : FunctionModifiers { + constructor(function: SimpleFunctionDescriptor) : this( + function.isOperator, + function.isInfix, + function.isInline, + function.isTailrec, + function.isSuspend, + function.isExternal + ) + } +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/NamedListWrappedCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/NamedListWrappedCommonizer.kt new file mode 100644 index 00000000000..af7a99c3d0d --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/NamedListWrappedCommonizer.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.Named +import org.jetbrains.kotlin.name.Name + +abstract class NamedListWrappedCommonizer( + private val subject: String, + private val wrappedCommonizerFactory: () -> Commonizer +) : Commonizer, List> { + private var wrapped: List>>? = null + private var error = false + + final override val result: List + get() = wrapped?.takeIf { !error }?.map { it.second.result } ?: error("Can't commonize list of $subject") + + final override fun commonizeWith(next: List): Boolean { + if (error) + return false + + val wrapped = wrapped + ?: next.map { it.name to wrappedCommonizerFactory() }.also { this.wrapped = it } + + if (wrapped.size != next.size) + error = true + else + for (index in 0 until next.size) { + val (name, commonizer) = wrapped[index] + val nextElement = next[index] + + if (name != nextElement.name || !commonizer.commonizeWith(nextElement)) { + error = true + break + } + } + + return !error + } +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/NullableWrappedCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/NullableWrappedCommonizer.kt new file mode 100644 index 00000000000..e0008e4a6cf --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/NullableWrappedCommonizer.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +abstract class NullableWrappedCommonizer( + private val subject: String, + private val wrappedCommonizerFactory: () -> Commonizer, + private val extractor: (T) -> WT, + private val builder: (WR) -> R +) : Commonizer { + private enum class State { + EMPTY, + ERROR, + WITH_WRAPPED, + WITHOUT_WRAPPED + } + + private var state = State.EMPTY + private var wrapped: Commonizer? = null + + final override val result: R? + get() = when (state) { + State.EMPTY, State.ERROR -> error("$subject setter can't be commonized") + State.WITH_WRAPPED -> builder(wrapped!!.result) + State.WITHOUT_WRAPPED -> null // null means there is no commonized result + } + + final override fun commonizeWith(next: T?): Boolean { + state = when (state) { + State.ERROR -> State.ERROR + State.EMPTY -> next?.let { + wrapped = wrappedCommonizerFactory() + doCommonizeWith(next) + } ?: State.WITHOUT_WRAPPED + State.WITH_WRAPPED -> next?.let(::doCommonizeWith) ?: State.ERROR + State.WITHOUT_WRAPPED -> next?.let { State.ERROR } ?: State.WITHOUT_WRAPPED + } + + return state != State.ERROR + } + + private fun doCommonizeWith(next: T) = + if (wrapped!!.commonizeWith(extractor(next))) State.WITH_WRAPPED else State.ERROR +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt index 63ab4b49a53..159843f82c7 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt @@ -7,64 +7,39 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.commonizer.ir.CommonProperty -import org.jetbrains.kotlin.descriptors.commonizer.ir.ExtensionReceiver +import org.jetbrains.kotlin.descriptors.commonizer.ir.ExtensionReceiver.Companion.toReceiverNoAnnotations import org.jetbrains.kotlin.descriptors.commonizer.ir.Property -import org.jetbrains.kotlin.name.Name -class PropertyCommonizer : Commonizer { - private enum class State { - EMPTY, - ERROR, - IN_PROGRESS - } - - private var name: Name? = null - // TODO: visibility - what if virtual declaration? - private val visibility = VisibilityCommonizer.lowering() - private val modality = ModalityCommonizer.default() - private val returnType = TypeCommonizer.default() +class PropertyCommonizer : CallableMemberCommonizer() { private val setter = PropertySetterCommonizer.default() - private val extensionReceiver = ExtensionReceiverCommonizer.default() - - private var state = State.EMPTY + private var isExternal = true override val result: Property get() = when (state) { State.EMPTY, State.ERROR -> error("Can't commonize property") State.IN_PROGRESS -> CommonProperty( name = name!!, - visibility = visibility.result, modality = modality.result, - type = returnType.result, - setter = setter.result, - extensionReceiver = extensionReceiver.result?.let { ExtensionReceiver.createNoAnnotations(it) } + visibility = visibility.result, + isExternal = isExternal, + extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(), + returnType = returnType.result, + setter = setter.result ) } - override fun commonizeWith(next: PropertyDescriptor): Boolean { - if (state == State.ERROR) - return false + override fun canBeCommonized(next: PropertyDescriptor) = when { + next.isConst -> false // expect property can't be const because expect can't have initializer + next.isLateInit -> false // expect property can't be lateinit + else -> true + } - if (name == null) - name = next.name - - val result = canBeCommonized(next) - && visibility.commonizeWith(next.visibility) - && modality.commonizeWith(next.modality) - && returnType.commonizeWith(next.type) - && setter.commonizeWith(next.setter) - && extensionReceiver.commonizeWith(next.extensionReceiverParameter) + override fun commonizeSpecifics(next: PropertyDescriptor): Boolean { // TODO: type parameters (for properties???) - state = if (!result) State.ERROR else State.IN_PROGRESS + isExternal = isExternal && next.isExternal - return result - } - - private fun canBeCommonized(property: PropertyDescriptor) = when { - property.isConst -> false // expect property can't be const because expect can't have initializer - property.isLateInit -> false // expect property can't be lateinit - else -> true + return setter.commonizeWith(next.setter) } } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertySetterCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertySetterCommonizer.kt index a1b159a5fc5..e8766967693 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertySetterCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertySetterCommonizer.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.commonizer.ir.Setter interface PropertySetterCommonizer : Commonizer { @@ -14,38 +15,11 @@ interface PropertySetterCommonizer : Commonizer error("Property setter can't be commonized") - State.WITH_SETTER -> Setter.createDefaultNoAnnotations(setterVisibility!!.result) - State.WITHOUT_SETTER -> null // null visibility means there is no setter - } - - override fun commonizeWith(next: PropertySetterDescriptor?): Boolean { - state = when (state) { - State.ERROR -> State.ERROR - State.EMPTY -> next?.let { - setterVisibility = VisibilityCommonizer.equalizing() - doCommonizeWith(next) - } ?: State.WITHOUT_SETTER - State.WITH_SETTER -> next?.let(::doCommonizeWith) ?: State.ERROR - State.WITHOUT_SETTER -> next?.let { State.ERROR } ?: State.WITHOUT_SETTER - } - - return state != State.ERROR - } - - private fun doCommonizeWith(setter: PropertySetterDescriptor) = - if (setterVisibility!!.commonizeWith(setter.visibility)) State.WITH_SETTER else State.ERROR -} +private class DefaultPropertySetterCommonizer : + PropertySetterCommonizer, + NullableWrappedCommonizer( + subject = "Property", + wrappedCommonizerFactory = { VisibilityCommonizer.equalizing() }, + extractor = { it.visibility }, + builder = { Setter.createDefaultNoAnnotations(it) } + ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt new file mode 100644 index 00000000000..dfa834275d0 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt @@ -0,0 +1,88 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.CommonValueParameter +import org.jetbrains.kotlin.descriptors.commonizer.ir.ValueParameter +import org.jetbrains.kotlin.descriptors.commonizer.isNull +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.UnwrappedType + +interface ValueParameterCommonizer : Commonizer { + companion object { + fun default(): ValueParameterCommonizer = DefaultValueParameterCommonizer() + } +} + +private class DefaultValueParameterCommonizer : ValueParameterCommonizer { + private enum class State { + EMPTY, + ERROR, + IN_PROGRESS + } + + private var name: Name? = null + private val returnType = TypeCommonizer.default() + private var varargElementType: UnwrappedType? = null + private var isCrossinline = true + private var isNoinline = true + + private var state = State.EMPTY + + override val result: ValueParameter + get() = when (state) { + State.EMPTY, State.ERROR -> error("Can't commonize value parameter") + State.IN_PROGRESS -> CommonValueParameter( + name = name!!, + returnType = returnType.result, + varargElementType = varargElementType, + isCrossinline = isCrossinline, + isNoinline = isNoinline + ) + } + + override fun commonizeWith(next: ValueParameterDescriptor): Boolean { + if (state == State.ERROR) + return true + + val result = !next.declaresDefaultValue() && returnType.commonizeWith(next.type) + state = if (!result) + State.ERROR + else when { + state == State.EMPTY -> { + name = next.name + varargElementType = next.varargElementType?.unwrap() + isCrossinline = next.isCrossinline + isNoinline = next.isNoinline + + State.IN_PROGRESS + } + varargElementType.isNull() != next.varargElementType.isNull() -> State.ERROR + else -> { + isCrossinline = isCrossinline && next.isCrossinline + isNoinline = isNoinline && next.isNoinline + + State.IN_PROGRESS + } + } + + return state != State.ERROR + } +} + +interface ValueParameterListCommonizer : Commonizer, List> { + companion object { + fun default(): ValueParameterListCommonizer = DefaultValueParameterListCommonizer() + } +} + +private class DefaultValueParameterListCommonizer : + ValueParameterListCommonizer, + NamedListWrappedCommonizer( + subject = "value parameters", + wrappedCommonizerFactory = { ValueParameterCommonizer.default() } + ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/CallableMember.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/CallableMember.kt new file mode 100644 index 00000000000..9a69ac92f52 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/CallableMember.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.ir + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.commonizer.ir.ExtensionReceiver.Companion.toReceiver +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.UnwrappedType + +interface CallableMember { + val annotations: Annotations + val name: Name + val modality: Modality + val visibility: Visibility + val isExternal: Boolean + val extensionReceiver: ExtensionReceiver? + val returnType: UnwrappedType + val kind: CallableMemberDescriptor.Kind +} + +abstract class CommonCallableMember : CallableMember { + final override val annotations: Annotations get() = Annotations.EMPTY + final override val kind get() = CallableMemberDescriptor.Kind.DECLARATION +} + +abstract class TargetCallableMember(protected val descriptor: T) : CallableMember { + final override val annotations: Annotations get() = descriptor.annotations + final override val name: Name get() = descriptor.name + final override val modality: Modality get() = descriptor.modality + final override val visibility: Visibility get() = descriptor.visibility + final override val isExternal: Boolean get() = descriptor.isExternal + final override val extensionReceiver: ExtensionReceiver? get() = descriptor.extensionReceiverParameter?.toReceiver() + final override val returnType: UnwrappedType get() = descriptor.returnType!!.unwrap() + final override val kind: CallableMemberDescriptor.Kind get() = descriptor.kind +} + +data class ExtensionReceiver( + val annotations: Annotations, + val type: UnwrappedType +) { + companion object { + fun UnwrappedType.toReceiverNoAnnotations() = ExtensionReceiver(Annotations.EMPTY, this) + fun ReceiverParameterDescriptor.toReceiver() = ExtensionReceiver(annotations, type.unwrap()) + } +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/ExtensionReceiver.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/ExtensionReceiver.kt deleted file mode 100644 index 3c5a8d02ce3..00000000000 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/ExtensionReceiver.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.ir - -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor -import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.types.UnwrappedType - -data class ExtensionReceiver( - val annotations: Annotations, - val type: UnwrappedType -) { - companion object { - fun createNoAnnotations(type: UnwrappedType) = ExtensionReceiver(Annotations.EMPTY, type) - - fun ReceiverParameterDescriptor.toReceiver() = ExtensionReceiver(annotations, type.unwrap()) - } -} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Function.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Function.kt new file mode 100644 index 00000000000..8c7b70e6e87 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Function.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.ir + +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.UnwrappedType + +interface FunctionModifiers { + val isOperator: Boolean + val isInfix: Boolean + val isInline: Boolean + val isTailrec: Boolean + val isSuspend: Boolean + val isExternal: Boolean +} + +interface Function : CallableMember, FunctionModifiers, Declaration { + val valueParameters: List +} + +data class CommonFunction( + override val name: Name, + override val modality: Modality, + override val visibility: Visibility, + override val extensionReceiver: ExtensionReceiver?, + override val returnType: UnwrappedType, + private val modifiers: FunctionModifiers, + override val valueParameters: List +) : CommonCallableMember(), Function, FunctionModifiers by modifiers + +class TargetFunction(descriptor: SimpleFunctionDescriptor) : TargetCallableMember(descriptor), Function { + override val isOperator: Boolean get() = descriptor.isOperator + override val isInfix: Boolean get() = descriptor.isInfix + override val isInline: Boolean get() = descriptor.isInline + override val isTailrec: Boolean get() = descriptor.isTailrec + override val isSuspend: Boolean get() = descriptor.isSuspend + override val valueParameters: List get() = descriptor.valueParameters.map(::PlatformValueParameter) +} + +interface ValueParameter { + val name: Name + val annotations: Annotations + val returnType: UnwrappedType + val varargElementType: UnwrappedType? + val declaresDefaultValue: Boolean + val isCrossinline: Boolean + val isNoinline: Boolean +} + +data class CommonValueParameter( + override val name: Name, + override val returnType: UnwrappedType, + override val varargElementType: UnwrappedType?, + override val isCrossinline: Boolean, + override val isNoinline: Boolean +) : ValueParameter { + override val annotations: Annotations get() = Annotations.EMPTY + override val declaresDefaultValue: Boolean get() = false +} + +data class PlatformValueParameter(private val descriptor: ValueParameterDescriptor) : ValueParameter { + override val name: Name get() = descriptor.name + override val annotations: Annotations get() = descriptor.annotations + override val returnType: UnwrappedType get() = descriptor.returnType!!.unwrap() + override val varargElementType: UnwrappedType? get() = descriptor.varargElementType?.unwrap() + override val declaresDefaultValue: Boolean get() = descriptor.declaresDefaultValue() + override val isCrossinline: Boolean get() = descriptor.isCrossinline + override val isNoinline: Boolean get() = descriptor.isNoinline +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/NodeVisitor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/NodeVisitor.kt index 5ecf2f2f0d2..4b715df8933 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/NodeVisitor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/NodeVisitor.kt @@ -10,4 +10,5 @@ interface NodeVisitor { fun visitModuleNode(node: ModuleNode, data: T): R fun visitPackageNode(node: PackageNode, data: T): R fun visitPropertyNode(node: PropertyNode, data: T): R + fun visitFunctionNode(node: FunctionNode, data: T): R } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Property.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Property.kt index 74662674853..8fd66fee33f 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Property.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/Property.kt @@ -11,24 +11,15 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.descriptors.commonizer.ir.Getter.Companion.toGetter import org.jetbrains.kotlin.descriptors.commonizer.ir.Setter.Companion.toSetter -import org.jetbrains.kotlin.descriptors.commonizer.ir.ExtensionReceiver.Companion.toReceiver import org.jetbrains.kotlin.resolve.constants.ConstantValue -interface Property : Declaration { - val annotations: Annotations - val name: Name - val visibility: Visibility - val modality: Modality +interface Property : CallableMember, Declaration { val isVar: Boolean - val kind: CallableMemberDescriptor.Kind - val type: UnwrappedType val lateInit: Boolean val isConst: Boolean - val isExternal: Boolean val isDelegate: Boolean val getter: Getter? val setter: Setter? - val extensionReceiver: ExtensionReceiver? val backingFieldAnnotations: Annotations? // null assumes no backing field val delegateFieldAnnotations: Annotations? // null assumes no backing field val compileTimeInitializer: ConstantValue<*>? @@ -36,18 +27,16 @@ interface Property : Declaration { data class CommonProperty( override val name: Name, - override val visibility: Visibility, override val modality: Modality, - override val type: UnwrappedType, - override val setter: Setter?, - override val extensionReceiver: ExtensionReceiver? -) : Property { - override val annotations get() = Annotations.EMPTY + override val visibility: Visibility, + override val isExternal: Boolean, + override val extensionReceiver: ExtensionReceiver?, + override val returnType: UnwrappedType, + override val setter: Setter? +) : CommonCallableMember(), Property { override val isVar: Boolean get() = setter != null - override val kind get() = CallableMemberDescriptor.Kind.DECLARATION override val lateInit: Boolean get() = false override val isConst: Boolean get() = false - override val isExternal: Boolean get() = false override val isDelegate: Boolean get() = false override val getter: Getter get() = Getter.DEFAULT_NO_ANNOTATIONS override val backingFieldAnnotations: Annotations? get() = null @@ -55,22 +44,14 @@ data class CommonProperty( override val compileTimeInitializer: ConstantValue<*>? get() = null } -data class TargetProperty(private val descriptor: PropertyDescriptor) : Property { - override val annotations: Annotations get() = descriptor.annotations - override val name: Name get() = descriptor.name - override val visibility: Visibility get() = descriptor.visibility - override val modality: Modality get() = descriptor.modality +class TargetProperty(descriptor: PropertyDescriptor) : TargetCallableMember(descriptor), Property { override val isVar: Boolean get() = descriptor.isVar - override val kind: CallableMemberDescriptor.Kind get() = descriptor.kind - override val type: UnwrappedType get() = descriptor.type.unwrap() override val lateInit: Boolean get() = descriptor.isLateInit override val isConst: Boolean get() = descriptor.isConst - override val isExternal: Boolean get() = descriptor.isExternal @Suppress("DEPRECATION") override val isDelegate: Boolean get() = descriptor.isDelegated override val getter: Getter? get() = descriptor.getter?.toGetter() override val setter: Setter? get() = descriptor.setter?.toSetter() - override val extensionReceiver: ExtensionReceiver? get() = descriptor.extensionReceiverParameter?.toReceiver() override val backingFieldAnnotations: Annotations? get() = descriptor.backingField?.annotations override val delegateFieldAnnotations: Annotations? get() = descriptor.delegateField?.annotations override val compileTimeInitializer: ConstantValue<*>? get() = descriptor.compileTimeInitializer diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodeBuilders.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodeBuilders.kt index 5532fba130e..192b49aae1e 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodeBuilders.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodeBuilders.kt @@ -7,10 +7,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.ir import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.commonizer.* import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer import org.jetbrains.kotlin.descriptors.commonizer.core.PropertyCommonizer +import org.jetbrains.kotlin.descriptors.commonizer.core.FunctionCommonizer import org.jetbrains.kotlin.descriptors.commonizer.firstNonNull import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -41,6 +43,13 @@ internal fun buildPropertyNode(properties: List): PropertyN ::PropertyNode ) +internal fun buildFunctionNode(functions: List): FunctionNode = buildNode( + functions, + { TargetFunction(it) }, + { commonize(it, FunctionCommonizer()) }, + ::FunctionNode +) + private fun > buildNode( descriptors: List, targetDeclarationProducer: (T) -> D, diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodes.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodes.kt index 1afe8f74dc4..ff179f12291 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodes.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/ir/nodes.kt @@ -39,6 +39,7 @@ class PackageNode( override val common: Package? ) : Node { val properties: MutableList = ArrayList() + val functions: MutableList = ArrayList() override fun accept(visitor: NodeVisitor, data: T) = visitor.visitPackageNode(this, data) @@ -52,6 +53,14 @@ class PropertyNode( visitor.visitPropertyNode(this, data) } +class FunctionNode( + override val target: List, + override val common: Function? +) : Node { + override fun accept(visitor: NodeVisitor, data: T) = + visitor.visitFunctionNode(this, data) +} + internal val Node.indexOfCommon: Int get() = target.size diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/functions.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/functions.kt new file mode 100644 index 00000000000..76455b36779 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/functions.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.mergedtree + +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.buildFunctionNode + +internal fun mergeFunctions(properties: List) = buildFunctionNode(properties) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt index b5acc6f7bbc..a08283aaf7f 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt @@ -6,10 +6,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroupMap +import org.jetbrains.kotlin.descriptors.commonizer.fqName import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.descriptors.commonizer.ir.PackageNode @@ -22,22 +23,40 @@ internal fun mergePackages( val node = buildPackageNode(packageFqName, packageMemberScopes) val propertiesMap = CommonizedGroupMap(packageMemberScopes.size) + val functionsMap = CommonizedGroupMap(packageMemberScopes.size) packageMemberScopes.forEachIndexed { index, memberScope -> memberScope?.collectProperties { propertyKey, property -> propertiesMap[propertyKey][index] = property } + memberScope?.collectFunctions { functionKey, function -> + functionsMap[functionKey][index] = function + } } for ((_, propertiesGroup) in propertiesMap) { node.properties += mergeProperties(propertiesGroup.toList()) } - // FIXME: traverse the rest - functions, classes, typealiases + for ((_, functionsGroup) in functionsMap) { + node.functions += mergeFunctions(functionsGroup.toList()) + } + + // FIXME: traverse the rest - classes, typealiases return node } +internal data class PropertyKey( + val name: Name, + val extensionReceiverParameterFqName: FqName? +) { + constructor(property: PropertyDescriptor) : this( + property.name, + property.extensionReceiverParameter?.type?.fqName + ) +} + internal fun MemberScope.collectProperties(collector: (PropertyKey, PropertyDescriptor) -> Unit) { getContributedDescriptors(DescriptorKindFilter.VARIABLES).asSequence() .filterIsInstance() @@ -46,12 +65,22 @@ internal fun MemberScope.collectProperties(collector: (PropertyKey, PropertyDesc } } -internal data class PropertyKey( +internal data class FunctionKey( val name: Name, + val valueParameters: List>, val extensionReceiverParameterFqName: FqName? ) { - constructor(property: PropertyDescriptor) : this( - property.name, - property.extensionReceiverParameter?.run { type.constructor.declarationDescriptor!!.fqNameSafe } + constructor(function: SimpleFunctionDescriptor) : this( + function.name, + function.valueParameters.map { it.name to it.type.fqName }, + function.extensionReceiverParameter?.type?.fqName ) } + +internal fun MemberScope.collectFunctions(collector: (FunctionKey, SimpleFunctionDescriptor) -> Unit) { + getContributedDescriptors(DescriptorKindFilter.FUNCTIONS).asSequence() + .filterIsInstance() + .forEach { function -> + collector(FunctionKey(function), function) + } +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt index 8ec8c1e8458..1792a57f432 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt @@ -5,6 +5,9 @@ package org.jetbrains.kotlin.descriptors.commonizer +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance internal fun Sequence.toList(expectedCapacity: Int): List { @@ -14,3 +17,8 @@ internal fun Sequence.toList(expectedCapacity: Int): List { } internal inline fun Iterable.firstNonNull() = firstIsInstance() + +internal val KotlinType.fqName: FqName + get() = constructor.declarationDescriptor!!.fqNameSafe + +internal fun Any?.isNull() = this == null diff --git a/konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/common/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/common/package_root.kt similarity index 54% rename from konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/common/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/common/package_root.kt index bff2ce7e967..dfb3ae8a2a8 100644 --- a/konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/common/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/common/package_root.kt @@ -6,3 +6,10 @@ expect val Short.intProperty: Int expect val Long.intProperty: Int expect val String.intProperty: Int expect val Planet.intProperty: Int + +expect fun intFunction(): Int +expect fun Int.intFunction(): Int +expect fun Short.intFunction(): Int +expect fun Long.intFunction(): Int +expect fun String.intFunction(): Int +expect fun Planet.intFunction(): Int diff --git a/konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/js/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/js/package_root.kt similarity index 56% rename from konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/js/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/js/package_root.kt index ecad1b4032f..c5873e4300a 100644 --- a/konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/js/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/js/package_root.kt @@ -7,5 +7,15 @@ actual val Long.intProperty get() = toInt() actual val String.intProperty get() = length actual val Planet.intProperty get() = diameter.toInt() +actual fun intFunction() = 42 +actual fun Int.intFunction() = this +actual fun Short.intFunction() = toInt() +actual fun Long.intFunction() = toInt() +actual fun String.intFunction() = length +actual fun Planet.intFunction() = diameter.toInt() + val String.mismatchedProperty1 get() = 42 val mismatchedProperty2 get() = 42 + +fun String.mismatchedFunction1() = 42 +fun mismatchedFunction2() = 42 diff --git a/konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/jvm/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/jvm/package_root.kt similarity index 56% rename from konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/jvm/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/jvm/package_root.kt index d339bf4cf52..22ff0baf6c2 100644 --- a/konan/commonizer/testData/propertyCommonization/extensionReceivers/commonized/jvm/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/commonized/jvm/package_root.kt @@ -7,5 +7,15 @@ actual val Long.intProperty get() = toInt() actual val String.intProperty get() = length actual val Planet.intProperty get() = diameter.toInt() +actual fun intFunction() = 42 +actual fun Int.intFunction() = this +actual fun Short.intFunction() = toInt() +actual fun Long.intFunction() = toInt() +actual fun String.intFunction() = length +actual fun Planet.intFunction() = diameter.toInt() + val mismatchedProperty1 get() = 42 val Double.mismatchedProperty2 get() = 42 + +fun mismatchedFunction1() = 42 +fun Double.mismatchedFunction2() = 42 diff --git a/konan/commonizer/testData/propertyCommonization/extensionReceivers/original/js/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/original/js/package_root.kt similarity index 56% rename from konan/commonizer/testData/propertyCommonization/extensionReceivers/original/js/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/extensionReceivers/original/js/package_root.kt index 2f1692e78e0..7cab8a200ea 100644 --- a/konan/commonizer/testData/propertyCommonization/extensionReceivers/original/js/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/original/js/package_root.kt @@ -7,5 +7,15 @@ val Long.intProperty get() = toInt() val String.intProperty get() = length val Planet.intProperty get() = diameter.toInt() +fun intFunction() = 42 +fun Int.intFunction() = this +fun Short.intFunction() = toInt() +fun Long.intFunction() = toInt() +fun String.intFunction() = length +fun Planet.intFunction() = diameter.toInt() + val String.mismatchedProperty1 get() = 42 val mismatchedProperty2 get() = 42 + +fun String.mismatchedFunction1() = 42 +fun mismatchedFunction2() = 42 diff --git a/konan/commonizer/testData/propertyCommonization/extensionReceivers/original/jvm/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/original/jvm/package_root.kt similarity index 56% rename from konan/commonizer/testData/propertyCommonization/extensionReceivers/original/jvm/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/extensionReceivers/original/jvm/package_root.kt index bf01a3ba368..daa1c272269 100644 --- a/konan/commonizer/testData/propertyCommonization/extensionReceivers/original/jvm/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/extensionReceivers/original/jvm/package_root.kt @@ -7,5 +7,15 @@ val Long.intProperty get() = toInt() val String.intProperty get() = length val Planet.intProperty get() = diameter.toInt() +fun intFunction() = 42 +fun Int.intFunction() = this +fun Short.intFunction() = toInt() +fun Long.intFunction() = toInt() +fun String.intFunction() = length +fun Planet.intFunction() = diameter.toInt() + val mismatchedProperty1 get() = 42 val Double.mismatchedProperty2 get() = 42 + +fun mismatchedFunction1() = 42 +fun Double.mismatchedFunction2() = 42 diff --git a/konan/commonizer/testData/propertyCommonization/returnTypes/commonized/common/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/common/package_root.kt similarity index 74% rename from konan/commonizer/testData/propertyCommonization/returnTypes/commonized/common/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/common/package_root.kt index c9b97cfb6cc..1d0cae72063 100644 --- a/konan/commonizer/testData/propertyCommonization/returnTypes/commonized/common/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/common/package_root.kt @@ -13,3 +13,9 @@ expect val property2: String expect val property3: Planet expect val property6: Planet expect val property7: C + +expect fun function1(): Int +expect fun function2(): String +expect fun function3(): Planet +expect fun function6(): Planet +expect fun function7(): C diff --git a/konan/commonizer/testData/propertyCommonization/returnTypes/commonized/js/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/js/package_root.kt similarity index 62% rename from konan/commonizer/testData/propertyCommonization/returnTypes/commonized/js/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/js/package_root.kt index 56fc38a1a65..a9e3e496f0c 100644 --- a/konan/commonizer/testData/propertyCommonization/returnTypes/commonized/js/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/js/package_root.kt @@ -17,8 +17,22 @@ val property5 = A("Earth", 12742) actual val property6 = Planet("Earth", 12742) actual val property7 = C("Earth", 12742) +actual fun function1() = 1 +actual fun function2() = "hello" +actual fun function3() = Planet("Earth", 12742) +fun function4() = A("Earth", 12742) +fun function5() = A("Earth", 12742) +actual fun function6() = Planet("Earth", 12742) +actual fun function7() = C("Earth", 12742) + val propertyWithMismatchedType1: Int = 1 val propertyWithMismatchedType2: Int = 1 val propertyWithMismatchedType3: Int = 1 val propertyWithMismatchedType4: Int = 1 val propertyWithMismatchedType5: Int = 1 + +fun functionWithMismatchedType1(): Int = 1 +fun functionWithMismatchedType2(): Int = 1 +fun functionWithMismatchedType3(): Int = 1 +fun functionWithMismatchedType4(): Int = 1 +fun functionWithMismatchedType5(): Int = 1 diff --git a/konan/commonizer/testData/propertyCommonization/returnTypes/commonized/jvm/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/jvm/package_root.kt similarity index 61% rename from konan/commonizer/testData/propertyCommonization/returnTypes/commonized/jvm/package_root.kt rename to konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/jvm/package_root.kt index 767401cc92d..378a1be17ee 100644 --- a/konan/commonizer/testData/propertyCommonization/returnTypes/commonized/jvm/package_root.kt +++ b/konan/commonizer/testData/callableMemberCommonization/returnTypes/commonized/jvm/package_root.kt @@ -17,8 +17,22 @@ val property5: Planet = A("Earth", 12742) actual val property6: Planet = A("Earth", 12742) actual val property7: C = Planet("Earth", 12742) +actual fun function1(): Int = 1 +actual fun function2(): String = "hello" +actual fun function3(): Planet = Planet("Earth", 12742) +fun function4(): B = A("Earth", 12742) +fun function5(): Planet = A("Earth", 12742) +actual fun function6(): Planet = Planet("Earth", 12742) +actual fun function7(): C = C("Earth", 12742) + val propertyWithMismatchedType1: Long = 1 val propertyWithMismatchedType2: Short = 1 val propertyWithMismatchedType3: Number = 1 val propertyWithMismatchedType4: Comparable = 1 val propertyWithMismatchedType5: String = 1.toString() + +fun functionWithMismatchedType1(): Long = 1 +fun functionWithMismatchedType2(): Short = 1 +fun functionWithMismatchedType3(): Number = 1 +fun functionWithMismatchedType4(): Comparable = 1 +fun functionWithMismatchedType5(): String = 1.toString() diff --git a/konan/commonizer/testData/callableMemberCommonization/returnTypes/original/js/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/returnTypes/original/js/package_root.kt new file mode 100644 index 00000000000..f7680053299 --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/returnTypes/original/js/package_root.kt @@ -0,0 +1,40 @@ +class Planet(val name: String, val diameter: Double) + +val propertyWithInferredType1 = 1 +val propertyWithInferredType2 = "hello" +val propertyWithInferredType3 = 42.toString() +val propertyWithInferredType4 = null +val propertyWithInferredType5 = Planet("Earth", 12742) + +typealias A = Planet +typealias C = Planet + +// with inferred type: +val property1 = 1 +val property2 = "hello" +val property3 = Planet("Earth", 12742) +val property4 = A("Earth", 12742) +val property5 = A("Earth", 12742) +val property6 = Planet("Earth", 12742) +val property7 = C("Earth", 12742) + +// with inferred type: +fun function1() = 1 +fun function2() = "hello" +fun function3() = Planet("Earth", 12742) +fun function4() = A("Earth", 12742) +fun function5() = A("Earth", 12742) +fun function6() = Planet("Earth", 12742) +fun function7() = C("Earth", 12742) + +val propertyWithMismatchedType1: Int = 1 +val propertyWithMismatchedType2: Int = 1 +val propertyWithMismatchedType3: Int = 1 +val propertyWithMismatchedType4: Int = 1 +val propertyWithMismatchedType5: Int = 1 + +fun functionWithMismatchedType1(): Int = 1 +fun functionWithMismatchedType2(): Int = 1 +fun functionWithMismatchedType3(): Int = 1 +fun functionWithMismatchedType4(): Int = 1 +fun functionWithMismatchedType5(): Int = 1 diff --git a/konan/commonizer/testData/callableMemberCommonization/returnTypes/original/jvm/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/returnTypes/original/jvm/package_root.kt new file mode 100644 index 00000000000..31ebb440109 --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/returnTypes/original/jvm/package_root.kt @@ -0,0 +1,40 @@ +class Planet(val name: String, val diameter: Double) + +val propertyWithInferredType1 get() = 1 +val propertyWithInferredType2 get() = "hello" +val propertyWithInferredType3 get() = 42.toString() +val propertyWithInferredType4 get() = null +val propertyWithInferredType5 get() = Planet("Earth", 12742) + +typealias B = Planet +typealias C = Planet + +// with explicit type: +val property1: Int = 1 +val property2: String = "hello" +val property3: Planet = Planet("Earth", 12742) +val property4: B = Planet("Earth", 12742) +val property5: Planet = A("Earth", 12742) +val property6: Planet = A("Earth", 12742) +val property7: C = Planet("Earth", 12742) + +// with explicit type: +fun function1(): Int = 1 +fun function2(): String = "hello" +fun function3(): Planet = Planet("Earth", 12742) +fun function4(): B = A("Earth", 12742) +fun function5(): Planet = A("Earth", 12742) +fun function6(): Planet = Planet("Earth", 12742) +fun function7(): C = C("Earth", 12742) + +val propertyWithMismatchedType1: Long = 1 +val propertyWithMismatchedType2: Short = 1 +val propertyWithMismatchedType3: Number = 1 +val propertyWithMismatchedType4: Comparable = 1 +val propertyWithMismatchedType5: String = 1.toString() + +fun functionWithMismatchedType1(): Long = 1 +fun functionWithMismatchedType2(): Short = 1 +fun functionWithMismatchedType3(): Number = 1 +fun functionWithMismatchedType4(): Comparable = 1 +fun functionWithMismatchedType5(): String = 1.toString() diff --git a/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/common/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/common/package_root.kt new file mode 100644 index 00000000000..1b77a8601d9 --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/common/package_root.kt @@ -0,0 +1,7 @@ +expect public val publicProperty: Int +expect internal val publicOrInternalProperty: Int +expect internal val internalProperty: Int + +expect public fun publicFunction(): Int +expect internal val internalFunction(): Int +expect internal fun publicOrInternalFunction(): Int diff --git a/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/js/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/js/package_root.kt new file mode 100644 index 00000000000..371a876a036 --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/js/package_root.kt @@ -0,0 +1,11 @@ +actual public val publicProperty = 1 +actual public val publicOrInternalProperty = 1 +actual internal val internalProperty = 1 +internal val internalOrPrivateProperty = 1 +private val privateProperty = 1 + +actual public fun publicFunction() = 1 +actual public fun publicOrInternalFunction() = 1 +actual internal val internalFunction() = 1 +internal val internalOrPrivateFunction() = 1 +private val privateFunction() = 1 diff --git a/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/jvm/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/jvm/package_root.kt new file mode 100644 index 00000000000..00a96a0fda0 --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/visibility/commonized/jvm/package_root.kt @@ -0,0 +1,11 @@ +actual public val publicProperty = 1 +actual internal val publicOrInternalProperty = 1 +actual internal val internalProperty = 1 +private val internalOrPrivateProperty = 1 +private val privateProperty = 1 + +actual public fun publicFunction() = 1 +actual internal fun publicOrInternalFunction() = 1 +actual internal val internalFunction() = 1 +private val internalOrPrivateFunction() = 1 +private val privateFunction() = 1 diff --git a/konan/commonizer/testData/callableMemberCommonization/visibility/original/js/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/visibility/original/js/package_root.kt new file mode 100644 index 00000000000..b816e7716ec --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/visibility/original/js/package_root.kt @@ -0,0 +1,11 @@ +public val publicProperty = 1 +public val publicOrInternalProperty = 1 +internal val internalProperty = 1 +internal val internalOrPrivateProperty = 1 +private val privateProperty = 1 + +public fun publicFunction() = 1 +public fun publicOrInternalFunction() = 1 +internal val internalFunction() = 1 +internal val internalOrPrivateFunction() = 1 +private val privateFunction() = 1 diff --git a/konan/commonizer/testData/callableMemberCommonization/visibility/original/jvm/package_root.kt b/konan/commonizer/testData/callableMemberCommonization/visibility/original/jvm/package_root.kt new file mode 100644 index 00000000000..4f5b02569c9 --- /dev/null +++ b/konan/commonizer/testData/callableMemberCommonization/visibility/original/jvm/package_root.kt @@ -0,0 +1,11 @@ +public val publicProperty = 1 +internal val publicOrInternalProperty = 1 +internal val internalProperty = 1 +private val internalOrPrivateProperty = 1 +private val privateProperty = 1 + +public fun publicFunction() = 1 +internal fun publicOrInternalFunction() = 1 +internal val internalFunction() = 1 +private val internalOrPrivateFunction() = 1 +private val privateFunction() = 1 diff --git a/konan/commonizer/testData/functionCommonization/specifics/commonized/common/package_root.kt b/konan/commonizer/testData/functionCommonization/specifics/commonized/common/package_root.kt new file mode 100644 index 00000000000..f96445f8ae0 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/specifics/commonized/common/package_root.kt @@ -0,0 +1,18 @@ +expect suspend fun suspendFunction1(): Int + +class Qux + +expect operator fun Qux.get(index: Int): String +expect fun Qux.set(index: Int, value: String) + +expect infix fun Qux.infixFunction1(another: Qux) +expect fun Qux.infixFunction2(another: Qux) + +expect tailrec fun tailrecFunction1() +expect fun tailrecFunction2() + +expect external fun externalFunction1() +expect fun externalFunction2() + +expect inline fun inlineFunction1() {} +expect fun inlineFunction2() {} diff --git a/konan/commonizer/testData/functionCommonization/specifics/commonized/js/package_root.kt b/konan/commonizer/testData/functionCommonization/specifics/commonized/js/package_root.kt new file mode 100644 index 00000000000..263e46df3a3 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/specifics/commonized/js/package_root.kt @@ -0,0 +1,19 @@ +actual suspend fun suspendFunction1() = 1 +suspend fun suspendFunction2() = 1 + +class Qux + +actual operator fun Qux.get(index: Int) = "$index" +actual operator fun Qux.set(index: Int, value: String) = Unit + +actual infix fun Qux.infixFunction1(another: Qux) {} +actual infix fun Qux.infixFunction2(another: Qux) {} + +actual tailrec fun tailrecFunction1() {} +actual tailrec fun tailrecFunction2() {} + +actual external fun externalFunction1() +actual external fun externalFunction2() + +actual inline fun inlineFunction1() {} +actual inline fun inlineFunction2() {} diff --git a/konan/commonizer/testData/functionCommonization/specifics/commonized/jvm/package_root.kt b/konan/commonizer/testData/functionCommonization/specifics/commonized/jvm/package_root.kt new file mode 100644 index 00000000000..a2026c786f5 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/specifics/commonized/jvm/package_root.kt @@ -0,0 +1,19 @@ +actual suspend fun suspendFunction1() = 1 +fun suspendFunction2() = 1 + +class Qux + +actual operator fun Qux.get(index: Int) = "$index" +actual fun Qux.set(index: Int, value: String) = Unit + +actual infix fun Qux.infixFunction1(another: Qux) {} +actual fun Qux.infixFunction2(another: Qux) {} + +actual tailrec fun tailrecFunction1() {} +actual fun tailrecFunction2() {} + +actual external fun externalFunction1() +actual fun externalFunction2() {} + +actual inline fun inlineFunction1() {} +actual fun inlineFunction2() {} diff --git a/konan/commonizer/testData/functionCommonization/specifics/original/js/package_root.kt b/konan/commonizer/testData/functionCommonization/specifics/original/js/package_root.kt new file mode 100644 index 00000000000..c3f22b47b56 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/specifics/original/js/package_root.kt @@ -0,0 +1,19 @@ +suspend fun suspendFunction1() = 1 +suspend fun suspendFunction2() = 1 + +class Qux + +operator fun Qux.get(index: Int) = "$index" +operator fun Qux.set(index: Int, value: String) = Unit + +infix fun Qux.infixFunction1(another: Qux) {} +infix fun Qux.infixFunction2(another: Qux) {} + +tailrec fun tailrecFunction1() {} +tailrec fun tailrecFunction2() {} + +external fun externalFunction1() +external fun externalFunction2() + +inline fun inlineFunction1() {} +inline fun inlineFunction2() {} diff --git a/konan/commonizer/testData/functionCommonization/specifics/original/jvm/package_root.kt b/konan/commonizer/testData/functionCommonization/specifics/original/jvm/package_root.kt new file mode 100644 index 00000000000..59b0f9d204c --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/specifics/original/jvm/package_root.kt @@ -0,0 +1,19 @@ +suspend fun suspendFunction1() = 1 +fun suspendFunction2() = 1 + +class Qux + +operator fun Qux.get(index: Int) = "$index" +fun Qux.set(index: Int, value: String) = Unit + +infix fun Qux.infixFunction1(another: Qux) {} +fun Qux.infixFunction2(another: Qux) {} + +tailrec fun tailrecFunction1() {} +fun tailrecFunction2() {} + +external fun externalFunction1() +fun externalFunction2() {} + +inline fun inlineFunction1() {} +fun inlineFunction2() {} diff --git a/konan/commonizer/testData/functionCommonization/valueParameters/commonized/common/package_root.kt b/konan/commonizer/testData/functionCommonization/valueParameters/commonized/common/package_root.kt new file mode 100644 index 00000000000..206bebb7cf3 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/valueParameters/commonized/common/package_root.kt @@ -0,0 +1,13 @@ +expect fun functionNoParameters() +expect fun functionSingleParameter(i: Int) +expect fun functionTwoParameters(i: Int, s: String) +expect fun functionThreeParameters(i: Int, s: String, l: List) + +expect inline fun inlineFunction1(lazyMessage: () -> String) +expect inline fun inlineFunction2(lazyMessage: () -> String) +expect inline fun inlineFunction3(crossinline lazyMessage: () -> String) +expect inline fun inlineFunction4(lazyMessage: () -> String) +expect inline fun inlineFunction5(noinline lazyMessage: () -> String) + +expect fun functionWithVararg1(vararg numbers: Int) +expect fun functionWithVararg5(numbers: Array) diff --git a/konan/commonizer/testData/functionCommonization/valueParameters/commonized/js/package_root.kt b/konan/commonizer/testData/functionCommonization/valueParameters/commonized/js/package_root.kt new file mode 100644 index 00000000000..8ea15f08a7a --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/valueParameters/commonized/js/package_root.kt @@ -0,0 +1,28 @@ +actual fun functionNoParameters() {} +actual fun functionSingleParameter(i: Int) {} +actual fun functionTwoParameters(i: Int, s: String) {} +actual fun functionThreeParameters(i: Int, s: String, l: List) {} + +fun functionMismatchedParameterCount1(i: Int, s: String) {} +fun functionMismatchedParameterCount2(i: Int, s: String, l: List) {} + +fun functionMismatchedParameterNames1(i: Int, s: String) {} +fun functionMismatchedParameterNames2(i: Int, s: String) {} + +fun functionMismatchedParameterTypes1(i: Int, s: String) {} +fun functionMismatchedParameterTypes2(i: Int, s: String) {} + +fun functionDefaultValues1(i: Int = 1, s: String) {} +fun functionDefaultValues2(i: Int, s: String = "hello") {} + +actual inline fun inlineFunction1(lazyMessage: () -> String) {} +actual inline fun inlineFunction2(lazyMessage: () -> String) {} +actual inline fun inlineFunction3(crossinline lazyMessage: () -> String) {} +actual inline fun inlineFunction4(lazyMessage: () -> String) {} +actual inline fun inlineFunction5(noinline lazyMessage: () -> String) {} + +actual fun functionWithVararg1(vararg numbers: Int) {} +fun functionWithVararg2(vararg numbers: Int) {} +fun functionWithVararg3(vararg numbers: Int) {} +//fun functionWithVararg4(numbers: Array) {} +actual fun functionWithVararg5(numbers: Array) {} diff --git a/konan/commonizer/testData/functionCommonization/valueParameters/commonized/jvm/package_root.kt b/konan/commonizer/testData/functionCommonization/valueParameters/commonized/jvm/package_root.kt new file mode 100644 index 00000000000..b96b4ef91ce --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/valueParameters/commonized/jvm/package_root.kt @@ -0,0 +1,28 @@ +actual fun functionNoParameters() {} +actual fun functionSingleParameter(i: Int) {} +actual fun functionTwoParameters(i: Int, s: String) {} +actual fun functionThreeParameters(i: Int, s: String, l: List) {} + +fun functionMismatchedParameterCount1(i: Int, s: String, l: List) {} +fun functionMismatchedParameterCount2(i: Int, s: String) {} + +fun functionMismatchedParameterNames1(i1: Int, s: String) {} +fun functionMismatchedParameterNames2(i: Int, s1: String) {} + +fun functionMismatchedParameterTypes1(i: Short, s: String) {} +fun functionMismatchedParameterTypes2(i: Int, s: CharSequence) {} + +fun functionDefaultValues1(i: Int = 1, s: String) {} +fun functionDefaultValues2(i: Int, s: String = "hello") {} + +actual inline fun inlineFunction1(lazyMessage: () -> String) {} +actual inline fun inlineFunction2(crossinline lazyMessage: () -> String) {} +actual inline fun inlineFunction3(crossinline lazyMessage: () -> String) {} +actual inline fun inlineFunction4(noinline lazyMessage: () -> String) {} +actual inline fun inlineFunction5(noinline lazyMessage: () -> String) {} + +actual fun functionWithVararg1(vararg numbers: Int) {} +fun functionWithVararg2(numbers: Array) {} +fun functionWithVararg3(numbers: Array) {} +//fun functionWithVararg4(numbers: Array) {} +actual fun functionWithVararg5(numbers: Array) {} diff --git a/konan/commonizer/testData/functionCommonization/valueParameters/original/js/package_root.kt b/konan/commonizer/testData/functionCommonization/valueParameters/original/js/package_root.kt new file mode 100644 index 00000000000..13e6c537b73 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/valueParameters/original/js/package_root.kt @@ -0,0 +1,28 @@ +fun functionNoParameters() {} +fun functionSingleParameter(i: Int) {} +fun functionTwoParameters(i: Int, s: String) {} +fun functionThreeParameters(i: Int, s: String, l: List) {} + +fun functionMismatchedParameterCount1(i: Int, s: String) {} +fun functionMismatchedParameterCount2(i: Int, s: String, l: List) {} + +fun functionMismatchedParameterNames1(i: Int, s: String) {} +fun functionMismatchedParameterNames2(i: Int, s: String) {} + +fun functionMismatchedParameterTypes1(i: Int, s: String) {} +fun functionMismatchedParameterTypes2(i: Int, s: String) {} + +fun functionDefaultValues1(i: Int = 1, s: String) {} +fun functionDefaultValues2(i: Int, s: String = "hello") {} + +inline fun inlineFunction1(lazyMessage: () -> String) {} +inline fun inlineFunction2(lazyMessage: () -> String) {} +inline fun inlineFunction3(crossinline lazyMessage: () -> String) {} +inline fun inlineFunction4(lazyMessage: () -> String) {} +inline fun inlineFunction5(noinline lazyMessage: () -> String) {} + +fun functionWithVararg1(vararg numbers: Int) {} +fun functionWithVararg2(vararg numbers: Int) {} +fun functionWithVararg3(vararg numbers: Int) {} +//fun functionWithVararg4(numbers: Array) {} +fun functionWithVararg5(numbers: Array) {} diff --git a/konan/commonizer/testData/functionCommonization/valueParameters/original/jvm/package_root.kt b/konan/commonizer/testData/functionCommonization/valueParameters/original/jvm/package_root.kt new file mode 100644 index 00000000000..f6ac65c9287 --- /dev/null +++ b/konan/commonizer/testData/functionCommonization/valueParameters/original/jvm/package_root.kt @@ -0,0 +1,28 @@ +fun functionNoParameters() {} +fun functionSingleParameter(i: Int) {} +fun functionTwoParameters(i: Int, s: String) {} +fun functionThreeParameters(i: Int, s: String, l: List) {} + +fun functionMismatchedParameterCount1(i: Int, s: String, l: List) {} +fun functionMismatchedParameterCount2(i: Int, s: String) {} + +fun functionMismatchedParameterNames1(i1: Int, s: String) {} +fun functionMismatchedParameterNames2(i: Int, s1: String) {} + +fun functionMismatchedParameterTypes1(i: Short, s: String) {} +fun functionMismatchedParameterTypes2(i: Int, s: CharSequence) {} + +fun functionDefaultValues1(i: Int = 1, s: String) {} +fun functionDefaultValues2(i: Int, s: String = "hello") {} + +inline fun inlineFunction1(lazyMessage: () -> String) {} +inline fun inlineFunction2(crossinline lazyMessage: () -> String) {} +inline fun inlineFunction3(crossinline lazyMessage: () -> String) {} +inline fun inlineFunction4(noinline lazyMessage: () -> String) {} +inline fun inlineFunction5(noinline lazyMessage: () -> String) {} + +fun functionWithVararg1(vararg numbers: Int) {} +fun functionWithVararg2(numbers: Array) {} +fun functionWithVararg3(numbers: Array) {} +//fun functionWithVararg4(numbers: Array) {} +fun functionWithVararg5(numbers: Array) {} diff --git a/konan/commonizer/testData/propertyCommonization/annotations/commonized/common/package_root.kt b/konan/commonizer/testData/generalCommonization/annotations/commonized/common/package_root.kt similarity index 69% rename from konan/commonizer/testData/propertyCommonization/annotations/commonized/common/package_root.kt rename to konan/commonizer/testData/generalCommonization/annotations/commonized/common/package_root.kt index b381a344e29..5a1759bfba7 100644 --- a/konan/commonizer/testData/propertyCommonization/annotations/commonized/common/package_root.kt +++ b/konan/commonizer/testData/generalCommonization/annotations/commonized/common/package_root.kt @@ -1,7 +1,7 @@ expect var propertyWithoutBackingField: Double - expect val propertyWithBackingField: Double - expect val propertyWithDelegateField: Int - expect val String.propertyWithExtensionReceiver: Int + +expect fun function1(text: String): String +expect fun String.function2(): String diff --git a/konan/commonizer/testData/propertyCommonization/annotations/commonized/js/package_root.kt b/konan/commonizer/testData/generalCommonization/annotations/commonized/js/package_root.kt similarity index 78% rename from konan/commonizer/testData/propertyCommonization/annotations/commonized/js/package_root.kt rename to konan/commonizer/testData/generalCommonization/annotations/commonized/js/package_root.kt index 5582fbef945..d505eede886 100644 --- a/konan/commonizer/testData/propertyCommonization/annotations/commonized/js/package_root.kt +++ b/konan/commonizer/testData/generalCommonization/annotations/commonized/js/package_root.kt @@ -1,7 +1,6 @@ import kotlin.annotation.AnnotationTarget.* @Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER) -@Repeatable annotation class Foo(val text: String) @property:Foo("property") @@ -20,3 +19,9 @@ actual val propertyWithDelegateField: Int by lazy { 42 } actual val @receiver:Foo("receiver") String.propertyWithExtensionReceiver: Int get() = length + +@Foo("function") +actual fun function1(@Foo("parameter") text: String) = text + +@Foo("function") +actual fun @receiver:Foo("receiver") String.function2() = this diff --git a/konan/commonizer/testData/propertyCommonization/annotations/commonized/jvm/package_root.kt b/konan/commonizer/testData/generalCommonization/annotations/commonized/jvm/package_root.kt similarity index 77% rename from konan/commonizer/testData/propertyCommonization/annotations/commonized/jvm/package_root.kt rename to konan/commonizer/testData/generalCommonization/annotations/commonized/jvm/package_root.kt index f39e574fad5..7f422677aad 100644 --- a/konan/commonizer/testData/propertyCommonization/annotations/commonized/jvm/package_root.kt +++ b/konan/commonizer/testData/generalCommonization/annotations/commonized/jvm/package_root.kt @@ -1,7 +1,6 @@ import kotlin.annotation.AnnotationTarget.* @Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER) -@Repeatable annotation class Bar(val text: String) @Bar("property") @@ -17,3 +16,9 @@ actual val propertyWithDelegateField: Int by lazy { 42 } actual val @receiver:Bar("receiver") String.propertyWithExtensionReceiver: Int get() = length + +@Bar("function") +actual fun function1(@Bar("parameter") text: String) = text + +@Bar("function") +actual fun @receiver:Foo("receiver") String.function2() = this diff --git a/konan/commonizer/testData/propertyCommonization/annotations/original/js/package_root.kt b/konan/commonizer/testData/generalCommonization/annotations/original/js/package_root.kt similarity index 75% rename from konan/commonizer/testData/propertyCommonization/annotations/original/js/package_root.kt rename to konan/commonizer/testData/generalCommonization/annotations/original/js/package_root.kt index f49d1c95f9e..48a4756e78a 100644 --- a/konan/commonizer/testData/propertyCommonization/annotations/original/js/package_root.kt +++ b/konan/commonizer/testData/generalCommonization/annotations/original/js/package_root.kt @@ -1,7 +1,6 @@ import kotlin.annotation.AnnotationTarget.* -@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER) -@Repeatable +@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER, FUNCTION) annotation class Foo(val text: String) @Foo("property") @@ -17,3 +16,9 @@ val propertyWithDelegateField: Int by lazy { 42 } val @receiver:Foo("receiver") String.propertyWithExtensionReceiver: Int get() = length + +@Foo("function") +fun function1(@Foo("parameter") text: String) = text + +@Foo("function") +fun @receiver:Foo("receiver") String.function2() = this diff --git a/konan/commonizer/testData/propertyCommonization/annotations/original/jvm/package_root.kt b/konan/commonizer/testData/generalCommonization/annotations/original/jvm/package_root.kt similarity index 78% rename from konan/commonizer/testData/propertyCommonization/annotations/original/jvm/package_root.kt rename to konan/commonizer/testData/generalCommonization/annotations/original/jvm/package_root.kt index e3c8d6aa86c..c0668feb872 100644 --- a/konan/commonizer/testData/propertyCommonization/annotations/original/jvm/package_root.kt +++ b/konan/commonizer/testData/generalCommonization/annotations/original/jvm/package_root.kt @@ -1,7 +1,6 @@ import kotlin.annotation.AnnotationTarget.* @Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER) -@Repeatable annotation class Bar(val text: String) @Bar("property") @@ -17,3 +16,9 @@ val propertyWithDelegateField: Int by lazy { 42 } val @receiver:Bar("receiver") String.propertyWithExtensionReceiver: Int get() = length + +@Bar("function") +fun function1(@Bar("parameter") text: String) = text + +@Bar("function") +fun @receiver:Foo("receiver") String.function2() = this diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/common/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/common/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/common/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/common/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/common/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/common/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/common/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/common/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_org_sample.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_org_sample.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_org_sample.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_org_sample.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_org_sample_one.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_org_sample_one.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_org_sample_one.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_org_sample_one.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/js/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/js/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/jvm/package_org_sample.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/jvm/package_org_sample.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/jvm/package_org_sample.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/jvm/package_org_sample.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/jvm/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/jvm/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/jvm/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/jvm/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/jvm/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/jvm/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/jvm/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/jvm/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/native/package_org_sample_one.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/native/package_org_sample_one.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/native/package_org_sample_one.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/native/package_org_sample_one.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/native/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/native/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/native/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/native/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/native/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/native/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/commonized/native/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/commonized/native/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_org_sample.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_org_sample.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_org_sample.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_org_sample.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_org_sample_one.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_org_sample_one.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_org_sample_one.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_org_sample_one.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/js/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/js/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/jvm/package_org_sample.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/jvm/package_org_sample.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/jvm/package_org_sample.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/jvm/package_org_sample.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/jvm/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/jvm/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/jvm/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/jvm/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/jvm/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/jvm/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/jvm/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/jvm/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/native/package_org_sample_one.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/native/package_org_sample_one.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/native/package_org_sample_one.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/native/package_org_sample_one.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/native/package_org_sample_two.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/native/package_org_sample_two.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/native/package_org_sample_two.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/native/package_org_sample_two.kt diff --git a/konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/native/package_root.kt b/konan/commonizer/testData/generalCommonization/mismatchedPackages/original/native/package_root.kt similarity index 100% rename from konan/commonizer/testData/propertyCommonization/mismatchedPackages/original/native/package_root.kt rename to konan/commonizer/testData/generalCommonization/mismatchedPackages/original/native/package_root.kt diff --git a/konan/commonizer/testData/propertyCommonization/returnTypes/original/js/package_root.kt b/konan/commonizer/testData/propertyCommonization/returnTypes/original/js/package_root.kt deleted file mode 100644 index a298774f1b1..00000000000 --- a/konan/commonizer/testData/propertyCommonization/returnTypes/original/js/package_root.kt +++ /dev/null @@ -1,24 +0,0 @@ -class Planet(val name: String, val diameter: Double) - -val propertyWithInferredType1 = 1 -val propertyWithInferredType2 = "hello" -val propertyWithInferredType3 = 42.toString() -val propertyWithInferredType4 = null -val propertyWithInferredType5 = Planet("Earth", 12742) - -typealias A = Planet -typealias C = Planet - -val property1 = 1 // with inferred type -val property2 = "hello" // with inferred type -val property3 = Planet("Earth", 12742) // with inferred type -val property4 = A("Earth", 12742) // with inferred type -val property5 = A("Earth", 12742) // with inferred type -val property6 = Planet("Earth", 12742) // with inferred type -val property7 = C("Earth", 12742) // with inferred type - -val propertyWithMismatchedType1: Int = 1 -val propertyWithMismatchedType2: Int = 1 -val propertyWithMismatchedType3: Int = 1 -val propertyWithMismatchedType4: Int = 1 -val propertyWithMismatchedType5: Int = 1 diff --git a/konan/commonizer/testData/propertyCommonization/returnTypes/original/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/returnTypes/original/jvm/package_root.kt deleted file mode 100644 index 66fbea1cd6e..00000000000 --- a/konan/commonizer/testData/propertyCommonization/returnTypes/original/jvm/package_root.kt +++ /dev/null @@ -1,24 +0,0 @@ -class Planet(val name: String, val diameter: Double) - -val propertyWithInferredType1 get() = 1 -val propertyWithInferredType2 get() = "hello" -val propertyWithInferredType3 get() = 42.toString() -val propertyWithInferredType4 get() = null -val propertyWithInferredType5 get() = Planet("Earth", 12742) - -typealias B = Planet -typealias C = Planet - -val property1: Int = 1 // with explicit type -val property2: String = "hello" // with explicit type -val property3: Planet = Planet("Earth", 12742) // with explicit type -val property4: B = Planet("Earth", 12742) // with explicit type -val property5: Planet = A("Earth", 12742) // with explicit type -val property6: Planet = A("Earth", 12742) // with explicit type -val property7: C = Planet("Earth", 12742) // with explicit type - -val propertyWithMismatchedType1: Long = 1 -val propertyWithMismatchedType2: Short = 1 -val propertyWithMismatchedType3: Number = 1 -val propertyWithMismatchedType4: Comparable = 1 -val propertyWithMismatchedType5: String = 1.toString() diff --git a/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/common/package_root.kt b/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/common/package_root.kt deleted file mode 100644 index c8c63c83a95..00000000000 --- a/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/common/package_root.kt +++ /dev/null @@ -1,7 +0,0 @@ -expect val delegatedProperty1: Int -expect val delegatedProperty2: Int -expect val delegatedProperty3: Int -expect val delegatedProperty4: Int - -expect val inlineProperty1: Int -expect val inlineProperty2: Int diff --git a/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/js/package_root.kt b/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/js/package_root.kt deleted file mode 100644 index 6b5b3741f23..00000000000 --- a/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/js/package_root.kt +++ /dev/null @@ -1,13 +0,0 @@ -const val constProperty1 = 42 -const val constProperty2 = 42 - -actual val delegatedProperty1: Int by lazy { 42 } -actual val delegatedProperty2: Int by lazy { 42 } -actual val delegatedProperty3: Int by mapOf("delegatedProperty3" to 42) -actual val delegatedProperty4: Int by mapOf("delegatedProperty4" to 42) - -lateinit var lateinitProperty1: String -lateinit var lateinitProperty2: String - -actual inline val inlineProperty1 get() = 42 -actual inline val inlineProperty2 get() = 42 diff --git a/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/jvm/package_root.kt deleted file mode 100644 index 3dbb987a4c9..00000000000 --- a/konan/commonizer/testData/propertyCommonization/specificProperties/commonized/jvm/package_root.kt +++ /dev/null @@ -1,13 +0,0 @@ -const val constProperty1 = 42 -val constProperty2 = 42 // intentionally left as non-const - -actual val delegatedProperty1: Int by lazy { 42 } -actual val delegatedProperty2 = 42 // intentionally left as non-delegated -actual val delegatedProperty3: Int by mapOf("delegatedProperty3" to 42) -actual val delegatedProperty4 = 42 // intentionally left as non-delegated - -lateinit var lateinitProperty1: String -var lateinitProperty2 = "hello" // intentionally left as non-lateinit - -actual inline val inlineProperty1 get() = 42 -actual val inlineProperty2 = 42 // intentionally left as non-inline diff --git a/konan/commonizer/testData/propertyCommonization/specificProperties/original/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/specificProperties/original/jvm/package_root.kt deleted file mode 100644 index 73b646c180a..00000000000 --- a/konan/commonizer/testData/propertyCommonization/specificProperties/original/jvm/package_root.kt +++ /dev/null @@ -1,13 +0,0 @@ -const val constProperty1 = 42 -val constProperty2 = 42 // intentionally left as non-const - -val delegatedProperty1: Int by lazy { 42 } -val delegatedProperty2 = 42 // intentionally left as non-delegated -val delegatedProperty3: Int by mapOf("delegatedProperty3" to 42) -val delegatedProperty4 = 42 // intentionally left as non-delegated - -lateinit var lateinitProperty1: String -var lateinitProperty2 = "hello" // intentionally left as non-lateinit - -inline val inlineProperty1 get() = 42 -val inlineProperty2 = 42 // intentionally left as non-inline diff --git a/konan/commonizer/testData/propertyCommonization/specifics/commonized/common/package_root.kt b/konan/commonizer/testData/propertyCommonization/specifics/commonized/common/package_root.kt new file mode 100644 index 00000000000..b1d8c1961dd --- /dev/null +++ b/konan/commonizer/testData/propertyCommonization/specifics/commonized/common/package_root.kt @@ -0,0 +1,17 @@ +expect val delegatedProperty1: Int +expect val delegatedProperty2: Int +expect val delegatedProperty3: Int +expect val delegatedProperty4: Int + +expect val inlineProperty1: Int +expect val inlineProperty2: Int +expect val inlineProperty3: Int + +expect var inlineProperty4: Int +expect var inlineProperty5: Int +expect var inlineProperty6: Int +expect var inlineProperty7: Int +expect var inlineProperty8: Int + +expect external val externalProperty1: Int +expect val externalProperty2: Int diff --git a/konan/commonizer/testData/propertyCommonization/specifics/commonized/js/package_root.kt b/konan/commonizer/testData/propertyCommonization/specifics/commonized/js/package_root.kt new file mode 100644 index 00000000000..b019f9aef05 --- /dev/null +++ b/konan/commonizer/testData/propertyCommonization/specifics/commonized/js/package_root.kt @@ -0,0 +1,33 @@ +const val constProperty1 = 42 +const val constProperty2 = 42 + +actual val delegatedProperty1: Int by lazy { 42 } +actual val delegatedProperty2: Int by lazy { 42 } +actual val delegatedProperty3: Int by mapOf("delegatedProperty3" to 42) +actual val delegatedProperty4: Int by mapOf("delegatedProperty4" to 42) + +lateinit var lateinitProperty1: String +lateinit var lateinitProperty2: String + +actual inline val inlineProperty1 get() = 42 +actual inline val inlineProperty2 get() = 42 +actual inline val inlineProperty3 get() = 42 + +actual inline var inlineProperty4 + get() = 42 + set(value) = Unit +actual inline var inlineProperty5 + get() = 42 + set(value) = Unit +actual inline var inlineProperty6 + get() = 42 + set(value) = Unit +actual inline var inlineProperty7 + get() = 42 + set(value) = Unit +actual inline var inlineProperty8 + get() = 42 + set(value) = Unit + +actual external val externalProperty1: Int +actual external val externalProperty2: Int diff --git a/konan/commonizer/testData/propertyCommonization/specifics/commonized/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/specifics/commonized/jvm/package_root.kt new file mode 100644 index 00000000000..d6386a8bee3 --- /dev/null +++ b/konan/commonizer/testData/propertyCommonization/specifics/commonized/jvm/package_root.kt @@ -0,0 +1,33 @@ +const val constProperty1 = 42 +val constProperty2 = 42 // intentionally left as non-const + +actual val delegatedProperty1: Int by lazy { 42 } +actual val delegatedProperty2 = 42 // intentionally left as non-delegated +actual val delegatedProperty3: Int by mapOf("delegatedProperty3" to 42) +actual val delegatedProperty4 = 42 // intentionally left as non-delegated + +lateinit var lateinitProperty1: String +var lateinitProperty2 = "hello" // intentionally left as non-lateinit + +actual val inlineProperty1 inline get() = 42 +actual inline val inlineProperty2 get() = 42 +actual val inlineProperty3 = 42 // intentionally left as non-inline + +actual var inlineProperty4 + inline get() = 42 + inline set(value) = Unit +inline actual var inlineProperty5 + get() = 42 + set(value) = Unit +actual var inlineProperty6 + inline get() = 42 + set(value) = Unit +actual var inlineProperty7 + get() = 42 + inline set(value) = Unit +actual var inlineProperty8 + get() = 42 + set(value) = Unit + +actual external val externalProperty1: Int +actual val externalProperty2: Int = 1 diff --git a/konan/commonizer/testData/propertyCommonization/specificProperties/original/js/package_root.kt b/konan/commonizer/testData/propertyCommonization/specifics/original/js/package_root.kt similarity index 50% rename from konan/commonizer/testData/propertyCommonization/specificProperties/original/js/package_root.kt rename to konan/commonizer/testData/propertyCommonization/specifics/original/js/package_root.kt index ef7da638466..dd5947da28f 100644 --- a/konan/commonizer/testData/propertyCommonization/specificProperties/original/js/package_root.kt +++ b/konan/commonizer/testData/propertyCommonization/specifics/original/js/package_root.kt @@ -11,3 +11,23 @@ lateinit var lateinitProperty2: String inline val inlineProperty1 get() = 42 inline val inlineProperty2 get() = 42 +inline val inlineProperty3 get() = 42 + +inline var inlineProperty4 + get() = 42 + set(value) = Unit +inline var inlineProperty5 + get() = 42 + set(value) = Unit +inline var inlineProperty6 + get() = 42 + set(value) = Unit +inline var inlineProperty7 + get() = 42 + set(value) = Unit +inline var inlineProperty8 + get() = 42 + set(value) = Unit + +external val externalProperty1: Int +external val externalProperty2: Int diff --git a/konan/commonizer/testData/propertyCommonization/specifics/original/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/specifics/original/jvm/package_root.kt new file mode 100644 index 00000000000..88d1cb4b92d --- /dev/null +++ b/konan/commonizer/testData/propertyCommonization/specifics/original/jvm/package_root.kt @@ -0,0 +1,33 @@ +const val constProperty1 = 42 +val constProperty2 = 42 // intentionally left as non-const + +val delegatedProperty1: Int by lazy { 42 } +val delegatedProperty2 = 42 // intentionally left as non-delegated +val delegatedProperty3: Int by mapOf("delegatedProperty3" to 42) +val delegatedProperty4 = 42 // intentionally left as non-delegated + +lateinit var lateinitProperty1: String +var lateinitProperty2 = "hello" // intentionally left as non-lateinit + +inline val inlineProperty1 get() = 42 +val inlineProperty2 inline get() = 42 +val inlineProperty3 = 42 // intentionally left as non-inline + +inline var inlineProperty4 + get() = 42 + set(value) = Unit +var inlineProperty5 + inline get() = 42 + inline set(value) = Unit +var inlineProperty6 + inline get() = 42 + set(value) = Unit +var inlineProperty7 + get() = 42 + inline set(value) = Unit +var inlineProperty8 + get() = 42 + set(value) = Unit + +external val externalProperty1: Int +val externalProperty2: Int = 1 diff --git a/konan/commonizer/testData/propertyCommonization/visibility/commonized/common/package_root.kt b/konan/commonizer/testData/propertyCommonization/visibility/commonized/common/package_root.kt deleted file mode 100644 index 6c28487caef..00000000000 --- a/konan/commonizer/testData/propertyCommonization/visibility/commonized/common/package_root.kt +++ /dev/null @@ -1,2 +0,0 @@ -expect public val publicProperty: Int -expect internal val internalProperty: Int diff --git a/konan/commonizer/testData/propertyCommonization/visibility/commonized/js/package_root.kt b/konan/commonizer/testData/propertyCommonization/visibility/commonized/js/package_root.kt deleted file mode 100644 index 2b102527fa0..00000000000 --- a/konan/commonizer/testData/propertyCommonization/visibility/commonized/js/package_root.kt +++ /dev/null @@ -1,3 +0,0 @@ -actual public val publicProperty = 1 -actual internal val internalProperty = 1 -private val privateProperty = 1 diff --git a/konan/commonizer/testData/propertyCommonization/visibility/commonized/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/visibility/commonized/jvm/package_root.kt deleted file mode 100644 index 2b102527fa0..00000000000 --- a/konan/commonizer/testData/propertyCommonization/visibility/commonized/jvm/package_root.kt +++ /dev/null @@ -1,3 +0,0 @@ -actual public val publicProperty = 1 -actual internal val internalProperty = 1 -private val privateProperty = 1 diff --git a/konan/commonizer/testData/propertyCommonization/visibility/original/js/package_root.kt b/konan/commonizer/testData/propertyCommonization/visibility/original/js/package_root.kt deleted file mode 100644 index 698aa404820..00000000000 --- a/konan/commonizer/testData/propertyCommonization/visibility/original/js/package_root.kt +++ /dev/null @@ -1,3 +0,0 @@ -public val publicProperty = 1 -internal val internalProperty = 1 -private val privateProperty = 1 diff --git a/konan/commonizer/testData/propertyCommonization/visibility/original/jvm/package_root.kt b/konan/commonizer/testData/propertyCommonization/visibility/original/jvm/package_root.kt deleted file mode 100644 index 698aa404820..00000000000 --- a/konan/commonizer/testData/propertyCommonization/visibility/original/jvm/package_root.kt +++ /dev/null @@ -1,3 +0,0 @@ -public val publicProperty = 1 -internal val internalProperty = 1 -private val privateProperty = 1 diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt new file mode 100644 index 00000000000..975393eb4d4 --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer + +import kotlin.contracts.ExperimentalContracts + +@ExperimentalContracts +class CallableMemberCommonizationFromSourcesTest : AbstractCommonizationFromSourcesTest() { + + fun testVisibility() = doTestSuccessfulCommonization() + + fun testReturnTypes() = doTestSuccessfulCommonization() + + fun testExtensionReceivers() = doTestSuccessfulCommonization() + + // TODO: test modality (possible only inside classes) + // TODO: test virtual val/fun visibility commonization (possible only inside classes) +} diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/FunctionCommonizationFromSourcesTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/FunctionCommonizationFromSourcesTest.kt new file mode 100644 index 00000000000..2e103ad2f2f --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/FunctionCommonizationFromSourcesTest.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer + +import kotlin.contracts.ExperimentalContracts + +@ExperimentalContracts +class FunctionCommonizationFromSourcesTest : AbstractCommonizationFromSourcesTest() { + + fun testValueParameters() = doTestSuccessfulCommonization() + + fun testSpecifics() = doTestSuccessfulCommonization() +} diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/GeneralCommonizationFromSourcesTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/GeneralCommonizationFromSourcesTest.kt new file mode 100644 index 00000000000..ef4df165345 --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/GeneralCommonizationFromSourcesTest.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer + +import kotlin.contracts.ExperimentalContracts + +@ExperimentalContracts +class GeneralCommonizationFromSourcesTest : AbstractCommonizationFromSourcesTest() { + + fun testMismatchedPackages() = doTestSuccessfulCommonization() + + fun testAnnotations() = doTestSuccessfulCommonization() +} diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/PropertyCommonizationFromSourcesTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/PropertyCommonizationFromSourcesTest.kt index c348632bcf2..d7a995115fd 100644 --- a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/PropertyCommonizationFromSourcesTest.kt +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/PropertyCommonizationFromSourcesTest.kt @@ -10,21 +10,7 @@ import kotlin.contracts.ExperimentalContracts @ExperimentalContracts class PropertyCommonizationFromSourcesTest : AbstractCommonizationFromSourcesTest() { - fun testMismatchedPackages() = doTestSuccessfulCommonization() - - fun testReturnTypes() = doTestSuccessfulCommonization() - - fun testVisibility() = doTestSuccessfulCommonization() - - fun testSpecificProperties() = doTestSuccessfulCommonization() - - fun testExtensionReceivers() = doTestSuccessfulCommonization() + fun testSpecifics() = doTestSuccessfulCommonization() fun testSetters() = doTestSuccessfulCommonization() - - fun testAnnotations() = doTestSuccessfulCommonization() - - // TODO: test modality (possible only inside classes) - // TODO: test virtual val visibility commonization (possible only inside classes) - } diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/assertions.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/assertions.kt index 693860e7957..1d3adf7bac0 100644 --- a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/assertions.kt +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/assertions.kt @@ -8,9 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer import junit.framework.TestCase.fail import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.PropertyKey -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.collectNonEmptyPackageMemberScopes -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.collectProperties +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -92,12 +90,6 @@ private class ComparingDeclarationsVisitor( } } - override fun visitPackageViewDescriptor(expected: PackageViewDescriptor, context: Context) = - fail("Comparison of package views not supported") - - override fun visitPackageFragmentDescriptor(expected: PackageFragmentDescriptor, context: Context) = - fail("Comparison of package fragments not supported") - fun visitMemberScopes(expected: MemberScope, actual: MemberScope, context: Context) { fun collectProperties(memberScope: MemberScope): Map = mutableMapOf().also { @@ -116,15 +108,78 @@ private class ComparingDeclarationsVisitor( expectedProperty.accept(this, context.nextLevel(actualProperty)) } - // FIXME: traverse the rest - functions, classes, typealiases + fun collectFunctions(memberScope: MemberScope): Map = + mutableMapOf().also { + memberScope.collectFunctions { functionKey, function -> + it[functionKey] = function + } + } + + val expectedFunctions = collectFunctions(expected) + val actualFunctions = collectFunctions(actual) + + context.assertEquals(expectedFunctions.keys, actualFunctions.keys, "sets of functions") + + expectedFunctions.forEach { (functionKey, expectedFunction) -> + val actualFunction = actualFunctions.getValue(functionKey) + expectedFunction.accept(this, context.nextLevel(actualFunction)) + } + + // FIXME: traverse the rest - classes, typealiases } - override fun visitVariableDescriptor(expected: VariableDescriptor, context: Context) { - TODO("not implemented") - } override fun visitFunctionDescriptor(expected: FunctionDescriptor, context: Context) { - TODO("not implemented") + @Suppress("NAME_SHADOWING") + val expected = expected as SimpleFunctionDescriptor + val actual = context.getActualAs() + + visitAnnotations(expected.annotations, actual.annotations, context.nextLevel("Function annotations")) + context.assertFieldsEqual(expected::getName, actual::getName) + context.assertFieldsEqual(expected::getVisibility, actual::getVisibility) + context.assertFieldsEqual(expected::getModality, actual::getModality) + context.assertFieldsEqual(expected::getKind, actual::getKind) + context.assertFieldsEqual(expected::isOperator, actual::isOperator) + context.assertFieldsEqual(expected::isInfix, actual::isInfix) + context.assertFieldsEqual(expected::isInline, actual::isInline) + context.assertFieldsEqual(expected::isTailrec, actual::isTailrec) + context.assertFieldsEqual(expected::isSuspend, actual::isSuspend) + context.assertFieldsEqual(expected::isExternal, actual::isExternal) + context.assertFieldsEqual(expected::isExpect, actual::isExpect) + context.assertFieldsEqual(expected::isActual, actual::isActual) + + visitType(expected.returnType, actual.returnType, context.nextLevel("Function type")) + + visitValueParameterDescriptorList(expected.valueParameters, actual.valueParameters, context.nextLevel("Function value parameters")) + + visitReceiverParameterDescriptor(expected.extensionReceiverParameter, context.nextLevel(actual.extensionReceiverParameter)) + visitReceiverParameterDescriptor(expected.dispatchReceiverParameter, context.nextLevel(actual.dispatchReceiverParameter)) + } + + fun visitValueParameterDescriptorList( + expected: List, + actual: List, + context: Context + ) { + context.assertEquals(expected.size, actual.size, "Size of value parameters list") + + expected.forEachIndexed { index, expectedParam -> + val actualParam = actual[index] + expectedParam.accept(this, context.nextLevel(actualParam)) + } + } + + override fun visitValueParameterDescriptor(expected: ValueParameterDescriptor, context: Context) { + val actual = context.getActualAs() + + visitAnnotations(expected.annotations, actual.annotations, context.nextLevel("Value parameter annotations")) + context.assertEquals(expected.name, actual.name, "Name") + context.assertEquals(expected.index, actual.index, "Index") + context.assertEquals(expected.declaresDefaultValue(), actual.declaresDefaultValue(), "Declares default value") + context.assertEquals(expected.isCrossinline, actual.isCrossinline, "Crossinline") + context.assertEquals(expected.isNoinline, actual.isNoinline, "Noinline") + visitType(expected.type, actual.type, context.nextLevel("Value parameter type")) + visitType(expected.varargElementType, actual.varargElementType, context.nextLevel("Value parameter vararg element type")) } override fun visitTypeParameterDescriptor(expected: TypeParameterDescriptor, context: Context) { @@ -135,11 +190,11 @@ private class ComparingDeclarationsVisitor( TODO("not implemented") } - override fun visitTypeAliasDescriptor(expected: TypeAliasDescriptor, context: Context) { + override fun visitConstructorDescriptor(expected: ConstructorDescriptor, context: Context) { TODO("not implemented") } - override fun visitConstructorDescriptor(expected: ConstructorDescriptor, context: Context) { + override fun visitTypeAliasDescriptor(expected: TypeAliasDescriptor, context: Context) { TODO("not implemented") } @@ -157,6 +212,7 @@ private class ComparingDeclarationsVisitor( context.assertFieldsEqual(expected::isExternal, actual::isExternal) context.assertFieldsEqual(expected::isExpect, actual::isExpect) context.assertFieldsEqual(expected::isActual, actual::isActual) + @Suppress("DEPRECATION") context.assertFieldsEqual(expected::isDelegated, actual::isDelegated) visitAnnotations( expected.delegateField?.annotations, @@ -168,7 +224,7 @@ private class ComparingDeclarationsVisitor( actual.backingField?.annotations, context.nextLevel("Property backing field annotations") ) - context.assertEquals(expected.compileTimeInitializer != null, actual.compileTimeInitializer != null, "compile-time initializers") + context.assertEquals(expected.compileTimeInitializer.isNull(), actual.compileTimeInitializer.isNull(), "compile-time initializers") visitType(expected.type, actual.type, context.nextLevel("Property type")) visitPropertyGetterDescriptor(expected.getter, context.nextLevel(actual.getter)) @@ -178,10 +234,6 @@ private class ComparingDeclarationsVisitor( visitReceiverParameterDescriptor(expected.dispatchReceiverParameter, context.nextLevel(actual.dispatchReceiverParameter)) } - override fun visitValueParameterDescriptor(expected: ValueParameterDescriptor, context: Context) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - override fun visitPropertyGetterDescriptor(expected: PropertyGetterDescriptor?, context: Context) { val actual = context.getActualAs() if (expected === actual) return @@ -222,8 +274,6 @@ private class ComparingDeclarationsVisitor( visitAnnotations(expected.annotations, actual.annotations, context.nextLevel("Receiver parameter annotations")) } - override fun visitScriptDescriptor(expected: ScriptDescriptor, context: Context) = - fail("Comparison of script descriptors not supported") private fun visitAnnotations(expected: Annotations?, actual: Annotations?, context: Context) { if (expected === actual) return @@ -234,9 +284,11 @@ private class ComparingDeclarationsVisitor( context.assertEquals(expectedAnnotationFqNames, actualAnnotationFqNames, "annotations") } - private fun visitType(expected: KotlinType, actual: KotlinType, context: Context) { + private fun visitType(expected: KotlinType?, actual: KotlinType?, context: Context) { if (expected === actual) return + check(actual != null && expected != null) + val expectedUnwrapped = expected.unwrap() val actualUnwrapped = actual.unwrap() @@ -265,4 +317,16 @@ private class ComparingDeclarationsVisitor( assertEquals(expectedValue, actualValue, "fields \"$expected\"") } + + override fun visitPackageViewDescriptor(expected: PackageViewDescriptor, context: Context) = + fail("Comparison of package views not supported") + + override fun visitPackageFragmentDescriptor(expected: PackageFragmentDescriptor, context: Context) = + fail("Comparison of package fragments not supported") + + override fun visitScriptDescriptor(expected: ScriptDescriptor, context: Context) = + fail("Comparison of script descriptors not supported") + + override fun visitVariableDescriptor(expected: VariableDescriptor, context: Context) = + fail("Comparison of variables not supported") } diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultFunctionModifiersCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultFunctionModifiersCommonizerTest.kt new file mode 100644 index 00000000000..68b969faffa --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultFunctionModifiersCommonizerTest.kt @@ -0,0 +1,181 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.TestFunctionModifiers +import org.jetbrains.kotlin.descriptors.commonizer.TestFunctionModifiers.Companion.areEqual +import org.jetbrains.kotlin.descriptors.commonizer.ir.FunctionModifiers +import org.jetbrains.kotlin.descriptors.commonizer.mockClassType +import org.jetbrains.kotlin.descriptors.commonizer.mockFunction +import org.jetbrains.kotlin.types.refinement.TypeRefinement +import org.junit.Test + +@TypeRefinement +class DefaultFunctionModifiersCommonizerTest : AbstractCommonizerTest() { + + @Test + fun allDefault() = doTestSuccess( + create(), + create().toMockFunction(), + create().toMockFunction(), + create().toMockFunction() + ) + + @Test + fun allSuspend() = doTestSuccess( + create(isSuspend = true), + create(isSuspend = true).toMockFunction(), + create(isSuspend = true).toMockFunction(), + create(isSuspend = true).toMockFunction() + ) + + @Test(expected = IllegalStateException::class) + fun suspendAndNotSuspend() = doTestFailure( + create(isSuspend = true).toMockFunction(), + create(isSuspend = true).toMockFunction(), + create().toMockFunction() + ) + + @Test(expected = IllegalStateException::class) + fun notSuspendAndSuspend() = doTestFailure( + create().toMockFunction(), + create().toMockFunction(), + create(isSuspend = true).toMockFunction() + ) + + @Test + fun allOperator() = doTestSuccess( + create(isOperator = true), + create(isOperator = true).toMockFunction(), + create(isOperator = true).toMockFunction(), + create(isOperator = true).toMockFunction() + ) + + @Test + fun notOperatorAndOperator() = doTestSuccess( + create(), + create().toMockFunction(), + create(isOperator = true).toMockFunction(), + create(isOperator = true).toMockFunction() + ) + + @Test + fun operatorAndNotOperator() = doTestSuccess( + create(), + create(isOperator = true).toMockFunction(), + create(isOperator = true).toMockFunction(), + create().toMockFunction() + ) + + @Test + fun allInfix() = doTestSuccess( + create(isInfix = true), + create(isInfix = true).toMockFunction(), + create(isInfix = true).toMockFunction(), + create(isInfix = true).toMockFunction() + ) + + @Test + fun notInfixAndInfix() = doTestSuccess( + create(), + create().toMockFunction(), + create(isInfix = true).toMockFunction(), + create(isInfix = true).toMockFunction() + ) + + @Test + fun infixAndNotInfix() = doTestSuccess( + create(), + create(isInfix = true).toMockFunction(), + create(isInfix = true).toMockFunction(), + create().toMockFunction() + ) + + @Test + fun allInline() = doTestSuccess( + create(isInline = true), + create(isInline = true).toMockFunction(), + create(isInline = true).toMockFunction(), + create(isInline = true).toMockFunction() + ) + + @Test + fun notInlineAndInline() = doTestSuccess( + create(), + create().toMockFunction(), + create(isInline = true).toMockFunction(), + create(isInline = true).toMockFunction() + ) + + @Test + fun inlineAndNotInline() = doTestSuccess( + create(), + create(isInline = true).toMockFunction(), + create(isInline = true).toMockFunction(), + create().toMockFunction() + ) + + @Test + fun allTailrec() = doTestSuccess( + create(isTailrec = true), + create(isTailrec = true).toMockFunction(), + create(isTailrec = true).toMockFunction(), + create(isTailrec = true).toMockFunction() + ) + + @Test + fun notTailrecAndTailrec() = doTestSuccess( + create(), + create().toMockFunction(), + create(isTailrec = true).toMockFunction(), + create(isTailrec = true).toMockFunction() + ) + + @Test + fun tailrecAndNotTailrec() = doTestSuccess( + create(), + create(isTailrec = true).toMockFunction(), + create(isTailrec = true).toMockFunction(), + create().toMockFunction() + ) + + @Test + fun allExternal() = doTestSuccess( + create(isExternal = true), + create(isExternal = true).toMockFunction(), + create(isExternal = true).toMockFunction(), + create(isExternal = true).toMockFunction() + ) + + @Test + fun notExternalAndExternal() = doTestSuccess( + create(), + create().toMockFunction(), + create(isExternal = true).toMockFunction(), + create(isExternal = true).toMockFunction() + ) + + @Test + fun externalAndNotExternal() = doTestSuccess( + create(), + create(isExternal = true).toMockFunction(), + create(isExternal = true).toMockFunction(), + create().toMockFunction() + ) + + override fun createCommonizer() = FunctionModifiersCommonizer.default() + override fun isEqual(a: FunctionModifiers?, b: FunctionModifiers?) = (a === b) || (a != null && b != null && areEqual(a, b)) +} + +private typealias create = TestFunctionModifiers + +@TypeRefinement +private fun TestFunctionModifiers.toMockFunction() = mockFunction( + name = "myFunction", + returnType = mockClassType("kotlin.String"), + modifiers = this +) diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultPropertySetterCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultPropertySetterCommonizerTest.kt index a451fd53e24..3fe699ee9e6 100644 --- a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultPropertySetterCommonizerTest.kt +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultPropertySetterCommonizerTest.kt @@ -78,5 +78,5 @@ private fun Visibility.toMockProperty() = mockProperty( name = "myProperty", setterVisibility = this, extensionReceiverType = null, - returnType = mockClassType("kotlin.String").unwrap() + returnType = mockClassType("kotlin.String") ).setter!! diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultValueParameterCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultValueParameterCommonizerTest.kt new file mode 100644 index 00000000000..0091eac7272 --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultValueParameterCommonizerTest.kt @@ -0,0 +1,176 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.CommonValueParameter +import org.jetbrains.kotlin.descriptors.commonizer.ir.ValueParameter +import org.jetbrains.kotlin.descriptors.commonizer.mockClassType +import org.jetbrains.kotlin.descriptors.commonizer.mockValueParameter +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.refinement.TypeRefinement +import org.junit.Test + +@TypeRefinement +class DefaultValueParameterCommonizerTest : AbstractCommonizerTest() { + + @Test + fun sameReturnType1() = doTestSuccess( + create("kotlin.String"), + create("kotlin.String").toMockParam(), + create("kotlin.String").toMockParam(), + create("kotlin.String").toMockParam() + ) + + @Test + fun sameReturnType2() = doTestSuccess( + create("org.sample.Foo"), + create("org.sample.Foo").toMockParam(), + create("org.sample.Foo").toMockParam(), + create("org.sample.Foo").toMockParam() + ) + + @Test(expected = IllegalStateException::class) + fun differentReturnTypes1() = doTestFailure( + create("kotlin.String").toMockParam(), + create("kotlin.String").toMockParam(), + create("kotlin.Int").toMockParam() + ) + + @Test(expected = IllegalStateException::class) + fun differentReturnTypes2() = doTestFailure( + create("kotlin.String").toMockParam(), + create("kotlin.String").toMockParam(), + create("org.sample.Foo").toMockParam() + ) + + @Test(expected = IllegalStateException::class) + fun differentReturnTypes3() = doTestFailure( + create("org.sample.Foo").toMockParam(), + create("org.sample.Foo").toMockParam(), + create("org.sample.Bar").toMockParam() + ) + + @Test + fun allHaveVararg1() = doTestSuccess( + create("kotlin.String", hasVarargElementType = true), + create("kotlin.String", hasVarargElementType = true).toMockParam(), + create("kotlin.String", hasVarargElementType = true).toMockParam(), + create("kotlin.String", hasVarargElementType = true).toMockParam() + ) + + @Test + fun allHaveVararg2() = doTestSuccess( + create("org.sample.Foo", hasVarargElementType = true), + create("org.sample.Foo", hasVarargElementType = true).toMockParam(), + create("org.sample.Foo", hasVarargElementType = true).toMockParam(), + create("org.sample.Foo", hasVarargElementType = true).toMockParam() + ) + + @Test(expected = IllegalStateException::class) + fun someDoesNotHaveVararg1() = doTestFailure( + create("kotlin.String", hasVarargElementType = true).toMockParam(), + create("kotlin.String", hasVarargElementType = true).toMockParam(), + create("kotlin.String", hasVarargElementType = false).toMockParam() + ) + + @Test(expected = IllegalStateException::class) + fun someDoesNotHaveVararg2() = doTestFailure( + create("org.sample.Foo", hasVarargElementType = false).toMockParam(), + create("org.sample.Foo", hasVarargElementType = false).toMockParam(), + create("org.sample.Foo", hasVarargElementType = true).toMockParam() + ) + + @Test + fun allHaveCrossinline() = doTestSuccess( + create("kotlin.String", isCrossinline = true), + create("kotlin.String", isCrossinline = true).toMockParam(), + create("kotlin.String", isCrossinline = true).toMockParam(), + create("kotlin.String", isCrossinline = true).toMockParam() + ) + + @Test + fun someHaveCrossinline1() = doTestSuccess( + create("kotlin.String", isCrossinline = false), + create("kotlin.String", isCrossinline = true).toMockParam(), + create("kotlin.String", isCrossinline = true).toMockParam(), + create("kotlin.String", isCrossinline = false).toMockParam() + ) + + @Test + fun someHaveCrossinline2() = doTestSuccess( + create("kotlin.String", isCrossinline = false), + create("kotlin.String", isCrossinline = false).toMockParam(), + create("kotlin.String", isCrossinline = true).toMockParam(), + create("kotlin.String", isCrossinline = true).toMockParam() + ) + + @Test + fun allHaveNoinline() = doTestSuccess( + create("kotlin.String", isNoinline = true), + create("kotlin.String", isNoinline = true).toMockParam(), + create("kotlin.String", isNoinline = true).toMockParam(), + create("kotlin.String", isNoinline = true).toMockParam() + ) + + @Test + fun someHaveNoinline1() = doTestSuccess( + create("kotlin.String", isNoinline = false), + create("kotlin.String", isNoinline = true).toMockParam(), + create("kotlin.String", isNoinline = true).toMockParam(), + create("kotlin.String", isNoinline = false).toMockParam() + ) + + @Test + fun someHaveNoinline2() = doTestSuccess( + create("kotlin.String", isNoinline = false), + create("kotlin.String", isNoinline = false).toMockParam(), + create("kotlin.String", isNoinline = true).toMockParam(), + create("kotlin.String", isNoinline = true).toMockParam() + ) + + @Test(expected = IllegalStateException::class) + fun anyDeclaresDefaultValue() = doTestFailure( + create("kotlin.String").toMockParam(declaresDefaultValue = false), + create("kotlin.String").toMockParam(declaresDefaultValue = false), + create("kotlin.String").toMockParam(declaresDefaultValue = true) + ) + + override fun createCommonizer() = ValueParameterCommonizer.default() + + companion object { + internal fun create( + returnTypeFqName: String, + name: String = "myParameter", + hasVarargElementType: Boolean = false, + isCrossinline: Boolean = false, + isNoinline: Boolean = false + ): ValueParameter { + val returnType = mockClassType(returnTypeFqName).unwrap() + + return CommonValueParameter( + name = Name.identifier(name), + returnType = returnType, + varargElementType = returnType.takeIf { hasVarargElementType }, // the vararg type itself does not matter here, only it's presence matters + isCrossinline = isCrossinline, + isNoinline = isNoinline + ) + } + + internal fun ValueParameter.toMockParam( + index: Int = 0, + declaresDefaultValue: Boolean = false + ): ValueParameterDescriptor = mockValueParameter( + name = name.asString(), + index = index, + returnType = returnType, + varargElementType = varargElementType, + declaresDefaultValue = declaresDefaultValue, + isCrossinline = isCrossinline, + isNoinline = isNoinline + ) + } +} diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultValueParameterListCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultValueParameterListCommonizerTest.kt new file mode 100644 index 00000000000..33c1f4c387d --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultValueParameterListCommonizerTest.kt @@ -0,0 +1,185 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.ir.ValueParameter +import org.jetbrains.kotlin.types.refinement.TypeRefinement +import org.junit.Test + +@TypeRefinement +class DefaultValueParameterListCommonizerTest : AbstractCommonizerTest, List>() { + + @Test + fun emptyValueParameters() = doTestSuccess( + emptyList(), + emptyList(), + emptyList(), + emptyList() + ) + + @Test + fun matchedParameters() = doTestSuccess( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams() + ) + + @Test(expected = IllegalStateException::class) + fun mismatchedParameterListSize1() = doTestFailure( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + emptyList() + ) + + @Test(expected = IllegalStateException::class) + fun mismatchedParameterListSize2() = doTestFailure( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int" + ).toMockParams() + ) + + @Test(expected = IllegalStateException::class) + fun mismatchedParameterListSize3() = doTestFailure( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo", + "d" to "org.sample.Bar" + ).toMockParams() + ) + + @Test(expected = IllegalStateException::class) + fun mismatchedParameterNames1() = doTestFailure( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a1" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams() + ) + + @Test(expected = IllegalStateException::class) + fun mismatchedParameterNames2() = doTestFailure( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c1" to "org.sample.Foo" + ).toMockParams() + ) + + @Test(expected = IllegalStateException::class) + fun mismatchedParameterTypes() = doTestFailure( + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.String", + "b" to "kotlin.Int", + "c" to "org.sample.Foo" + ).toMockParams(), + create( + "a" to "kotlin.Int", + "b" to "kotlin.String", + "c" to "org.sample.Bar" + ).toMockParams() + ) + + override fun createCommonizer() = ValueParameterListCommonizer.default() + + companion object { + fun create(vararg params: Pair): List { + check(params.isNotEmpty()) + return params.map { (name, returnTypeFqName) -> + DefaultValueParameterCommonizerTest.create( + name = name, + returnTypeFqName = returnTypeFqName + ) + } + } + + fun List.toMockParams() = DefaultValueParameterCommonizerTest.run { + mapIndexed { index, param -> param.toMockParam(index) } + } + } +} diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/mocks.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/mocks.kt index d584f2aeac8..ec626d7b777 100644 --- a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/mocks.kt +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/mocks.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.commonizer.ir.FunctionModifiers import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -179,6 +180,93 @@ internal fun mockProperty( return propertyDescriptor } +internal data class TestFunctionModifiers( + override val isOperator: Boolean = false, + override val isInfix: Boolean = false, + override val isInline: Boolean = false, + override val isTailrec: Boolean = false, + override val isSuspend: Boolean = false, + override val isExternal: Boolean = false +) : FunctionModifiers { + companion object { + fun areEqual(a: FunctionModifiers, b: FunctionModifiers) = + a.isOperator == b.isOperator && a.isInfix == b.isInfix && a.isInline == b.isInline + && a.isTailrec == b.isTailrec && a.isSuspend == b.isSuspend && a.isExternal == b.isExternal + } +} + +internal fun mockFunction( + name: String, + returnType: KotlinType, + modifiers: FunctionModifiers +): SimpleFunctionDescriptor { + val functionName = Name.identifier(name) + + val containingDeclaration = object : DeclarationDescriptorImpl(Annotations.EMPTY, Name.special("")) { + override fun getContainingDeclaration() = error("not supported") + override fun accept(visitor: DeclarationDescriptorVisitor?, data: D) = error("not supported") + } + + val functionDescriptor = SimpleFunctionDescriptorImpl.create( + /*containingDeclaration =*/ containingDeclaration, + /*annotations =*/ Annotations.EMPTY, + /*name =*/ functionName, + /*kind =*/ CallableMemberDescriptor.Kind.DECLARATION, + /*source =*/ SourceElement.NO_SOURCE + ) + + functionDescriptor.isOperator = modifiers.isOperator + functionDescriptor.isInfix = modifiers.isInfix + functionDescriptor.isInline = modifiers.isInline + functionDescriptor.isTailrec = modifiers.isTailrec + functionDescriptor.isSuspend = modifiers.isSuspend + functionDescriptor.isExternal = modifiers.isExternal + + val dispatchReceiverDescriptor = DescriptorUtils.getDispatchReceiverParameterIfNeeded(containingDeclaration) + + functionDescriptor.initialize( + /*extensionReceiverParameter =*/ null, + /*dispatchReceiverDescriptor =*/ dispatchReceiverDescriptor, + /*typeParameters =*/ emptyList(), + /*unsubstitutedValueParameters =*/ emptyList(), + /*returnType =*/ returnType, + /*modality =*/ Modality.FINAL, + /*visibility =*/ Visibilities.PUBLIC + ) + + return functionDescriptor +} + +internal fun mockValueParameter( + containingDeclaration: CallableDescriptor? = null, + name: String, + index: Int, + returnType: KotlinType, + varargElementType: KotlinType?, + declaresDefaultValue: Boolean, + isCrossinline: Boolean, + isNoinline: Boolean +): ValueParameterDescriptor { + check(index >= 0) + + val effectiveContainingDeclaration = containingDeclaration + ?: mockFunction("fakeFunction", returnType, TestFunctionModifiers()) // use fake function if no real containing declaration specified + + return ValueParameterDescriptorImpl( + containingDeclaration = effectiveContainingDeclaration, + original = null, + index = index, + annotations = Annotations.EMPTY, + name = Name.identifier(name), + outType = returnType, + declaresDefaultValue = declaresDefaultValue, + isCrossinline = isCrossinline, + isNoinline = isNoinline, + varargElementType = varargElementType, + source = SourceElement.NO_SOURCE + ) +} + //private fun mockTypeParameterType( // name: String, // containingDeclaration: DeclarationDescriptor,