[Commonizer] Function descriptors, function descriptor tests
This commit is contained in:
+12
-5
@@ -6,10 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.builder
|
package org.jetbrains.kotlin.descriptors.commonizer.builder
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
|
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.TargetId
|
import org.jetbrains.kotlin.descriptors.commonizer.TargetId
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
|
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
|
||||||
@@ -86,6 +83,9 @@ internal class DeclarationsBuilderVisitor(
|
|||||||
for (propertyNode in node.properties) {
|
for (propertyNode in node.properties) {
|
||||||
packageMemberScopes += propertyNode.accept(this, packageFragments)
|
packageMemberScopes += propertyNode.accept(this, packageFragments)
|
||||||
}
|
}
|
||||||
|
for (functionNode in node.functions) {
|
||||||
|
packageMemberScopes += functionNode.accept(this, packageFragments)
|
||||||
|
}
|
||||||
|
|
||||||
// initialize package fragments:
|
// initialize package fragments:
|
||||||
packageFragments.forEachIndexed { index, packageFragment ->
|
packageFragments.forEachIndexed { index, packageFragment ->
|
||||||
@@ -101,7 +101,14 @@ internal class DeclarationsBuilderVisitor(
|
|||||||
|
|
||||||
return propertyDescriptorsGroup.toList()
|
return propertyDescriptorsGroup.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitFunctionNode(node: FunctionNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
|
||||||
|
val functionDescriptorsGroup = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
|
||||||
|
node.buildDescriptors(functionDescriptorsGroup, data)
|
||||||
|
|
||||||
|
return functionDescriptorsGroup.toList()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
inline fun <reified T : DeclarationDescriptor> noContainingDeclarations() = emptyList<T?>()
|
inline fun <reified T : DeclarationDescriptor> noContainingDeclarations() = emptyList<T?>()
|
||||||
inline fun <reified T : DeclarationDescriptor> noReturningDeclarations() = emptyList<T?>()
|
inline fun <reified T : DeclarationDescriptor> noReturningDeclarations() = emptyList<T?>()
|
||||||
|
|||||||
+99
@@ -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<SimpleFunctionDescriptor>,
|
||||||
|
containingDeclarations: List<DeclarationDescriptor?>
|
||||||
|
) {
|
||||||
|
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<SimpleFunctionDescriptor>,
|
||||||
|
index: Int,
|
||||||
|
containingDeclarations: List<DeclarationDescriptor?>,
|
||||||
|
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<ValueParameter>.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
|
||||||
|
)
|
||||||
|
}
|
||||||
+1
-1
@@ -69,7 +69,7 @@ private fun Property.buildDescriptor(
|
|||||||
val dispatchReceiverDescriptor = DescriptorUtils.getDispatchReceiverParameterIfNeeded(containingDeclaration)
|
val dispatchReceiverDescriptor = DescriptorUtils.getDispatchReceiverParameterIfNeeded(containingDeclaration)
|
||||||
|
|
||||||
propertyDescriptor.setType(
|
propertyDescriptor.setType(
|
||||||
type,
|
returnType,
|
||||||
emptyList(), // TODO: support type parameters
|
emptyList(), // TODO: support type parameters
|
||||||
dispatchReceiverDescriptor,
|
dispatchReceiverDescriptor,
|
||||||
extensionReceiverDescriptor
|
extensionReceiverDescriptor
|
||||||
|
|||||||
+49
@@ -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<T : CallableMemberDescriptor, R: CallableMember> : Commonizer<T, R> {
|
||||||
|
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
|
||||||
|
}
|
||||||
+39
@@ -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<SimpleFunctionDescriptor, Function>() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -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<SimpleFunctionDescriptor, FunctionModifiers> {
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+43
@@ -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<T : Named, R>(
|
||||||
|
private val subject: String,
|
||||||
|
private val wrappedCommonizerFactory: () -> Commonizer<T, R>
|
||||||
|
) : Commonizer<List<T>, List<R>> {
|
||||||
|
private var wrapped: List<Pair<Name, Commonizer<T, R>>>? = null
|
||||||
|
private var error = false
|
||||||
|
|
||||||
|
final override val result: List<R>
|
||||||
|
get() = wrapped?.takeIf { !error }?.map { it.second.result } ?: error("Can't commonize list of $subject")
|
||||||
|
|
||||||
|
final override fun commonizeWith(next: List<T>): 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
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
@@ -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<T : Any, R : Any, WT, WR>(
|
||||||
|
private val subject: String,
|
||||||
|
private val wrappedCommonizerFactory: () -> Commonizer<WT, WR>,
|
||||||
|
private val extractor: (T) -> WT,
|
||||||
|
private val builder: (WR) -> R
|
||||||
|
) : Commonizer<T?, R?> {
|
||||||
|
private enum class State {
|
||||||
|
EMPTY,
|
||||||
|
ERROR,
|
||||||
|
WITH_WRAPPED,
|
||||||
|
WITHOUT_WRAPPED
|
||||||
|
}
|
||||||
|
|
||||||
|
private var state = State.EMPTY
|
||||||
|
private var wrapped: Commonizer<WT, WR>? = 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
|
||||||
|
}
|
||||||
+16
-41
@@ -7,64 +7,39 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ir.CommonProperty
|
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.descriptors.commonizer.ir.Property
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
class PropertyCommonizer : Commonizer<PropertyDescriptor, Property> {
|
class PropertyCommonizer : CallableMemberCommonizer<PropertyDescriptor, Property>() {
|
||||||
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()
|
|
||||||
private val setter = PropertySetterCommonizer.default()
|
private val setter = PropertySetterCommonizer.default()
|
||||||
private val extensionReceiver = ExtensionReceiverCommonizer.default()
|
private var isExternal = true
|
||||||
|
|
||||||
private var state = State.EMPTY
|
|
||||||
|
|
||||||
override val result: Property
|
override val result: Property
|
||||||
get() = when (state) {
|
get() = when (state) {
|
||||||
State.EMPTY, State.ERROR -> error("Can't commonize property")
|
State.EMPTY, State.ERROR -> error("Can't commonize property")
|
||||||
State.IN_PROGRESS -> CommonProperty(
|
State.IN_PROGRESS -> CommonProperty(
|
||||||
name = name!!,
|
name = name!!,
|
||||||
visibility = visibility.result,
|
|
||||||
modality = modality.result,
|
modality = modality.result,
|
||||||
type = returnType.result,
|
visibility = visibility.result,
|
||||||
setter = setter.result,
|
isExternal = isExternal,
|
||||||
extensionReceiver = extensionReceiver.result?.let { ExtensionReceiver.createNoAnnotations(it) }
|
extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(),
|
||||||
|
returnType = returnType.result,
|
||||||
|
setter = setter.result
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun commonizeWith(next: PropertyDescriptor): Boolean {
|
override fun canBeCommonized(next: PropertyDescriptor) = when {
|
||||||
if (state == State.ERROR)
|
next.isConst -> false // expect property can't be const because expect can't have initializer
|
||||||
return false
|
next.isLateInit -> false // expect property can't be lateinit
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
|
||||||
if (name == null)
|
override fun commonizeSpecifics(next: PropertyDescriptor): Boolean {
|
||||||
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)
|
|
||||||
|
|
||||||
// TODO: type parameters (for properties???)
|
// TODO: type parameters (for properties???)
|
||||||
|
|
||||||
state = if (!result) State.ERROR else State.IN_PROGRESS
|
isExternal = isExternal && next.isExternal
|
||||||
|
|
||||||
return result
|
return setter.commonizeWith(next.setter)
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-35
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.core
|
package org.jetbrains.kotlin.descriptors.commonizer.core
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ir.Setter
|
import org.jetbrains.kotlin.descriptors.commonizer.ir.Setter
|
||||||
|
|
||||||
interface PropertySetterCommonizer : Commonizer<PropertySetterDescriptor?, Setter?> {
|
interface PropertySetterCommonizer : Commonizer<PropertySetterDescriptor?, Setter?> {
|
||||||
@@ -14,38 +15,11 @@ interface PropertySetterCommonizer : Commonizer<PropertySetterDescriptor?, Sette
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DefaultPropertySetterCommonizer : PropertySetterCommonizer {
|
private class DefaultPropertySetterCommonizer :
|
||||||
private enum class State {
|
PropertySetterCommonizer,
|
||||||
EMPTY,
|
NullableWrappedCommonizer<PropertySetterDescriptor, Setter, Visibility, Visibility>(
|
||||||
ERROR,
|
subject = "Property",
|
||||||
WITH_SETTER,
|
wrappedCommonizerFactory = { VisibilityCommonizer.equalizing() },
|
||||||
WITHOUT_SETTER
|
extractor = { it.visibility },
|
||||||
}
|
builder = { Setter.createDefaultNoAnnotations(it) }
|
||||||
|
)
|
||||||
private var state = State.EMPTY
|
|
||||||
private var setterVisibility: VisibilityCommonizer? = null
|
|
||||||
|
|
||||||
override val result: Setter?
|
|
||||||
get() = when (state) {
|
|
||||||
State.EMPTY, State.ERROR -> 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
|
|
||||||
}
|
|
||||||
|
|||||||
+88
@@ -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<ValueParameterDescriptor, ValueParameter> {
|
||||||
|
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<ValueParameterDescriptor>, List<ValueParameter>> {
|
||||||
|
companion object {
|
||||||
|
fun default(): ValueParameterListCommonizer = DefaultValueParameterListCommonizer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DefaultValueParameterListCommonizer :
|
||||||
|
ValueParameterListCommonizer,
|
||||||
|
NamedListWrappedCommonizer<ValueParameterDescriptor, ValueParameter>(
|
||||||
|
subject = "value parameters",
|
||||||
|
wrappedCommonizerFactory = { ValueParameterCommonizer.default() }
|
||||||
|
)
|
||||||
@@ -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<T : CallableMemberDescriptor>(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())
|
||||||
|
}
|
||||||
|
}
|
||||||
-21
@@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<ValueParameter>
|
||||||
|
}
|
||||||
|
|
||||||
|
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<ValueParameter>
|
||||||
|
) : CommonCallableMember(), Function, FunctionModifiers by modifiers
|
||||||
|
|
||||||
|
class TargetFunction(descriptor: SimpleFunctionDescriptor) : TargetCallableMember<SimpleFunctionDescriptor>(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<ValueParameter> 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
|
||||||
|
}
|
||||||
@@ -10,4 +10,5 @@ interface NodeVisitor<R, T> {
|
|||||||
fun visitModuleNode(node: ModuleNode, data: T): R
|
fun visitModuleNode(node: ModuleNode, data: T): R
|
||||||
fun visitPackageNode(node: PackageNode, data: T): R
|
fun visitPackageNode(node: PackageNode, data: T): R
|
||||||
fun visitPropertyNode(node: PropertyNode, data: T): R
|
fun visitPropertyNode(node: PropertyNode, data: T): R
|
||||||
|
fun visitFunctionNode(node: FunctionNode, data: T): R
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,24 +11,15 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ir.Getter.Companion.toGetter
|
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.Setter.Companion.toSetter
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ir.ExtensionReceiver.Companion.toReceiver
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
|
|
||||||
interface Property : Declaration {
|
interface Property : CallableMember, Declaration {
|
||||||
val annotations: Annotations
|
|
||||||
val name: Name
|
|
||||||
val visibility: Visibility
|
|
||||||
val modality: Modality
|
|
||||||
val isVar: Boolean
|
val isVar: Boolean
|
||||||
val kind: CallableMemberDescriptor.Kind
|
|
||||||
val type: UnwrappedType
|
|
||||||
val lateInit: Boolean
|
val lateInit: Boolean
|
||||||
val isConst: Boolean
|
val isConst: Boolean
|
||||||
val isExternal: Boolean
|
|
||||||
val isDelegate: Boolean
|
val isDelegate: Boolean
|
||||||
val getter: Getter?
|
val getter: Getter?
|
||||||
val setter: Setter?
|
val setter: Setter?
|
||||||
val extensionReceiver: ExtensionReceiver?
|
|
||||||
val backingFieldAnnotations: Annotations? // null assumes no backing field
|
val backingFieldAnnotations: Annotations? // null assumes no backing field
|
||||||
val delegateFieldAnnotations: Annotations? // null assumes no backing field
|
val delegateFieldAnnotations: Annotations? // null assumes no backing field
|
||||||
val compileTimeInitializer: ConstantValue<*>?
|
val compileTimeInitializer: ConstantValue<*>?
|
||||||
@@ -36,18 +27,16 @@ interface Property : Declaration {
|
|||||||
|
|
||||||
data class CommonProperty(
|
data class CommonProperty(
|
||||||
override val name: Name,
|
override val name: Name,
|
||||||
override val visibility: Visibility,
|
|
||||||
override val modality: Modality,
|
override val modality: Modality,
|
||||||
override val type: UnwrappedType,
|
override val visibility: Visibility,
|
||||||
override val setter: Setter?,
|
override val isExternal: Boolean,
|
||||||
override val extensionReceiver: ExtensionReceiver?
|
override val extensionReceiver: ExtensionReceiver?,
|
||||||
) : Property {
|
override val returnType: UnwrappedType,
|
||||||
override val annotations get() = Annotations.EMPTY
|
override val setter: Setter?
|
||||||
|
) : CommonCallableMember(), Property {
|
||||||
override val isVar: Boolean get() = setter != null
|
override val isVar: Boolean get() = setter != null
|
||||||
override val kind get() = CallableMemberDescriptor.Kind.DECLARATION
|
|
||||||
override val lateInit: Boolean get() = false
|
override val lateInit: Boolean get() = false
|
||||||
override val isConst: Boolean get() = false
|
override val isConst: Boolean get() = false
|
||||||
override val isExternal: Boolean get() = false
|
|
||||||
override val isDelegate: Boolean get() = false
|
override val isDelegate: Boolean get() = false
|
||||||
override val getter: Getter get() = Getter.DEFAULT_NO_ANNOTATIONS
|
override val getter: Getter get() = Getter.DEFAULT_NO_ANNOTATIONS
|
||||||
override val backingFieldAnnotations: Annotations? get() = null
|
override val backingFieldAnnotations: Annotations? get() = null
|
||||||
@@ -55,22 +44,14 @@ data class CommonProperty(
|
|||||||
override val compileTimeInitializer: ConstantValue<*>? get() = null
|
override val compileTimeInitializer: ConstantValue<*>? get() = null
|
||||||
}
|
}
|
||||||
|
|
||||||
data class TargetProperty(private val descriptor: PropertyDescriptor) : Property {
|
class TargetProperty(descriptor: PropertyDescriptor) : TargetCallableMember<PropertyDescriptor>(descriptor), 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
|
|
||||||
override val isVar: Boolean get() = descriptor.isVar
|
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 lateInit: Boolean get() = descriptor.isLateInit
|
||||||
override val isConst: Boolean get() = descriptor.isConst
|
override val isConst: Boolean get() = descriptor.isConst
|
||||||
override val isExternal: Boolean get() = descriptor.isExternal
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
override val isDelegate: Boolean get() = descriptor.isDelegated
|
override val isDelegate: Boolean get() = descriptor.isDelegated
|
||||||
override val getter: Getter? get() = descriptor.getter?.toGetter()
|
override val getter: Getter? get() = descriptor.getter?.toGetter()
|
||||||
override val setter: Setter? get() = descriptor.setter?.toSetter()
|
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 backingFieldAnnotations: Annotations? get() = descriptor.backingField?.annotations
|
||||||
override val delegateFieldAnnotations: Annotations? get() = descriptor.delegateField?.annotations
|
override val delegateFieldAnnotations: Annotations? get() = descriptor.delegateField?.annotations
|
||||||
override val compileTimeInitializer: ConstantValue<*>? get() = descriptor.compileTimeInitializer
|
override val compileTimeInitializer: ConstantValue<*>? get() = descriptor.compileTimeInitializer
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.ir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.*
|
import org.jetbrains.kotlin.descriptors.commonizer.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
|
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
|
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.core.PropertyCommonizer
|
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.descriptors.commonizer.firstNonNull
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
@@ -41,6 +43,13 @@ internal fun buildPropertyNode(properties: List<PropertyDescriptor?>): PropertyN
|
|||||||
::PropertyNode
|
::PropertyNode
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal fun buildFunctionNode(functions: List<SimpleFunctionDescriptor?>): FunctionNode = buildNode(
|
||||||
|
functions,
|
||||||
|
{ TargetFunction(it) },
|
||||||
|
{ commonize(it, FunctionCommonizer()) },
|
||||||
|
::FunctionNode
|
||||||
|
)
|
||||||
|
|
||||||
private fun <T : Any, D : Declaration, N : Node<D>> buildNode(
|
private fun <T : Any, D : Declaration, N : Node<D>> buildNode(
|
||||||
descriptors: List<T?>,
|
descriptors: List<T?>,
|
||||||
targetDeclarationProducer: (T) -> D,
|
targetDeclarationProducer: (T) -> D,
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class PackageNode(
|
|||||||
override val common: Package?
|
override val common: Package?
|
||||||
) : Node<Package> {
|
) : Node<Package> {
|
||||||
val properties: MutableList<PropertyNode> = ArrayList()
|
val properties: MutableList<PropertyNode> = ArrayList()
|
||||||
|
val functions: MutableList<FunctionNode> = ArrayList()
|
||||||
|
|
||||||
override fun <R, T> accept(visitor: NodeVisitor<R, T>, data: T) =
|
override fun <R, T> accept(visitor: NodeVisitor<R, T>, data: T) =
|
||||||
visitor.visitPackageNode(this, data)
|
visitor.visitPackageNode(this, data)
|
||||||
@@ -52,6 +53,14 @@ class PropertyNode(
|
|||||||
visitor.visitPropertyNode(this, data)
|
visitor.visitPropertyNode(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FunctionNode(
|
||||||
|
override val target: List<Function?>,
|
||||||
|
override val common: Function?
|
||||||
|
) : Node<Function> {
|
||||||
|
override fun <R, T> accept(visitor: NodeVisitor<R, T>, data: T) =
|
||||||
|
visitor.visitFunctionNode(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
internal val <D : Declaration> Node<D>.indexOfCommon: Int
|
internal val <D : Declaration> Node<D>.indexOfCommon: Int
|
||||||
get() = target.size
|
get() = target.size
|
||||||
|
|
||||||
|
|||||||
+11
@@ -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<SimpleFunctionDescriptor?>) = buildFunctionNode(properties)
|
||||||
+35
-6
@@ -6,10 +6,11 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
|
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
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.CommonizedGroupMap
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.fqName
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
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.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ir.PackageNode
|
import org.jetbrains.kotlin.descriptors.commonizer.ir.PackageNode
|
||||||
@@ -22,22 +23,40 @@ internal fun mergePackages(
|
|||||||
val node = buildPackageNode(packageFqName, packageMemberScopes)
|
val node = buildPackageNode(packageFqName, packageMemberScopes)
|
||||||
|
|
||||||
val propertiesMap = CommonizedGroupMap<PropertyKey, PropertyDescriptor>(packageMemberScopes.size)
|
val propertiesMap = CommonizedGroupMap<PropertyKey, PropertyDescriptor>(packageMemberScopes.size)
|
||||||
|
val functionsMap = CommonizedGroupMap<FunctionKey, SimpleFunctionDescriptor>(packageMemberScopes.size)
|
||||||
|
|
||||||
packageMemberScopes.forEachIndexed { index, memberScope ->
|
packageMemberScopes.forEachIndexed { index, memberScope ->
|
||||||
memberScope?.collectProperties { propertyKey, property ->
|
memberScope?.collectProperties { propertyKey, property ->
|
||||||
propertiesMap[propertyKey][index] = property
|
propertiesMap[propertyKey][index] = property
|
||||||
}
|
}
|
||||||
|
memberScope?.collectFunctions { functionKey, function ->
|
||||||
|
functionsMap[functionKey][index] = function
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((_, propertiesGroup) in propertiesMap) {
|
for ((_, propertiesGroup) in propertiesMap) {
|
||||||
node.properties += mergeProperties(propertiesGroup.toList())
|
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
|
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) {
|
internal fun MemberScope.collectProperties(collector: (PropertyKey, PropertyDescriptor) -> Unit) {
|
||||||
getContributedDescriptors(DescriptorKindFilter.VARIABLES).asSequence()
|
getContributedDescriptors(DescriptorKindFilter.VARIABLES).asSequence()
|
||||||
.filterIsInstance<PropertyDescriptor>()
|
.filterIsInstance<PropertyDescriptor>()
|
||||||
@@ -46,12 +65,22 @@ internal fun MemberScope.collectProperties(collector: (PropertyKey, PropertyDesc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal data class PropertyKey(
|
internal data class FunctionKey(
|
||||||
val name: Name,
|
val name: Name,
|
||||||
|
val valueParameters: List<Pair<Name, FqName>>,
|
||||||
val extensionReceiverParameterFqName: FqName?
|
val extensionReceiverParameterFqName: FqName?
|
||||||
) {
|
) {
|
||||||
constructor(property: PropertyDescriptor) : this(
|
constructor(function: SimpleFunctionDescriptor) : this(
|
||||||
property.name,
|
function.name,
|
||||||
property.extensionReceiverParameter?.run { type.constructor.declarationDescriptor!!.fqNameSafe }
|
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<SimpleFunctionDescriptor>()
|
||||||
|
.forEach { function ->
|
||||||
|
collector(FunctionKey(function), function)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer
|
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
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
|
|
||||||
internal fun <T> Sequence<T>.toList(expectedCapacity: Int): List<T> {
|
internal fun <T> Sequence<T>.toList(expectedCapacity: Int): List<T> {
|
||||||
@@ -14,3 +17,8 @@ internal fun <T> Sequence<T>.toList(expectedCapacity: Int): List<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified T> Iterable<T?>.firstNonNull() = firstIsInstance<T>()
|
internal inline fun <reified T> Iterable<T?>.firstNonNull() = firstIsInstance<T>()
|
||||||
|
|
||||||
|
internal val KotlinType.fqName: FqName
|
||||||
|
get() = constructor.declarationDescriptor!!.fqNameSafe
|
||||||
|
|
||||||
|
internal fun Any?.isNull() = this == null
|
||||||
|
|||||||
+7
@@ -6,3 +6,10 @@ expect val Short.intProperty: Int
|
|||||||
expect val Long.intProperty: Int
|
expect val Long.intProperty: Int
|
||||||
expect val String.intProperty: Int
|
expect val String.intProperty: Int
|
||||||
expect val Planet.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
|
||||||
+10
@@ -7,5 +7,15 @@ actual val Long.intProperty get() = toInt()
|
|||||||
actual val String.intProperty get() = length
|
actual val String.intProperty get() = length
|
||||||
actual val Planet.intProperty get() = diameter.toInt()
|
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 String.mismatchedProperty1 get() = 42
|
||||||
val mismatchedProperty2 get() = 42
|
val mismatchedProperty2 get() = 42
|
||||||
|
|
||||||
|
fun String.mismatchedFunction1() = 42
|
||||||
|
fun mismatchedFunction2() = 42
|
||||||
+10
@@ -7,5 +7,15 @@ actual val Long.intProperty get() = toInt()
|
|||||||
actual val String.intProperty get() = length
|
actual val String.intProperty get() = length
|
||||||
actual val Planet.intProperty get() = diameter.toInt()
|
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 mismatchedProperty1 get() = 42
|
||||||
val Double.mismatchedProperty2 get() = 42
|
val Double.mismatchedProperty2 get() = 42
|
||||||
|
|
||||||
|
fun mismatchedFunction1() = 42
|
||||||
|
fun Double.mismatchedFunction2() = 42
|
||||||
+10
@@ -7,5 +7,15 @@ val Long.intProperty get() = toInt()
|
|||||||
val String.intProperty get() = length
|
val String.intProperty get() = length
|
||||||
val Planet.intProperty get() = diameter.toInt()
|
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 String.mismatchedProperty1 get() = 42
|
||||||
val mismatchedProperty2 get() = 42
|
val mismatchedProperty2 get() = 42
|
||||||
|
|
||||||
|
fun String.mismatchedFunction1() = 42
|
||||||
|
fun mismatchedFunction2() = 42
|
||||||
+10
@@ -7,5 +7,15 @@ val Long.intProperty get() = toInt()
|
|||||||
val String.intProperty get() = length
|
val String.intProperty get() = length
|
||||||
val Planet.intProperty get() = diameter.toInt()
|
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 mismatchedProperty1 get() = 42
|
||||||
val Double.mismatchedProperty2 get() = 42
|
val Double.mismatchedProperty2 get() = 42
|
||||||
|
|
||||||
|
fun mismatchedFunction1() = 42
|
||||||
|
fun Double.mismatchedFunction2() = 42
|
||||||
+6
@@ -13,3 +13,9 @@ expect val property2: String
|
|||||||
expect val property3: Planet
|
expect val property3: Planet
|
||||||
expect val property6: Planet
|
expect val property6: Planet
|
||||||
expect val property7: C
|
expect val property7: C
|
||||||
|
|
||||||
|
expect fun function1(): Int
|
||||||
|
expect fun function2(): String
|
||||||
|
expect fun function3(): Planet
|
||||||
|
expect fun function6(): Planet
|
||||||
|
expect fun function7(): C
|
||||||
+14
@@ -17,8 +17,22 @@ val property5 = A("Earth", 12742)
|
|||||||
actual val property6 = Planet("Earth", 12742)
|
actual val property6 = Planet("Earth", 12742)
|
||||||
actual val property7 = C("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 propertyWithMismatchedType1: Int = 1
|
||||||
val propertyWithMismatchedType2: Int = 1
|
val propertyWithMismatchedType2: Int = 1
|
||||||
val propertyWithMismatchedType3: Int = 1
|
val propertyWithMismatchedType3: Int = 1
|
||||||
val propertyWithMismatchedType4: Int = 1
|
val propertyWithMismatchedType4: Int = 1
|
||||||
val propertyWithMismatchedType5: 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
|
||||||
+14
@@ -17,8 +17,22 @@ val property5: Planet = A("Earth", 12742)
|
|||||||
actual val property6: Planet = A("Earth", 12742)
|
actual val property6: Planet = A("Earth", 12742)
|
||||||
actual val property7: C = Planet("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 propertyWithMismatchedType1: Long = 1
|
||||||
val propertyWithMismatchedType2: Short = 1
|
val propertyWithMismatchedType2: Short = 1
|
||||||
val propertyWithMismatchedType3: Number = 1
|
val propertyWithMismatchedType3: Number = 1
|
||||||
val propertyWithMismatchedType4: Comparable<Int> = 1
|
val propertyWithMismatchedType4: Comparable<Int> = 1
|
||||||
val propertyWithMismatchedType5: String = 1.toString()
|
val propertyWithMismatchedType5: String = 1.toString()
|
||||||
|
|
||||||
|
fun functionWithMismatchedType1(): Long = 1
|
||||||
|
fun functionWithMismatchedType2(): Short = 1
|
||||||
|
fun functionWithMismatchedType3(): Number = 1
|
||||||
|
fun functionWithMismatchedType4(): Comparable<Int> = 1
|
||||||
|
fun functionWithMismatchedType5(): String = 1.toString()
|
||||||
Vendored
+40
@@ -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
|
||||||
Vendored
+40
@@ -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<Int> = 1
|
||||||
|
val propertyWithMismatchedType5: String = 1.toString()
|
||||||
|
|
||||||
|
fun functionWithMismatchedType1(): Long = 1
|
||||||
|
fun functionWithMismatchedType2(): Short = 1
|
||||||
|
fun functionWithMismatchedType3(): Number = 1
|
||||||
|
fun functionWithMismatchedType4(): Comparable<Int> = 1
|
||||||
|
fun functionWithMismatchedType5(): String = 1.toString()
|
||||||
Vendored
+7
@@ -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
|
||||||
Vendored
+11
@@ -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
|
||||||
Vendored
+11
@@ -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
|
||||||
Vendored
+11
@@ -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
|
||||||
Vendored
+11
@@ -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
|
||||||
Vendored
+18
@@ -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() {}
|
||||||
+19
@@ -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() {}
|
||||||
+19
@@ -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() {}
|
||||||
+19
@@ -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() {}
|
||||||
+19
@@ -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() {}
|
||||||
Vendored
+13
@@ -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<Double>)
|
||||||
|
|
||||||
|
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<out Int>)
|
||||||
Vendored
+28
@@ -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<Double>) {}
|
||||||
|
|
||||||
|
fun functionMismatchedParameterCount1(i: Int, s: String) {}
|
||||||
|
fun functionMismatchedParameterCount2(i: Int, s: String, l: List<Double>) {}
|
||||||
|
|
||||||
|
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<Int>) {}
|
||||||
|
actual fun functionWithVararg5(numbers: Array<out Int>) {}
|
||||||
Vendored
+28
@@ -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<Double>) {}
|
||||||
|
|
||||||
|
fun functionMismatchedParameterCount1(i: Int, s: String, l: List<Double>) {}
|
||||||
|
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<Int>) {}
|
||||||
|
fun functionWithVararg3(numbers: Array<out Int>) {}
|
||||||
|
//fun functionWithVararg4(numbers: Array<out Int>) {}
|
||||||
|
actual fun functionWithVararg5(numbers: Array<out Int>) {}
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
fun functionNoParameters() {}
|
||||||
|
fun functionSingleParameter(i: Int) {}
|
||||||
|
fun functionTwoParameters(i: Int, s: String) {}
|
||||||
|
fun functionThreeParameters(i: Int, s: String, l: List<Double>) {}
|
||||||
|
|
||||||
|
fun functionMismatchedParameterCount1(i: Int, s: String) {}
|
||||||
|
fun functionMismatchedParameterCount2(i: Int, s: String, l: List<Double>) {}
|
||||||
|
|
||||||
|
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<Int>) {}
|
||||||
|
fun functionWithVararg5(numbers: Array<out Int>) {}
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
fun functionNoParameters() {}
|
||||||
|
fun functionSingleParameter(i: Int) {}
|
||||||
|
fun functionTwoParameters(i: Int, s: String) {}
|
||||||
|
fun functionThreeParameters(i: Int, s: String, l: List<Double>) {}
|
||||||
|
|
||||||
|
fun functionMismatchedParameterCount1(i: Int, s: String, l: List<Double>) {}
|
||||||
|
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<Int>) {}
|
||||||
|
fun functionWithVararg3(numbers: Array<out Int>) {}
|
||||||
|
//fun functionWithVararg4(numbers: Array<out Int>) {}
|
||||||
|
fun functionWithVararg5(numbers: Array<out Int>) {}
|
||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
expect var propertyWithoutBackingField: Double
|
expect var propertyWithoutBackingField: Double
|
||||||
|
|
||||||
expect val propertyWithBackingField: Double
|
expect val propertyWithBackingField: Double
|
||||||
|
|
||||||
expect val propertyWithDelegateField: Int
|
expect val propertyWithDelegateField: Int
|
||||||
|
|
||||||
expect val String.propertyWithExtensionReceiver: Int
|
expect val String.propertyWithExtensionReceiver: Int
|
||||||
|
|
||||||
|
expect fun function1(text: String): String
|
||||||
|
expect fun String.function2(): String
|
||||||
+6
-1
@@ -1,7 +1,6 @@
|
|||||||
import kotlin.annotation.AnnotationTarget.*
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
||||||
@Repeatable
|
|
||||||
annotation class Foo(val text: String)
|
annotation class Foo(val text: String)
|
||||||
|
|
||||||
@property:Foo("property")
|
@property:Foo("property")
|
||||||
@@ -20,3 +19,9 @@ actual val propertyWithDelegateField: Int by lazy { 42 }
|
|||||||
|
|
||||||
actual val @receiver:Foo("receiver") String.propertyWithExtensionReceiver: Int
|
actual val @receiver:Foo("receiver") String.propertyWithExtensionReceiver: Int
|
||||||
get() = length
|
get() = length
|
||||||
|
|
||||||
|
@Foo("function")
|
||||||
|
actual fun function1(@Foo("parameter") text: String) = text
|
||||||
|
|
||||||
|
@Foo("function")
|
||||||
|
actual fun @receiver:Foo("receiver") String.function2() = this
|
||||||
+6
-1
@@ -1,7 +1,6 @@
|
|||||||
import kotlin.annotation.AnnotationTarget.*
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
||||||
@Repeatable
|
|
||||||
annotation class Bar(val text: String)
|
annotation class Bar(val text: String)
|
||||||
|
|
||||||
@Bar("property")
|
@Bar("property")
|
||||||
@@ -17,3 +16,9 @@ actual val propertyWithDelegateField: Int by lazy { 42 }
|
|||||||
|
|
||||||
actual val @receiver:Bar("receiver") String.propertyWithExtensionReceiver: Int
|
actual val @receiver:Bar("receiver") String.propertyWithExtensionReceiver: Int
|
||||||
get() = length
|
get() = length
|
||||||
|
|
||||||
|
@Bar("function")
|
||||||
|
actual fun function1(@Bar("parameter") text: String) = text
|
||||||
|
|
||||||
|
@Bar("function")
|
||||||
|
actual fun @receiver:Foo("receiver") String.function2() = this
|
||||||
+7
-2
@@ -1,7 +1,6 @@
|
|||||||
import kotlin.annotation.AnnotationTarget.*
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER, FUNCTION)
|
||||||
@Repeatable
|
|
||||||
annotation class Foo(val text: String)
|
annotation class Foo(val text: String)
|
||||||
|
|
||||||
@Foo("property")
|
@Foo("property")
|
||||||
@@ -17,3 +16,9 @@ val propertyWithDelegateField: Int by lazy { 42 }
|
|||||||
|
|
||||||
val @receiver:Foo("receiver") String.propertyWithExtensionReceiver: Int
|
val @receiver:Foo("receiver") String.propertyWithExtensionReceiver: Int
|
||||||
get() = length
|
get() = length
|
||||||
|
|
||||||
|
@Foo("function")
|
||||||
|
fun function1(@Foo("parameter") text: String) = text
|
||||||
|
|
||||||
|
@Foo("function")
|
||||||
|
fun @receiver:Foo("receiver") String.function2() = this
|
||||||
+6
-1
@@ -1,7 +1,6 @@
|
|||||||
import kotlin.annotation.AnnotationTarget.*
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
@Target(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, FIELD, VALUE_PARAMETER)
|
||||||
@Repeatable
|
|
||||||
annotation class Bar(val text: String)
|
annotation class Bar(val text: String)
|
||||||
|
|
||||||
@Bar("property")
|
@Bar("property")
|
||||||
@@ -17,3 +16,9 @@ val propertyWithDelegateField: Int by lazy { 42 }
|
|||||||
|
|
||||||
val @receiver:Bar("receiver") String.propertyWithExtensionReceiver: Int
|
val @receiver:Bar("receiver") String.propertyWithExtensionReceiver: Int
|
||||||
get() = length
|
get() = length
|
||||||
|
|
||||||
|
@Bar("function")
|
||||||
|
fun function1(@Bar("parameter") text: String) = text
|
||||||
|
|
||||||
|
@Bar("function")
|
||||||
|
fun @receiver:Foo("receiver") String.function2() = this
|
||||||
-24
@@ -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
|
|
||||||
-24
@@ -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<Int> = 1
|
|
||||||
val propertyWithMismatchedType5: String = 1.toString()
|
|
||||||
konan/commonizer/testData/propertyCommonization/specificProperties/commonized/common/package_root.kt
Vendored
-7
@@ -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
|
|
||||||
Vendored
-13
@@ -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
|
|
||||||
Vendored
-13
@@ -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
|
|
||||||
Vendored
-13
@@ -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
|
|
||||||
Vendored
+17
@@ -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
|
||||||
+33
@@ -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
|
||||||
+33
@@ -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
|
||||||
+20
@@ -11,3 +11,23 @@ lateinit var lateinitProperty2: String
|
|||||||
|
|
||||||
inline val inlineProperty1 get() = 42
|
inline val inlineProperty1 get() = 42
|
||||||
inline val inlineProperty2 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
|
||||||
+33
@@ -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
|
||||||
Vendored
-2
@@ -1,2 +0,0 @@
|
|||||||
expect public val publicProperty: Int
|
|
||||||
expect internal val internalProperty: Int
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
actual public val publicProperty = 1
|
|
||||||
actual internal val internalProperty = 1
|
|
||||||
private val privateProperty = 1
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
actual public val publicProperty = 1
|
|
||||||
actual internal val internalProperty = 1
|
|
||||||
private val privateProperty = 1
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
public val publicProperty = 1
|
|
||||||
internal val internalProperty = 1
|
|
||||||
private val privateProperty = 1
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
public val publicProperty = 1
|
|
||||||
internal val internalProperty = 1
|
|
||||||
private val privateProperty = 1
|
|
||||||
+21
@@ -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)
|
||||||
|
}
|
||||||
+16
@@ -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()
|
||||||
|
}
|
||||||
+16
@@ -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()
|
||||||
|
}
|
||||||
+1
-15
@@ -10,21 +10,7 @@ import kotlin.contracts.ExperimentalContracts
|
|||||||
@ExperimentalContracts
|
@ExperimentalContracts
|
||||||
class PropertyCommonizationFromSourcesTest : AbstractCommonizationFromSourcesTest() {
|
class PropertyCommonizationFromSourcesTest : AbstractCommonizationFromSourcesTest() {
|
||||||
|
|
||||||
fun testMismatchedPackages() = doTestSuccessfulCommonization()
|
fun testSpecifics() = doTestSuccessfulCommonization()
|
||||||
|
|
||||||
fun testReturnTypes() = doTestSuccessfulCommonization()
|
|
||||||
|
|
||||||
fun testVisibility() = doTestSuccessfulCommonization()
|
|
||||||
|
|
||||||
fun testSpecificProperties() = doTestSuccessfulCommonization()
|
|
||||||
|
|
||||||
fun testExtensionReceivers() = doTestSuccessfulCommonization()
|
|
||||||
|
|
||||||
fun testSetters() = doTestSuccessfulCommonization()
|
fun testSetters() = doTestSuccessfulCommonization()
|
||||||
|
|
||||||
fun testAnnotations() = doTestSuccessfulCommonization()
|
|
||||||
|
|
||||||
// TODO: test modality (possible only inside classes)
|
|
||||||
// TODO: test virtual val visibility commonization (possible only inside classes)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer
|
|||||||
import junit.framework.TestCase.fail
|
import junit.framework.TestCase.fail
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.PropertyKey
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.collectNonEmptyPackageMemberScopes
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.collectProperties
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
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 visitMemberScopes(expected: MemberScope, actual: MemberScope, context: Context) {
|
||||||
fun collectProperties(memberScope: MemberScope): Map<PropertyKey, PropertyDescriptor> =
|
fun collectProperties(memberScope: MemberScope): Map<PropertyKey, PropertyDescriptor> =
|
||||||
mutableMapOf<PropertyKey, PropertyDescriptor>().also {
|
mutableMapOf<PropertyKey, PropertyDescriptor>().also {
|
||||||
@@ -116,15 +108,78 @@ private class ComparingDeclarationsVisitor(
|
|||||||
expectedProperty.accept(this, context.nextLevel(actualProperty))
|
expectedProperty.accept(this, context.nextLevel(actualProperty))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: traverse the rest - functions, classes, typealiases
|
fun collectFunctions(memberScope: MemberScope): Map<FunctionKey, SimpleFunctionDescriptor> =
|
||||||
|
mutableMapOf<FunctionKey, SimpleFunctionDescriptor>().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) {
|
override fun visitFunctionDescriptor(expected: FunctionDescriptor, context: Context) {
|
||||||
TODO("not implemented")
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val expected = expected as SimpleFunctionDescriptor
|
||||||
|
val actual = context.getActualAs<SimpleFunctionDescriptor>()
|
||||||
|
|
||||||
|
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<ValueParameterDescriptor>,
|
||||||
|
actual: List<ValueParameterDescriptor>,
|
||||||
|
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<ValueParameterDescriptor>()
|
||||||
|
|
||||||
|
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) {
|
override fun visitTypeParameterDescriptor(expected: TypeParameterDescriptor, context: Context) {
|
||||||
@@ -135,11 +190,11 @@ private class ComparingDeclarationsVisitor(
|
|||||||
TODO("not implemented")
|
TODO("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAliasDescriptor(expected: TypeAliasDescriptor, context: Context) {
|
override fun visitConstructorDescriptor(expected: ConstructorDescriptor, context: Context) {
|
||||||
TODO("not implemented")
|
TODO("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructorDescriptor(expected: ConstructorDescriptor, context: Context) {
|
override fun visitTypeAliasDescriptor(expected: TypeAliasDescriptor, context: Context) {
|
||||||
TODO("not implemented")
|
TODO("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +212,7 @@ private class ComparingDeclarationsVisitor(
|
|||||||
context.assertFieldsEqual(expected::isExternal, actual::isExternal)
|
context.assertFieldsEqual(expected::isExternal, actual::isExternal)
|
||||||
context.assertFieldsEqual(expected::isExpect, actual::isExpect)
|
context.assertFieldsEqual(expected::isExpect, actual::isExpect)
|
||||||
context.assertFieldsEqual(expected::isActual, actual::isActual)
|
context.assertFieldsEqual(expected::isActual, actual::isActual)
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
context.assertFieldsEqual(expected::isDelegated, actual::isDelegated)
|
context.assertFieldsEqual(expected::isDelegated, actual::isDelegated)
|
||||||
visitAnnotations(
|
visitAnnotations(
|
||||||
expected.delegateField?.annotations,
|
expected.delegateField?.annotations,
|
||||||
@@ -168,7 +224,7 @@ private class ComparingDeclarationsVisitor(
|
|||||||
actual.backingField?.annotations,
|
actual.backingField?.annotations,
|
||||||
context.nextLevel("Property backing field 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"))
|
visitType(expected.type, actual.type, context.nextLevel("Property type"))
|
||||||
|
|
||||||
visitPropertyGetterDescriptor(expected.getter, context.nextLevel(actual.getter))
|
visitPropertyGetterDescriptor(expected.getter, context.nextLevel(actual.getter))
|
||||||
@@ -178,10 +234,6 @@ private class ComparingDeclarationsVisitor(
|
|||||||
visitReceiverParameterDescriptor(expected.dispatchReceiverParameter, context.nextLevel(actual.dispatchReceiverParameter))
|
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) {
|
override fun visitPropertyGetterDescriptor(expected: PropertyGetterDescriptor?, context: Context) {
|
||||||
val actual = context.getActualAs<PropertyGetterDescriptor?>()
|
val actual = context.getActualAs<PropertyGetterDescriptor?>()
|
||||||
if (expected === actual) return
|
if (expected === actual) return
|
||||||
@@ -222,8 +274,6 @@ private class ComparingDeclarationsVisitor(
|
|||||||
visitAnnotations(expected.annotations, actual.annotations, context.nextLevel("Receiver parameter annotations"))
|
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) {
|
private fun visitAnnotations(expected: Annotations?, actual: Annotations?, context: Context) {
|
||||||
if (expected === actual) return
|
if (expected === actual) return
|
||||||
@@ -234,9 +284,11 @@ private class ComparingDeclarationsVisitor(
|
|||||||
context.assertEquals(expectedAnnotationFqNames, actualAnnotationFqNames, "annotations")
|
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
|
if (expected === actual) return
|
||||||
|
|
||||||
|
check(actual != null && expected != null)
|
||||||
|
|
||||||
val expectedUnwrapped = expected.unwrap()
|
val expectedUnwrapped = expected.unwrap()
|
||||||
val actualUnwrapped = actual.unwrap()
|
val actualUnwrapped = actual.unwrap()
|
||||||
|
|
||||||
@@ -265,4 +317,16 @@ private class ComparingDeclarationsVisitor(
|
|||||||
|
|
||||||
assertEquals(expectedValue, actualValue, "fields \"$expected\"")
|
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")
|
||||||
}
|
}
|
||||||
|
|||||||
+181
@@ -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<SimpleFunctionDescriptor, FunctionModifiers>() {
|
||||||
|
|
||||||
|
@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
|
||||||
|
)
|
||||||
+1
-1
@@ -78,5 +78,5 @@ private fun Visibility.toMockProperty() = mockProperty(
|
|||||||
name = "myProperty",
|
name = "myProperty",
|
||||||
setterVisibility = this,
|
setterVisibility = this,
|
||||||
extensionReceiverType = null,
|
extensionReceiverType = null,
|
||||||
returnType = mockClassType("kotlin.String").unwrap()
|
returnType = mockClassType("kotlin.String")
|
||||||
).setter!!
|
).setter!!
|
||||||
|
|||||||
+176
@@ -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<ValueParameterDescriptor, ValueParameter>() {
|
||||||
|
|
||||||
|
@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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+185
@@ -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<ValueParameterDescriptor>, List<ValueParameter>>() {
|
||||||
|
|
||||||
|
@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<String, String>): List<ValueParameter> {
|
||||||
|
check(params.isNotEmpty())
|
||||||
|
return params.map { (name, returnTypeFqName) ->
|
||||||
|
DefaultValueParameterCommonizerTest.create(
|
||||||
|
name = name,
|
||||||
|
returnTypeFqName = returnTypeFqName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<ValueParameter>.toMockParams() = DefaultValueParameterCommonizerTest.run {
|
||||||
|
mapIndexed { index, param -> param.toMockParam(index) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
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.descriptors.impl.*
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -179,6 +180,93 @@ internal fun mockProperty(
|
|||||||
return propertyDescriptor
|
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("<fake containing declaration>")) {
|
||||||
|
override fun getContainingDeclaration() = error("not supported")
|
||||||
|
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, 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(
|
//private fun mockTypeParameterType(
|
||||||
// name: String,
|
// name: String,
|
||||||
// containingDeclaration: DeclarationDescriptor,
|
// containingDeclaration: DeclarationDescriptor,
|
||||||
|
|||||||
Reference in New Issue
Block a user