diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java index 181e014845b..7a73cfd1325 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorUtil.java @@ -19,24 +19,15 @@ package org.jetbrains.kotlin.resolve; import kotlin.Unit; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl; -import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; -import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl; -import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.kotlin.resolve.scopes.*; import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class FunctionDescriptorUtil { private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitution() { - @Override public TypeProjection get(@NotNull KotlinType key) { return null; @@ -61,7 +52,9 @@ public class FunctionDescriptorUtil { } @NotNull - public static LexicalScope getFunctionInnerScope(@NotNull LexicalScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) { + public static LexicalScope getFunctionInnerScope( + @NotNull LexicalScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace + ) { return getFunctionInnerScope(outerScope, descriptor, new TraceBasedLocalRedeclarationChecker(trace)); } @@ -87,81 +80,8 @@ public class FunctionDescriptorUtil { }); } - public static void initializeFromFunctionType( - @NotNull FunctionDescriptorImpl functionDescriptor, - @NotNull KotlinType functionType, - @Nullable ReceiverParameterDescriptor dispatchReceiverParameter, - @NotNull Modality modality, - @NotNull Visibility visibility - ) { - - assert KotlinBuiltIns.isFunctionOrExtensionFunctionType(functionType); - functionDescriptor.initialize(KotlinBuiltIns.getReceiverType(functionType), - dispatchReceiverParameter, - Collections.emptyList(), - KotlinBuiltIns.getValueParameters(functionDescriptor, functionType), - KotlinBuiltIns.getReturnTypeFromFunctionType(functionType), - modality, - visibility); - } - + @SuppressWarnings("unchecked") public static D alphaConvertTypeParameters(D candidate) { return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH); } - - /** - * Returns function's copy with new parameter list. Note that parameters may belong to other methods or have incorrect "index" property - * -- it will be fixed by this function. - */ - @NotNull - public static FunctionDescriptor replaceFunctionParameters( - @NotNull FunctionDescriptor function, - @NotNull List newParameters - ) { - FunctionDescriptorImpl descriptor = SimpleFunctionDescriptorImpl.create( - function.getContainingDeclaration(), - function.getAnnotations(), - function.getName(), - function.getKind(), - SourceElement.NO_SOURCE - ); - List parameters = new ArrayList(newParameters.size()); - int idx = 0; - for (ValueParameterDescriptor parameter : newParameters) { - KotlinType returnType = parameter.getReturnType(); - assert returnType != null; - - parameters.add( - new ValueParameterDescriptorImpl( - descriptor, - null, - idx, - parameter.getAnnotations(), - parameter.getName(), - returnType, - parameter.declaresDefaultValue(), - parameter.isCrossinline(), - parameter.isNoinline(), - parameter.getVarargElementType(), - SourceElement.NO_SOURCE - ) - ); - idx++; - } - ReceiverParameterDescriptor receiver = function.getExtensionReceiverParameter(); - descriptor.initialize( - receiver == null ? null : receiver.getType(), - function.getDispatchReceiverParameter(), - function.getTypeParameters(), - parameters, - function.getReturnType(), - function.getModality(), - function.getVisibility()); - descriptor.setOperator(function.isOperator()); - descriptor.setInfix(function.isInfix()); - descriptor.setExternal(function.isExternal()); - descriptor.setInline(function.isInline()); - descriptor.setTailrec(function.isTailrec()); - return descriptor; - } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt index b361b66c340..281d7a03097 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt @@ -28,7 +28,10 @@ import org.jetbrains.kotlin.psi.KtCallableReferenceExpression import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.ValueArgument -import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.TypeResolver import org.jetbrains.kotlin.resolve.calls.CallResolver import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext @@ -39,9 +42,9 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil import org.jetbrains.kotlin.resolve.calls.util.CallMaker import org.jetbrains.kotlin.resolve.scopes.BaseLexicalScope -import org.jetbrains.kotlin.resolve.scopes.ScopeUtils import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.resolve.scopes.ScopeUtils import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope @@ -199,14 +202,23 @@ private fun createReflectionTypeForProperty( return reflectionTypes.getKPropertyType(Annotations.EMPTY, receiverType, descriptor.type, descriptor.isVar) } -private fun bindFunctionReference(expression: KtCallableReferenceExpression, referenceType: KotlinType, context: ResolutionContext<*>) { +private fun bindFunctionReference(expression: KtCallableReferenceExpression, type: KotlinType, context: ResolutionContext<*>) { val functionDescriptor = AnonymousFunctionDescriptor( context.scope.ownerDescriptor, Annotations.EMPTY, CallableMemberDescriptor.Kind.DECLARATION, - expression.toSourceElement()) + expression.toSourceElement() + ) - FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, referenceType, null, Modality.FINAL, Visibilities.PUBLIC) + functionDescriptor.initialize( + KotlinBuiltIns.getReceiverType(type), + null, + emptyList(), + KotlinBuiltIns.getValueParameters(functionDescriptor, type), + KotlinBuiltIns.getReturnTypeFromFunctionType(type), + Modality.FINAL, + Visibilities.PUBLIC + ) context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt index fc4fc3d2aa4..4f35d6b5ce7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt @@ -27,6 +27,8 @@ import com.intellij.openapi.ui.popup.util.BaseListPopupStep import com.intellij.psi.PsiDocumentManager import com.intellij.util.PlatformIcons import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -37,9 +39,8 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtParameterList import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.ClassifierNamePolicy -import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil +import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden import org.jetbrains.kotlin.resolve.findMemberWithMaxVisibility import org.jetbrains.kotlin.types.checker.KotlinTypeChecker @@ -122,7 +123,7 @@ class ChangeMemberFunctionSignatureFix private constructor( matchParameters(ParameterChooser.MatchNames, superParameters, parameters, newParameters, matched, used) matchParameters(ParameterChooser.MatchTypes, superParameters, parameters, newParameters, matched, used) - val newFunction = FunctionDescriptorUtil.replaceFunctionParameters( + val newFunction = replaceFunctionParameters( superFunction.copy( function.containingDeclaration, Modality.OPEN, @@ -183,6 +184,44 @@ class ChangeMemberFunctionSignatureFix private constructor( .flatMap { supertype -> supertype.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE) } .filter { it.kind.isReal && it.isOverridable } } + + /** + * Returns function's copy with new parameter list. + * Note that parameters may belong to other methods or have incorrect "index" property -- it will be fixed by this function. + */ + private fun replaceFunctionParameters( + function: FunctionDescriptor, + newParameters: List + ): FunctionDescriptor { + val descriptor = SimpleFunctionDescriptorImpl.create( + function.containingDeclaration, + function.annotations, + function.name, + function.kind, + SourceElement.NO_SOURCE + ) + + val parameters = newParameters.withIndex().map { + val (index, parameter) = it + ValueParameterDescriptorImpl( + descriptor, null, index, + parameter.annotations, parameter.name, parameter.returnType!!, parameter.declaresDefaultValue(), + parameter.isCrossinline, parameter.isNoinline, parameter.varargElementType, SourceElement.NO_SOURCE + ) + } + + return descriptor.apply { + initialize( + function.extensionReceiverParameter?.type, function.dispatchReceiverParameter, + function.typeParameters, parameters, function.returnType, function.modality, function.visibility + ) + isOperator = function.isOperator + isInfix = function.isInfix + isExternal = function.isExternal + isInline = function.isInline + isTailrec = function.isTailrec + } + } } override fun getText(): String {