Support default arguments for expected declarations
#KT-21913 Fixed
This commit is contained in:
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
object CodegenUtil {
|
||||
@@ -166,4 +167,12 @@ object CodegenUtil {
|
||||
@JvmStatic
|
||||
fun getActualDeclarations(file: KtFile): List<KtDeclaration> =
|
||||
file.declarations.filterNot(KtDeclaration::hasExpectModifier)
|
||||
|
||||
@JvmStatic
|
||||
fun findExpectedFunctionForActual(descriptor: FunctionDescriptor): FunctionDescriptor? {
|
||||
val compatibleExpectedFunctions = with(ExpectedActualResolver) {
|
||||
descriptor.findCompatibleExpectedForActual(DescriptorUtils.getContainingModule(descriptor))
|
||||
}
|
||||
return compatibleExpectedFunctions.firstOrNull() as FunctionDescriptor?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.Bridge;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
|
||||
@@ -73,6 +74,7 @@ import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DEC
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
@@ -585,8 +587,10 @@ public class FunctionCodegen {
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else {
|
||||
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
|
||||
functionDescriptor));
|
||||
FrameMap frameMap = createFrameMap(
|
||||
parentCodegen.state, signature, functionDescriptor.getExtensionReceiverParameter(),
|
||||
functionDescriptor.getValueParameters(), isStaticMethod(context.getContextKind(), functionDescriptor)
|
||||
);
|
||||
if (context.isInlineMethodContext()) {
|
||||
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
}
|
||||
@@ -1046,7 +1050,7 @@ public class FunctionCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefaultNeeded(functionDescriptor)) {
|
||||
if (!isDefaultNeeded(functionDescriptor, function)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1106,8 +1110,19 @@ public class FunctionCodegen {
|
||||
GenerationState state = parentCodegen.state;
|
||||
JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
|
||||
|
||||
List<ValueParameterDescriptor> originalParameters = functionDescriptor.getValueParameters();
|
||||
List<ValueParameterDescriptor> valueParameters;
|
||||
if (functionDescriptor.isActual() && CollectionsKt.none(originalParameters, ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(functionDescriptor);
|
||||
assert expected != null : "Expected function should have been found earlier for " + functionDescriptor;
|
||||
valueParameters = expected.getValueParameters();
|
||||
}
|
||||
else {
|
||||
valueParameters = originalParameters;
|
||||
}
|
||||
|
||||
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
|
||||
FrameMap frameMap = createFrameMap(state, functionDescriptor, signature, isStatic);
|
||||
FrameMap frameMap = createFrameMap(state, signature, functionDescriptor.getExtensionReceiverParameter(), valueParameters, isStatic);
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
|
||||
|
||||
@@ -1123,7 +1138,6 @@ public class FunctionCodegen {
|
||||
capturedArgumentsCount++;
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
|
||||
assert valueParameters.size() > 0 : "Expecting value parameters to generate default function " + functionDescriptor;
|
||||
int firstMaskIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
for (int index = 1; index < valueParameters.size(); index++) {
|
||||
@@ -1191,10 +1205,11 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FrameMap createFrameMap(
|
||||
private static FrameMap createFrameMap(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor function,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@Nullable ReceiverParameterDescriptor extensionReceiverParameter,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
boolean isStatic
|
||||
) {
|
||||
FrameMap frameMap = new FrameMap();
|
||||
@@ -1204,9 +1219,8 @@ public class FunctionCodegen {
|
||||
|
||||
for (JvmMethodParameterSignature parameter : signature.getValueParameters()) {
|
||||
if (parameter.getKind() == JvmMethodParameterKind.RECEIVER) {
|
||||
ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
frameMap.enter(receiverParameter, state.getTypeMapper().mapType(receiverParameter));
|
||||
if (extensionReceiverParameter != null) {
|
||||
frameMap.enter(extensionReceiverParameter, state.getTypeMapper().mapType(extensionReceiverParameter));
|
||||
}
|
||||
else {
|
||||
frameMap.enterTemp(parameter.getAsmType());
|
||||
@@ -1217,7 +1231,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : function.getValueParameters()) {
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
frameMap.enter(parameter, state.getTypeMapper().mapType(parameter));
|
||||
}
|
||||
|
||||
@@ -1245,17 +1259,23 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDefaultNeeded(FunctionDescriptor functionDescriptor) {
|
||||
boolean needed = false;
|
||||
if (functionDescriptor != null) {
|
||||
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
|
||||
if (parameterDescriptor.declaresDefaultValue()) {
|
||||
needed = true;
|
||||
break;
|
||||
private boolean isDefaultNeeded(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
|
||||
if (descriptor.isActual()) {
|
||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(descriptor);
|
||||
if (expected != null && CollectionsKt.any(expected.getValueParameters(), ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(expected);
|
||||
if (element == null) {
|
||||
if (function != null) {
|
||||
state.getDiagnostics().report(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(function));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return needed;
|
||||
|
||||
return CollectionsKt.any(descriptor.getValueParameters(), ValueParameterDescriptor::declaresDefaultValue);
|
||||
}
|
||||
|
||||
private void generateBridge(
|
||||
|
||||
@@ -280,8 +280,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
val parentContext = context.parentContext ?: error("Context has no parent: " + context)
|
||||
val methodContext = parentContext.intoFunction(callableDescriptor)
|
||||
|
||||
val smap: SMAP
|
||||
if (callDefault) {
|
||||
val smap = if (callDefault) {
|
||||
val implementationOwner = state.typeMapper.mapImplementationOwner(callableDescriptor)
|
||||
val parentCodegen = FakeMemberCodegen(
|
||||
codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>,
|
||||
@@ -293,13 +292,13 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
throw IllegalStateException("Property accessors with default parameters not supported " + callableDescriptor)
|
||||
}
|
||||
FunctionCodegen.generateDefaultImplBody(
|
||||
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
inliningFunction as KtNamedFunction?, parentCodegen, asmMethod
|
||||
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
inliningFunction as KtNamedFunction?, parentCodegen, asmMethod
|
||||
)
|
||||
smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.orCreateSourceMapper.resultMappings)
|
||||
createSMAPWithDefaultMapping(inliningFunction, parentCodegen.orCreateSourceMapper.resultMappings)
|
||||
}
|
||||
else {
|
||||
smap = generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction!!, jvmSignature, null)
|
||||
generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction!!, jvmSignature, null)
|
||||
}
|
||||
maxCalcAdapter.visitMaxs(-1, -1)
|
||||
maxCalcAdapter.visitEnd()
|
||||
|
||||
@@ -561,7 +561,6 @@ public interface Errors {
|
||||
// Multi-platform projects
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> EXPECTED_DECLARATION_WITH_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtParameter> EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtConstructorDelegationCall> EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtParameter> EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtConstructor<?>> EXPECTED_ENUM_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
|
||||
@@ -571,7 +570,6 @@ public interface Errors {
|
||||
DiagnosticFactory0<PsiElement> EXPECTED_LATEINIT_PROPERTY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> EXPECTED_PRIVATE_DECLARATION = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtDelegatedSuperTypeEntry> IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_NOT_TO_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
@@ -579,6 +577,9 @@ public interface Errors {
|
||||
ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtTypeAlias> ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<PsiElement> ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory3<KtNamedDeclaration, MemberDescriptor, ModuleDescriptor,
|
||||
Map<Incompatible, Collection<MemberDescriptor>>> NO_ACTUAL_FOR_EXPECT =
|
||||
|
||||
@@ -157,8 +157,7 @@ object PositioningStrategies {
|
||||
callableDeclaration?.let { it.receiverTypeReference ?: it.valueParameterList }
|
||||
}
|
||||
ParameterCount, ParameterTypes, ParameterNames,
|
||||
ValueParameterHasDefault, ValueParameterVararg,
|
||||
ValueParameterNoinline, ValueParameterCrossinline -> {
|
||||
ValueParameterVararg, ValueParameterNoinline, ValueParameterCrossinline -> {
|
||||
callableDeclaration?.valueParameterList
|
||||
}
|
||||
ReturnType -> {
|
||||
|
||||
+5
-1
@@ -236,7 +236,6 @@ public class DefaultErrorMessages {
|
||||
MAP.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE);
|
||||
|
||||
MAP.put(EXPECTED_DECLARATION_WITH_BODY, "Expected declaration must not have a body");
|
||||
MAP.put(EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER, "Expected declaration cannot have parameters with default values");
|
||||
MAP.put(EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL, "Explicit delegation call for constructor of an expected class is not allowed");
|
||||
MAP.put(EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, "Expected class constructor cannot have a property parameter");
|
||||
MAP.put(EXPECTED_ENUM_CONSTRUCTOR, "Expected enum class cannot have a constructor");
|
||||
@@ -253,6 +252,11 @@ public class DefaultErrorMessages {
|
||||
MAP.put(ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE, "Aliased class should not have type parameters with declaration-site variance");
|
||||
MAP.put(ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of actual type alias cannot contain use-site variance or star projections");
|
||||
MAP.put(ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of actual type alias should be its type parameters in the same order, e.g. 'actual typealias Foo<A, B> = Bar<A, B>'");
|
||||
MAP.put(ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, "Actual function cannot have default argument values, they should be declared in the expected function");
|
||||
|
||||
MAP.put(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND,
|
||||
"Expected function source is not found, therefore it's impossible to generate default argument values declared there. " +
|
||||
"Please add the corresponding file to compilation sources");
|
||||
|
||||
MAP.put(NO_ACTUAL_FOR_EXPECT, "Expected {0} has no actual declaration in module{1}{2}", DECLARATION_NAME_WITH_KIND,
|
||||
PLATFORM, PlatformIncompatibilityDiagnosticRenderer.TEXT);
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -246,6 +247,10 @@ class DeclarationsChecker(
|
||||
checkVarargParameters(trace, constructorDescriptor)
|
||||
checkConstructorVisibility(constructorDescriptor, declaration)
|
||||
checkExpectedClassConstructor(constructorDescriptor, declaration)
|
||||
|
||||
if (constructorDescriptor.isActual) {
|
||||
checkActualFunction(declaration, constructorDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkExpectedClassConstructor(constructorDescriptor: ClassConstructorDescriptor, declaration: KtConstructor<*>) {
|
||||
@@ -765,6 +770,9 @@ class DeclarationsChecker(
|
||||
if (functionDescriptor.isExpect) {
|
||||
checkExpectedFunction(function, functionDescriptor)
|
||||
}
|
||||
if (functionDescriptor.isActual) {
|
||||
checkActualFunction(function, functionDescriptor)
|
||||
}
|
||||
|
||||
shadowedExtensionChecker.checkDeclaration(function, functionDescriptor)
|
||||
}
|
||||
@@ -774,13 +782,17 @@ class DeclarationsChecker(
|
||||
trace.report(EXPECTED_DECLARATION_WITH_BODY.on(function))
|
||||
}
|
||||
|
||||
for (parameter in function.valueParameters) {
|
||||
if (parameter.hasDefaultValue()) {
|
||||
trace.report(EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER.on(parameter))
|
||||
checkPrivateExpectedDeclaration(function, functionDescriptor)
|
||||
}
|
||||
|
||||
private fun checkActualFunction(element: KtDeclaration, functionDescriptor: FunctionDescriptor) {
|
||||
for (valueParameter in functionDescriptor.valueParameters) {
|
||||
if (valueParameter.declaresDefaultValue()) {
|
||||
trace.report(
|
||||
ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS.on(DescriptorToSourceUtils.descriptorToDeclaration(valueParameter) ?: element)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
checkPrivateExpectedDeclaration(function, functionDescriptor)
|
||||
}
|
||||
|
||||
private fun checkImplicitCallableType(declaration: KtCallableDeclaration, descriptor: CallableDescriptor) {
|
||||
|
||||
+4
-3
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.AnalyzerExtensions
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
|
||||
class InlineAnalyzerExtension(
|
||||
private val reasonableInlineRules: Iterable<ReasonableInlineRule>,
|
||||
@@ -95,9 +96,9 @@ class InlineAnalyzerExtension(
|
||||
if (parameter.hasDefaultValue()) {
|
||||
val ktParameter = ktParameters[parameter.index]
|
||||
//Always report unsupported error on functional parameter with inherited default (there are some problems with inlining)
|
||||
val inheritDefaultValues = !parameter.declaresDefaultValue()
|
||||
if (checkInlinableParameter(parameter, ktParameter, functionDescriptor, null) || inheritDefaultValues) {
|
||||
if (inheritDefaultValues || !languageVersionSettings.supportsFeature(LanguageFeature.InlineDefaultFunctionalParameters)) {
|
||||
val inheritsDefaultValue = !parameter.declaresDefaultValue() && parameter.declaresOrInheritsDefaultValue()
|
||||
if (checkInlinableParameter(parameter, ktParameter, functionDescriptor, null) || inheritsDefaultValue) {
|
||||
if (inheritsDefaultValue || !languageVersionSettings.supportsFeature(LanguageFeature.InlineDefaultFunctionalParameters)) {
|
||||
trace.report(
|
||||
Errors.NOT_YET_SUPPORTED_IN_INLINE.on(
|
||||
ktParameter,
|
||||
|
||||
+23
-3
@@ -19,16 +19,19 @@ package org.jetbrains.kotlin.resolve.calls.components
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
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.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
internal fun unexpectedArgument(argument: KotlinCallArgument): Nothing =
|
||||
@@ -59,12 +62,29 @@ val ValueParameterDescriptor.isVararg: Boolean get() = varargElementType != null
|
||||
val ParameterDescriptor.isVararg: Boolean get() = this.safeAs<ValueParameterDescriptor>()?.isVararg ?: false
|
||||
|
||||
/**
|
||||
* @return `true` iff the parameter has a default value, i.e. declares it or inherits by overriding a parameter which has a default value.
|
||||
* @return `true` iff the parameter has a default value, i.e. declares it, inherits it by overriding a parameter which has a default value,
|
||||
* or is a parameter of an 'actual' declaration, such that the corresponding 'expect' parameter has a default value.
|
||||
*/
|
||||
fun ValueParameterDescriptor.hasDefaultValue(): Boolean {
|
||||
return declaresOrInheritsDefaultValue()
|
||||
return DFS.ifAny(
|
||||
listOf(this),
|
||||
{ current -> current.overriddenDescriptors.map(ValueParameterDescriptor::getOriginal) },
|
||||
{ it.declaresDefaultValue() || it.isActualParameterWithExpectedDefault }
|
||||
)
|
||||
}
|
||||
|
||||
private 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()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun KotlinCallArgument.isArrayAssignedAsNamedArgumentInAnnotation(
|
||||
parameter: ParameterDescriptor,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
-2
@@ -172,7 +172,6 @@ object ExpectedActualResolver {
|
||||
object ParameterNames : Incompatible("parameter names are different")
|
||||
object TypeParameterNames : Incompatible("names of type parameters are different")
|
||||
|
||||
object ValueParameterHasDefault : Incompatible("some parameters have default values")
|
||||
object ValueParameterVararg : Incompatible("some value parameter is vararg in one declaration and non-vararg in the other")
|
||||
object ValueParameterNoinline : Incompatible("some value parameter is noinline in one declaration and not noinline in the other")
|
||||
object ValueParameterCrossinline : Incompatible("some value parameter is crossinline in one declaration and not crossinline in the other")
|
||||
@@ -257,7 +256,6 @@ object ExpectedActualResolver {
|
||||
|
||||
areCompatibleTypeParameters(aTypeParams, bTypeParams, platformModule, substitutor).let { if (it != Compatible) return it }
|
||||
|
||||
if (!equalsBy(aParams, bParams, ValueParameterDescriptor::declaresDefaultValue)) return Incompatible.ValueParameterHasDefault
|
||||
if (!equalsBy(aParams, bParams, { p -> listOf(p.varargElementType != null) })) return Incompatible.ValueParameterVararg
|
||||
|
||||
// Adding noinline/crossinline to parameters is disallowed, except if the expected declaration was not inline at all
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
|
||||
expect class Foo(a: String, b: Int = 0, c: Double? = null)
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
actual class Foo actual constructor(a: String, b: Int, c: Double?) {
|
||||
val result: String = a + "," + b + "," + c
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("OK,0,null", Foo("OK").result)
|
||||
assertEquals("OK,42,null", Foo("OK", 42).result)
|
||||
assertEquals("OK,42,3.14", Foo("OK", 42, 3.14).result)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
|
||||
expect fun topLevel(a: String, b: Int = 0, c: Double? = null): String
|
||||
|
||||
expect class Foo() {
|
||||
fun member(a: String, b: Int = 0, c: Double? = null): String
|
||||
}
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
actual fun topLevel(a: String, b: Int, c: Double?): String = a + "," + b + "," + c
|
||||
|
||||
actual class Foo actual constructor() {
|
||||
actual fun member(a: String, b: Int, c: Double?): String = a + "," + b + "," + c
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("OK,0,null", topLevel("OK"))
|
||||
assertEquals("OK,42,null", topLevel("OK", 42))
|
||||
assertEquals("OK,42,3.14", topLevel("OK", 42, 3.14))
|
||||
|
||||
val foo = Foo()
|
||||
assertEquals("OK,0,null", foo.member("OK"))
|
||||
assertEquals("OK,42,null", foo.member("OK", 42))
|
||||
assertEquals("OK,42,3.14", foo.member("OK", 42, 3.14))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
|
||||
open class A() {
|
||||
fun member(a: String, b: Int = 0, c: Double? = null): String = a + "," + b + "," + c
|
||||
}
|
||||
|
||||
expect class B() : A
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
actual class B actual constructor() : A()
|
||||
|
||||
fun box(): String {
|
||||
val b = B()
|
||||
assertEquals("OK,0,null", b.member("OK"))
|
||||
assertEquals("OK,42,null", b.member("OK", 42))
|
||||
assertEquals("OK,42,3.14", b.member("OK", 42, 3.14))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
|
||||
expect open class A() {
|
||||
fun member(a: String, b: Int = 0, c: Double? = null): String
|
||||
}
|
||||
|
||||
expect class B() : A
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
actual open class A actual constructor() {
|
||||
actual fun member(a: String, b: Int, c: Double?): String = a + "," + b + "," + c
|
||||
}
|
||||
|
||||
actual class B actual constructor() : A()
|
||||
|
||||
fun box(): String {
|
||||
val b = B()
|
||||
assertEquals("OK,0,null", b.member("OK"))
|
||||
assertEquals("OK,42,null", b.member("OK", 42))
|
||||
assertEquals("OK,42,3.14", b.member("OK", 42, 3.14))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
|
||||
expect inline fun topLevel(a: String, b: Int = 0, c: () -> Double? = { null }): String
|
||||
|
||||
expect class Foo() {
|
||||
inline fun member(a: String, b: Int = 0, c: () -> Double? = { null }): String
|
||||
}
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
actual inline fun topLevel(a: String, b: Int, c: () -> Double?): String = a + "," + b + "," + c()
|
||||
|
||||
actual class Foo actual constructor() {
|
||||
actual inline fun member(a: String, b: Int, c: () -> Double?): String = a + "," + b + "," + c()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("OK,0,null", topLevel("OK"))
|
||||
assertEquals("OK,42,null", topLevel("OK", 42))
|
||||
assertEquals("OK,42,3.14", topLevel("OK", 42, { 3.14 }))
|
||||
|
||||
val foo = Foo()
|
||||
assertEquals("OK,0,null", foo.member("OK"))
|
||||
assertEquals("OK,42,null", foo.member("OK", 42))
|
||||
assertEquals("OK,42,3.14", foo.member("OK", 42, { 3.14 }))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
expect class Ok(x: Int, y: String = "")
|
||||
|
||||
expect class FailX(x: Int, y: String = "")
|
||||
|
||||
expect class FailY(x: Int, y: String = "")
|
||||
|
||||
fun test() {
|
||||
Ok(42)
|
||||
Ok(42, "OK")
|
||||
}
|
||||
|
||||
// MODULE: m2-jvm(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual class Ok actual constructor(x: Int, y: String)
|
||||
|
||||
actual class FailX actual constructor(<!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>x: Int = 0<!>, y: String)
|
||||
|
||||
actual class FailY actual constructor(x: Int, <!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>y: String = ""<!>)
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// -- Module: <m1-common> --
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final expect class FailX {
|
||||
public constructor FailX(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final expect class FailY {
|
||||
public constructor FailY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final expect class Ok {
|
||||
public constructor Ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m2-jvm> --
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final actual class FailX {
|
||||
public constructor FailX(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final actual class FailY {
|
||||
public constructor FailY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final actual class Ok {
|
||||
public constructor Ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
expect fun ok(x: Int, y: String = "")
|
||||
|
||||
expect fun failX(x: Int, y: String = "")
|
||||
|
||||
expect fun failY(x: Int, y: String = "")
|
||||
|
||||
expect open class Foo {
|
||||
fun ok(x: Int, y: String = "")
|
||||
|
||||
fun failX(x: Int, y: String = "")
|
||||
|
||||
fun failY(x: Int, y: String = "")
|
||||
}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
ok(42)
|
||||
ok(42, "OK")
|
||||
foo.ok(42)
|
||||
foo.ok(42, "OK")
|
||||
}
|
||||
|
||||
// MODULE: m2-jvm(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual fun ok(x: Int, y: String) {}
|
||||
|
||||
actual fun failX(<!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>x: Int = 0<!>, y: String) {}
|
||||
|
||||
actual fun failY(x: Int, <!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>y: String = ""<!>) {}
|
||||
|
||||
actual open class Foo {
|
||||
actual fun ok(x: Int, y: String) {}
|
||||
|
||||
actual fun failX(<!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>x: Int = 0<!>, y: String) {}
|
||||
|
||||
actual fun failY(x: Int, <!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>y: String = ""<!>) {}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// -- Module: <m1-common> --
|
||||
package
|
||||
|
||||
public expect fun failX(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public expect fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public expect fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public fun test(/*0*/ foo: Foo): kotlin.Unit
|
||||
|
||||
public open expect class Foo {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final expect fun failX(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public final expect fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final expect fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m2-jvm> --
|
||||
package
|
||||
|
||||
public actual fun failX(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String): kotlin.Unit
|
||||
public actual fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public actual fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String): kotlin.Unit
|
||||
public fun test(/*0*/ foo: Foo): kotlin.Unit
|
||||
|
||||
public open actual class Foo {
|
||||
public constructor Foo()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final actual fun failX(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String): kotlin.Unit
|
||||
public final actual fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final actual fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
interface Foo {
|
||||
fun ok(x: Int, y: String = "")
|
||||
|
||||
fun failX(x: Int, y: String = "")
|
||||
|
||||
fun failY(x: Int, y: String = "")
|
||||
}
|
||||
|
||||
expect class Bar : Foo {
|
||||
override fun ok(x: Int, y: String)
|
||||
|
||||
override fun failX(x: Int, y: String)
|
||||
|
||||
override fun failY(x: Int, y: String)
|
||||
}
|
||||
|
||||
fun test(foo: Foo, bar: Bar) {
|
||||
foo.ok(42)
|
||||
foo.ok(42, "OK")
|
||||
bar.ok(42)
|
||||
bar.ok(42, "OK")
|
||||
}
|
||||
|
||||
// MODULE: m2-jvm(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual class Bar : Foo {
|
||||
actual override fun ok(x: Int, y: String) {}
|
||||
|
||||
actual override fun failX(<!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>x: Int = <!DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE!>0<!><!>, y: String) {}
|
||||
|
||||
actual override fun failY(x: Int, <!ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS!>y: String = <!DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE!>""<!><!>) {}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// -- Module: <m1-common> --
|
||||
package
|
||||
|
||||
public fun test(/*0*/ foo: Foo, /*1*/ bar: Bar): kotlin.Unit
|
||||
|
||||
public final expect class Bar : Foo {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open expect override /*1*/ fun failX(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open expect override /*1*/ fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open expect override /*1*/ fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface Foo {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun failX(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public abstract fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public abstract fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m2-jvm> --
|
||||
package
|
||||
|
||||
public fun test(/*0*/ foo: Foo, /*1*/ bar: Bar): kotlin.Unit
|
||||
|
||||
public final actual class Bar : Foo {
|
||||
public constructor Bar()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open actual override /*1*/ fun failX(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open actual override /*1*/ fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open actual override /*1*/ fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface Foo {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun failX(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public abstract fun failY(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public abstract fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
expect fun ok(x: Int, y: String = "")
|
||||
|
||||
// MODULE: m2-jvm(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual fun ok(x: Int, y: String) {}
|
||||
|
||||
fun ok(x: Int, y: Long = 1L) {}
|
||||
|
||||
fun test() {
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>ok<!>(1)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// -- Module: <m1-common> --
|
||||
package
|
||||
|
||||
public expect fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
|
||||
|
||||
// -- Module: <m2-jvm> --
|
||||
package
|
||||
|
||||
public fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Long = ...): kotlin.Unit
|
||||
public actual fun ok(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
Vendored
-2
@@ -21,8 +21,6 @@ expect class Foo(
|
||||
<!EXPECTED_DECLARATION_WITH_BODY!>get()<!> = "no"
|
||||
<!EXPECTED_DECLARATION_WITH_BODY!>set(value)<!> {}
|
||||
|
||||
fun defaultArg(<!EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER!>value: String = "no"<!>)
|
||||
|
||||
<!EXPECTED_DECLARATION_WITH_BODY!>fun functionWithBody(x: Int): Int<!> {
|
||||
return x + 1
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -7,7 +7,6 @@ public final expect class Foo {
|
||||
public expect final val constructorProperty: kotlin.String
|
||||
public expect final var getSet: kotlin.String
|
||||
public expect final val prop: kotlin.String = "no"
|
||||
public final expect fun defaultArg(/*0*/ value: kotlin.String = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final expect fun functionWithBody(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
expect fun foo(x: Int, <!EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER!>y: String = ""<!>)
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
package
|
||||
|
||||
public expect fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
@@ -164,12 +164,9 @@ The following declaration is incompatible because some type parameter is reified
|
||||
|
||||
actual inline fun <reified X> f14() {}
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/jvm.kt:26:15: error: actual function 'f16' has no corresponding expected declaration
|
||||
The following declaration is incompatible because some parameters have default values:
|
||||
public expect fun f16(s: String): Unit
|
||||
|
||||
compiler/testData/multiplatform/incompatibleCallables/jvm.kt:26:16: error: actual function cannot have default argument values, they should be declared in the expected function
|
||||
actual fun f16(s: String = "") {}
|
||||
^
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/jvm.kt:28:15: error: actual function 'f17' has no corresponding expected declaration
|
||||
The following declaration is incompatible because some value parameter is vararg in one declaration and non-vararg in the other:
|
||||
public expect fun f17(vararg s: String): Unit
|
||||
|
||||
Generated
+48
@@ -12646,6 +12646,54 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Multiplatform extends AbstractIrBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArguments extends AbstractIrBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInDefaultArguments() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("function.kt")
|
||||
public void testFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromCommonClass.kt")
|
||||
public void testInheritedFromCommonClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromCommonClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromExpectedClass.kt")
|
||||
public void testInheritedFromExpectedClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionWithDefaultLambda.kt")
|
||||
public void testInlineFunctionWithDefaultLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/nonLocalReturns")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+33
-6
@@ -14228,6 +14228,39 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArguments extends AbstractDiagnosticsTest {
|
||||
public void testAllFilesPresentInDefaultArguments() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedDeclaresDefaultArguments.kt")
|
||||
public void testExpectedDeclaresDefaultArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedInheritsDefaultArguments.kt")
|
||||
public void testExpectedInheritsDefaultArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedVsNonExpectedWithDefaults.kt")
|
||||
public void testExpectedVsNonExpectedWithDefaults() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/deprecated")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -14545,12 +14578,6 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArguments.kt")
|
||||
public void testDefaultArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/defaultArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionModifiers.kt")
|
||||
public void testFunctionModifiers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/functionModifiers.kt");
|
||||
|
||||
Generated
+33
-6
@@ -14228,6 +14228,39 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArguments extends AbstractDiagnosticsUsingJavacTest {
|
||||
public void testAllFilesPresentInDefaultArguments() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedDeclaresDefaultArguments.kt")
|
||||
public void testExpectedDeclaresDefaultArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedInheritsDefaultArguments.kt")
|
||||
public void testExpectedInheritsDefaultArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedVsNonExpectedWithDefaults.kt")
|
||||
public void testExpectedVsNonExpectedWithDefaults() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/deprecated")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -14545,12 +14578,6 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArguments.kt")
|
||||
public void testDefaultArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/defaultArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionModifiers.kt")
|
||||
public void testFunctionModifiers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun/functionModifiers.kt");
|
||||
|
||||
+48
@@ -12646,6 +12646,54 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Multiplatform extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArguments extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInDefaultArguments() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("function.kt")
|
||||
public void testFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromCommonClass.kt")
|
||||
public void testInheritedFromCommonClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromCommonClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromExpectedClass.kt")
|
||||
public void testInheritedFromExpectedClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionWithDefaultLambda.kt")
|
||||
public void testInlineFunctionWithDefaultLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/nonLocalReturns")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+48
@@ -12646,6 +12646,54 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Multiplatform extends AbstractLightAnalysisModeTest {
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArguments extends AbstractLightAnalysisModeTest {
|
||||
public void testAllFilesPresentInDefaultArguments() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("function.kt")
|
||||
public void testFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromCommonClass.kt")
|
||||
public void testInheritedFromCommonClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromCommonClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromExpectedClass.kt")
|
||||
public void testInheritedFromExpectedClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionWithDefaultLambda.kt")
|
||||
public void testInlineFunctionWithDefaultLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/nonLocalReturns")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
-1
@@ -63,7 +63,6 @@ class MigrateDiagnosticSuppressionInspection : AbstractKotlinInspection(), Clean
|
||||
|
||||
private val MIGRATION_MAP = mapOf(
|
||||
"HEADER_DECLARATION_WITH_BODY" to EXPECTED_DECLARATION_WITH_BODY,
|
||||
"HEADER_DECLARATION_WITH_DEFAULT_PARAMETER" to EXPECTED_DECLARATION_WITH_DEFAULT_PARAMETER,
|
||||
"HEADER_CLASS_CONSTRUCTOR_DELEGATION_CALL" to EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL,
|
||||
"HEADER_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER" to EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER,
|
||||
"HEADER_ENUM_CONSTRUCTOR" to EXPECTED_ENUM_CONSTRUCTOR,
|
||||
|
||||
+48
@@ -13732,6 +13732,54 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Multiplatform extends AbstractJsCodegenBoxTest {
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArguments extends AbstractJsCodegenBoxTest {
|
||||
public void testAllFilesPresentInDefaultArguments() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("function.kt")
|
||||
public void testFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromCommonClass.kt")
|
||||
public void testInheritedFromCommonClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromCommonClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFromExpectedClass.kt")
|
||||
public void testInheritedFromExpectedClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionWithDefaultLambda.kt")
|
||||
public void testInlineFunctionWithDefaultLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/nonLocalReturns")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+27
-5
@@ -17,12 +17,15 @@
|
||||
package org.jetbrains.kotlin.js.translate.utils;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties;
|
||||
import org.jetbrains.kotlin.js.naming.NameSuggestion;
|
||||
@@ -35,6 +38,7 @@ import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression;
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
@@ -74,18 +78,36 @@ public final class FunctionBodyTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsStatement> setDefaultValueForArguments(@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull TranslationContext functionBodyContext) {
|
||||
List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters();
|
||||
public static List<JsStatement> setDefaultValueForArguments(
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
List<ValueParameterDescriptor> originalParameters = descriptor.getValueParameters();
|
||||
List<ValueParameterDescriptor> valueParameters;
|
||||
if (descriptor.isActual() && CollectionsKt.none(originalParameters, ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(descriptor);
|
||||
if (expected != null) {
|
||||
valueParameters = expected.getValueParameters();
|
||||
}
|
||||
else {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||
assert element != null : "No element found for descriptor: " + descriptor;
|
||||
context.bindingTrace().report(Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(element));
|
||||
valueParameters = originalParameters;
|
||||
}
|
||||
}
|
||||
else {
|
||||
valueParameters = originalParameters;
|
||||
}
|
||||
|
||||
List<JsStatement> result = new ArrayList<>(valueParameters.size());
|
||||
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||
if (!valueParameter.declaresDefaultValue()) continue;
|
||||
|
||||
JsExpression jsNameRef = ReferenceTranslator.translateAsValueReference(valueParameter, functionBodyContext);
|
||||
JsExpression jsNameRef = ReferenceTranslator.translateAsValueReference(valueParameter, context);
|
||||
KtExpression defaultArgument = BindingUtils.getDefaultArgument(valueParameter);
|
||||
JsBlock defaultArgBlock = new JsBlock();
|
||||
JsExpression defaultValue = Translation.translateAsExpression(defaultArgument, functionBodyContext, defaultArgBlock);
|
||||
JsExpression defaultValue = Translation.translateAsExpression(defaultArgument, context, defaultArgBlock);
|
||||
PsiElement psi = KotlinSourceElementKt.getPsi(valueParameter.getSource());
|
||||
JsStatement assignStatement = assignment(jsNameRef, defaultValue).source(psi).makeStmt();
|
||||
JsStatement thenStatement = JsAstUtils.mergeStatementInBlockIfNeeded(assignStatement, defaultArgBlock);
|
||||
|
||||
Reference in New Issue
Block a user