Fixed handling of default params in declaration (KT-23239)
This commit is contained in:
+34
-11
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.CollectionLiteralKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
@@ -70,20 +69,44 @@ fun ValueParameterDescriptor.hasDefaultValue(): Boolean {
|
||||
return DFS.ifAny(
|
||||
listOf(this),
|
||||
{ current -> current.overriddenDescriptors.map(ValueParameterDescriptor::getOriginal) },
|
||||
{ it.declaresDefaultValue() || it.isActualParameterWithExpectedDefault }
|
||||
{ it.declaresDefaultValue() || it.isActualParameterWithAnyExpectedDefault }
|
||||
)
|
||||
}
|
||||
|
||||
val ValueParameterDescriptor.isActualParameterWithExpectedDefault: Boolean
|
||||
get() {
|
||||
val function = containingDeclaration
|
||||
if (function is FunctionDescriptor && function.isActual) {
|
||||
with(ExpectedActualResolver) {
|
||||
val expected = function.findCompatibleExpectedForActual(function.module).firstOrNull()
|
||||
return expected is FunctionDescriptor && expected.valueParameters[index].hasDefaultValue()
|
||||
}
|
||||
fun ValueParameterDescriptor.checkExpectedParameter(checker: (ValueParameterDescriptor) -> Boolean) : Boolean {
|
||||
val function = containingDeclaration
|
||||
if (function is FunctionDescriptor && function.isActual) {
|
||||
with(ExpectedActualResolver) {
|
||||
val expected = function.findCompatibleExpectedForActual(function.module).firstOrNull()
|
||||
return expected is FunctionDescriptor && checker(expected.valueParameters[index])
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* The following two properties describe two different situations:
|
||||
*
|
||||
* Consider hierarchy:
|
||||
* expect open class A { foo(p = 1) }
|
||||
* expect open class B : A { foo(p) }
|
||||
*
|
||||
* actual open class A { foo(p) }
|
||||
* actual open class B : A { foo(p) }
|
||||
*
|
||||
* For parameter `p` of method `foo`:
|
||||
* `Any` property returns `true` for both actual A and B
|
||||
* `Corresponding` property returns `true` only for `actual A` because `expect B` declaration doesn't have an default value
|
||||
*/
|
||||
|
||||
val ValueParameterDescriptor.isActualParameterWithAnyExpectedDefault: Boolean
|
||||
get() {
|
||||
return checkExpectedParameter { it.hasDefaultValue() }
|
||||
}
|
||||
|
||||
val ValueParameterDescriptor.isActualParameterWithCorrespondingExpectedDefault: Boolean
|
||||
get() {
|
||||
return checkExpectedParameter { it.declaresDefaultValue() }
|
||||
}
|
||||
|
||||
private fun KotlinCallArgument.isArrayAssignedAsNamedArgumentInAnnotation(
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.resolve.RequireKotlinNames
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithExpectedDefault
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithAnyExpectedDefault
|
||||
import org.jetbrains.kotlin.resolve.checkers.KotlinVersionStringAnnotationValueChecker
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||
@@ -408,7 +408,7 @@ class DescriptorSerializer private constructor(
|
||||
private fun valueParameter(descriptor: ValueParameterDescriptor): ProtoBuf.ValueParameter.Builder {
|
||||
val builder = ProtoBuf.ValueParameter.newBuilder()
|
||||
|
||||
val declaresDefaultValue = descriptor.declaresDefaultValue() || descriptor.isActualParameterWithExpectedDefault
|
||||
val declaresDefaultValue = descriptor.declaresDefaultValue() || descriptor.isActualParameterWithAnyExpectedDefault
|
||||
|
||||
val flags = Flags.getValueParameterFlags(
|
||||
hasAnnotations(descriptor), declaresDefaultValue, descriptor.isCrossinline, descriptor.isNoinline
|
||||
|
||||
+8
-3
@@ -28,7 +28,8 @@ import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOrInheritsParametersWithDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithCorrespondingExpectedDefault
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOwnParametersWithDefaultValue
|
||||
|
||||
class DeclarationBodyVisitor(
|
||||
@@ -110,8 +111,12 @@ class DeclarationBodyVisitor(
|
||||
initializerStatements.add(statement)
|
||||
}
|
||||
|
||||
private fun hasParametersWithDefaultValue(descriptor: FunctionDescriptor) = descriptor.valueParameters.any { it.hasDefaultValue() }
|
||||
private fun hasCorrespondingExpectParametersWithDefaultValue(descriptor: FunctionDescriptor) =
|
||||
descriptor.valueParameters.any { it.isActualParameterWithCorrespondingExpectedDefault }
|
||||
|
||||
override fun addFunction(descriptor: FunctionDescriptor, expression: JsExpression?, psi: KtElement?) {
|
||||
if (!descriptor.hasOrInheritsParametersWithDefaultValue() || !descriptor.isOverridableOrOverrides) {
|
||||
if (!hasParametersWithDefaultValue(descriptor) || !descriptor.isOverridableOrOverrides) {
|
||||
if (expression != null) {
|
||||
context.addDeclarationStatement(context.addFunctionToPrototype(containingClass, descriptor, expression))
|
||||
}
|
||||
@@ -125,7 +130,7 @@ class DeclarationBodyVisitor(
|
||||
context.addDeclarationStatement(JsAstUtils.assignment(functionRef, expression).makeStmt())
|
||||
}
|
||||
|
||||
if (descriptor.hasOwnParametersWithDefaultValue()) {
|
||||
if (descriptor.hasOwnParametersWithDefaultValue() || hasCorrespondingExpectParametersWithDefaultValue(descriptor)) {
|
||||
val caller = JsFunction(context.getScopeForDescriptor(containingClass), JsBlock(), "")
|
||||
caller.source = psi?.finalElement
|
||||
val callerContext = context
|
||||
|
||||
Reference in New Issue
Block a user