Extract logic to get function parameters for default value generation
For some reason, this logic was a bit different in JVM (FunctionCodegen) and JS (FunctionBodyTranslator). For example, in JS the EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND diagnostic was reported even in the case when no expected function was found for the actual function at all, which made it quite difficult to write multiplatform sources for JS stdlib where it both should be compiled as a part of the multiplatform project, and by itself (suppressing NO_ACTUAL_FOR_EXPECT): in the latter case, the new error must have been suppressed everywhere as well #KT-21913
This commit is contained in:
@@ -20,11 +20,14 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
@@ -175,4 +178,29 @@ object CodegenUtil {
|
||||
}
|
||||
return compatibleExpectedFunctions.firstOrNull() as FunctionDescriptor?
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getFunctionParametersForDefaultValueGeneration(
|
||||
descriptor: FunctionDescriptor,
|
||||
trace: DiagnosticSink?
|
||||
): List<ValueParameterDescriptor> {
|
||||
if (descriptor.isActual) {
|
||||
val expected = CodegenUtil.findExpectedFunctionForActual(descriptor)
|
||||
if (expected != null && expected.valueParameters.any(ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(expected)
|
||||
if (element == null) {
|
||||
if (trace != null) {
|
||||
val actualDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
|
||||
?: error("Not a source declaration: $descriptor")
|
||||
trace.report(Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(actualDeclaration))
|
||||
}
|
||||
return descriptor.valueParameters
|
||||
}
|
||||
|
||||
return expected.valueParameters
|
||||
}
|
||||
}
|
||||
|
||||
return descriptor.valueParameters
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ 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;
|
||||
@@ -1110,16 +1109,9 @@ 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;
|
||||
}
|
||||
// 'null' because the "could not find expected declaration" error has been already reported in isDefaultNeeded earlier
|
||||
List<ValueParameterDescriptor> valueParameters =
|
||||
CodegenUtil.getFunctionParametersForDefaultValueGeneration(functionDescriptor, null);
|
||||
|
||||
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
|
||||
FrameMap frameMap = createFrameMap(state, signature, functionDescriptor.getExtensionReceiverParameter(), valueParameters, isStatic);
|
||||
@@ -1260,22 +1252,9 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
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 CollectionsKt.any(descriptor.getValueParameters(), ValueParameterDescriptor::declaresDefaultValue);
|
||||
List<ValueParameterDescriptor> parameters =
|
||||
CodegenUtil.getFunctionParametersForDefaultValueGeneration(descriptor, state.getDiagnostics());
|
||||
return CollectionsKt.any(parameters, ValueParameterDescriptor::declaresDefaultValue);
|
||||
}
|
||||
|
||||
private void generateBridge(
|
||||
|
||||
+2
-19
@@ -17,7 +17,6 @@
|
||||
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;
|
||||
@@ -25,7 +24,6 @@ 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;
|
||||
@@ -38,7 +36,6 @@ 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;
|
||||
|
||||
@@ -83,22 +80,8 @@ public final class FunctionBodyTranslator extends AbstractTranslator {
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters();
|
||||
List<ValueParameterDescriptor> valueParametersForDefaultValue;
|
||||
if (descriptor.isActual() && CollectionsKt.none(valueParameters, ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(descriptor);
|
||||
if (expected != null) {
|
||||
valueParametersForDefaultValue = 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));
|
||||
valueParametersForDefaultValue = valueParameters;
|
||||
}
|
||||
}
|
||||
else {
|
||||
valueParametersForDefaultValue = valueParameters;
|
||||
}
|
||||
List<ValueParameterDescriptor> valueParametersForDefaultValue =
|
||||
CodegenUtil.getFunctionParametersForDefaultValueGeneration(descriptor, context.bindingTrace());
|
||||
|
||||
List<JsStatement> result = new ArrayList<>(valueParameters.size());
|
||||
for (int i = 0; i < valueParameters.size(); i++) {
|
||||
|
||||
Reference in New Issue
Block a user