diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 187598e704d..396faaaaa61 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -4,7 +4,9 @@
+
+
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt
new file mode 100644
index 00000000000..9a4954f2115
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.resolve.callableReferences
+
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.builtins.ReflectionTypes
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.descriptors.annotations.Annotations
+import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
+import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
+import org.jetbrains.kotlin.resolve.calls.CallResolver
+import org.jetbrains.kotlin.resolve.calls.context.*
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
+import org.jetbrains.kotlin.resolve.calls.util.CallMaker
+import org.jetbrains.kotlin.resolve.scopes.JetScope
+import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
+import org.jetbrains.kotlin.types.JetType
+import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
+import org.jetbrains.kotlin.utils.ThrowingList
+
+import org.jetbrains.kotlin.diagnostics.Errors.*
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.resolve.*
+import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil
+import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
+import org.jetbrains.kotlin.resolve.source.toSourceElement
+import org.jetbrains.kotlin.types.ErrorUtils
+import org.jetbrains.kotlin.types.TypeUtils
+import org.jetbrains.kotlin.types.expressions.ExpressionTypingComponents
+import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
+
+public fun resolveCallableReferenceReceiverType(
+ callableReferenceExpression: JetCallableReferenceExpression,
+ context: ResolutionContext<*>,
+ typeResolver: TypeResolver
+): JetType? =
+ callableReferenceExpression.getTypeReference()?.let {
+ typeResolver.resolveType(context.scope, it, context.trace, false)
+ }
+
+private fun ResolveArgumentsMode.acceptResolution(results: OverloadResolutionResults, trace: TemporaryTraceAndCache) {
+ when (this) {
+ ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS ->
+ if (results.isSingleResult()) trace.commit()
+ ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS ->
+ if (results.isSomething()) trace.commit()
+ }
+}
+
+private fun resolvePossiblyAmbiguousCallableReference(
+ reference: JetSimpleNameExpression,
+ receiver: ReceiverValue,
+ context: ResolutionContext<*>,
+ resolutionMode: ResolveArgumentsMode,
+ callResolver: CallResolver
+): OverloadResolutionResults {
+ val call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.instance())
+ val temporaryTrace = TemporaryTraceAndCache.create(context, "trace to resolve ::${reference.getReferencedName()} as function", reference)
+ val newContext = if (resolutionMode == ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS)
+ context.replaceTraceAndCache(temporaryTrace).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)
+ else
+ context.replaceTraceAndCache(temporaryTrace)
+ val callResolutionContext = BasicCallResolutionContext.create(
+ newContext, call, CheckArgumentTypesMode.CHECK_CALLABLE_TYPE)
+ val resolutionResults = callResolver.resolveCallForMember(reference, callResolutionContext)
+ resolutionMode.acceptResolution(resolutionResults, temporaryTrace)
+ return resolutionResults
+}
+
+private fun OverloadResolutionResults<*>.isSomething(): Boolean = !isNothing()
+
+public fun resolvePossiblyAmbiguousCallableReference(
+ callableReferenceExpression: JetCallableReferenceExpression,
+ lhsType: JetType?,
+ context: ResolutionContext<*>,
+ resolutionMode: ResolveArgumentsMode,
+ callResolver: CallResolver
+): OverloadResolutionResults? {
+ val reference = callableReferenceExpression.getCallableReference()
+
+ fun resolveInScope(traceTitle: String, scope: JetScope): OverloadResolutionResults {
+ val temporaryTraceAndCache = TemporaryTraceAndCache.create(context, traceTitle, reference)
+ val newContext = context.replaceTraceAndCache(temporaryTraceAndCache).replaceScope(scope)
+ val results = resolvePossiblyAmbiguousCallableReference(reference, ReceiverValue.NO_RECEIVER, newContext, resolutionMode, callResolver)
+ resolutionMode.acceptResolution(results, temporaryTraceAndCache)
+ return results
+ }
+
+ fun resolveWithReceiver(traceTitle: String, receiver: ReceiverValue): OverloadResolutionResults {
+ val temporaryTraceAndCache = TemporaryTraceAndCache.create(context, traceTitle, reference)
+ val newContext = context.replaceTraceAndCache(temporaryTraceAndCache)
+ val results = resolvePossiblyAmbiguousCallableReference(reference, receiver, newContext, resolutionMode, callResolver)
+ resolutionMode.acceptResolution(results, temporaryTraceAndCache)
+ return results
+ }
+
+ if (lhsType == null) {
+ return resolvePossiblyAmbiguousCallableReference(reference, ReceiverValue.NO_RECEIVER, context, resolutionMode, callResolver)
+ }
+
+ val classifier = lhsType.getConstructor().getDeclarationDescriptor()
+ if (classifier !is ClassDescriptor) {
+ context.trace.report(CALLABLE_REFERENCE_LHS_NOT_A_CLASS.on(callableReferenceExpression))
+ return null
+ }
+
+ val possibleStatic = resolveInScope("trace to resolve ::${reference.getReferencedName()} in static scope", classifier.getStaticScope())
+ if (possibleStatic.isSomething()) return possibleStatic
+
+ val possibleNested = resolveInScope("trace to resolve ::${reference.getReferencedName()} in static nested classes scope",
+ DescriptorUtils.getStaticNestedClassesScope(classifier))
+ if (possibleNested.isSomething()) return possibleNested
+
+ val possibleWithReceiver = resolveWithReceiver("trace to resolve ::${reference.getReferencedName()} with receiver",
+ TransientReceiver(lhsType))
+ if (possibleWithReceiver.isSomething()) return possibleWithReceiver
+
+ return null
+}
+
+public fun resolveCallableReferenceTarget(
+ callableReferenceExpression: JetCallableReferenceExpression,
+ lhsType: JetType?,
+ context: ResolutionContext<*>,
+ resolvedToSomething: BooleanArray,
+ callResolver: CallResolver
+): CallableDescriptor? {
+ val resolutionResults = resolvePossiblyAmbiguousCallableReference(
+ callableReferenceExpression, lhsType, context, ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS, callResolver)
+ return resolutionResults?.let { results ->
+ if (results.isSomething()) {
+ resolvedToSomething[0] = true
+ OverloadResolutionResultsUtil.getResultingCall(results, context.contextDependency)?.let { call ->
+ call.getResultingDescriptor()
+ }
+ }
+ else {
+ null
+ }
+ }
+}
+
+private fun createReflectionTypeForFunction(
+ descriptor: FunctionDescriptor,
+ receiverType: JetType?,
+ reflectionTypes: ReflectionTypes
+): JetType? {
+ val returnType = descriptor.getReturnType() ?: return null
+ val valueParametersTypes = ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters())
+ return reflectionTypes.getKFunctionType(Annotations.EMPTY, receiverType, valueParametersTypes, returnType)
+}
+
+private fun createReflectionTypeForProperty(
+ descriptor: PropertyDescriptor,
+ receiverType: JetType?,
+ reflectionTypes: ReflectionTypes
+): JetType {
+ return reflectionTypes.getKPropertyType(Annotations.EMPTY, receiverType, descriptor.getType(), descriptor.isVar())
+}
+
+private fun bindFunctionReference(expression: JetCallableReferenceExpression, referenceType: JetType, context: ResolutionContext<*>) {
+ val functionDescriptor = AnonymousFunctionDescriptor(
+ context.scope.getContainingDeclaration(),
+ Annotations.EMPTY,
+ CallableMemberDescriptor.Kind.DECLARATION,
+ expression.toSourceElement())
+
+ FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, referenceType, null, Modality.FINAL, Visibilities.PUBLIC)
+
+ context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor)
+}
+
+private fun bindPropertyReference(expression: JetCallableReferenceExpression, referenceType: JetType, context: ResolutionContext<*>) {
+ val localVariable = LocalVariableDescriptor(context.scope.getContainingDeclaration(), Annotations.EMPTY, Name.special(""),
+ referenceType, /* mutable = */ false, expression.toSourceElement())
+
+ context.trace.record(BindingContext.VARIABLE, expression, localVariable)
+}
+
+private fun createReflectionTypeForCallableDescriptor(
+ descriptor: CallableDescriptor,
+ context: ResolutionContext<*>,
+ reflectionTypes: ReflectionTypes,
+ reportOn: JetExpression?
+): JetType? {
+ val extensionReceiver = descriptor.getExtensionReceiverParameter()
+ val dispatchReceiver = descriptor.getDispatchReceiverParameter()
+
+ if (extensionReceiver != null && dispatchReceiver != null && descriptor is CallableMemberDescriptor) {
+ if (reportOn != null) {
+ context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reportOn, descriptor))
+ }
+ return null
+ }
+
+ val receiverType = extensionReceiver?.getType() ?: dispatchReceiver?.getType()
+
+ return when (descriptor) {
+ is FunctionDescriptor ->
+ createReflectionTypeForFunction(descriptor, receiverType, reflectionTypes)
+ is PropertyDescriptor ->
+ createReflectionTypeForProperty(descriptor, receiverType, reflectionTypes)
+ is VariableDescriptor -> {
+ if (reportOn != null) {
+ context.trace.report(UNSUPPORTED.on(reportOn, "References to variables aren't supported yet"))
+ }
+ null
+ }
+ else ->
+ throw UnsupportedOperationException("Callable reference resolved to an unsupported descriptor: $descriptor")
+ }
+}
+
+public fun getReflectionTypeForCandidateDescriptor(
+ descriptor: CallableDescriptor,
+ context: ResolutionContext<*>,
+ reflectionTypes: ReflectionTypes
+): JetType? =
+ createReflectionTypeForCallableDescriptor(descriptor, context, reflectionTypes, null)
+
+public fun createReflectionTypeForResolvedCallableReference(
+ reference: JetCallableReferenceExpression,
+ descriptor: CallableDescriptor,
+ context: ResolutionContext<*>,
+ reflectionTypes: ReflectionTypes
+): JetType? {
+ val type = createReflectionTypeForCallableDescriptor(descriptor, context, reflectionTypes, reference.getCallableReference())
+ ?: return null
+ when (descriptor) {
+ is FunctionDescriptor -> {
+ bindFunctionReference(reference, type, context)
+ }
+ is PropertyDescriptor -> {
+ bindPropertyReference(reference, type, context)
+ }
+ }
+ return type
+}
+
+public fun getResolvedCallableReferenceShapeType(
+ reference: JetCallableReferenceExpression,
+ overloadResolutionResults: OverloadResolutionResults?,
+ context: ResolutionContext<*>,
+ expectedTypeUnknown: Boolean,
+ reflectionTypes: ReflectionTypes,
+ builtIns: KotlinBuiltIns
+): JetType? =
+ when {
+ overloadResolutionResults == null ->
+ null
+ overloadResolutionResults.isSingleResult() ->
+ OverloadResolutionResultsUtil.getResultingCall(overloadResolutionResults, context.contextDependency)?.let { call ->
+ createReflectionTypeForCallableDescriptor(call.getResultingDescriptor(), context, reflectionTypes, reference)
+ }
+ expectedTypeUnknown /* && overload resolution was ambiguous */ ->
+ ErrorUtils.createFunctionPlaceholderType(emptyList(), false)
+ else ->
+ builtIns.getFunctionType(Annotations.EMPTY, null, emptyList(), TypeUtils.DONT_CARE)
+ }
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java
index 87ef35c94e9..1d6cbeaf985 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java
@@ -20,16 +20,20 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
+import org.jetbrains.kotlin.builtins.ReflectionTypes;
+import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
+import org.jetbrains.kotlin.resolve.callableReferences.CallableReferencesPackage;
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext;
-import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode;
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
@@ -60,17 +64,23 @@ import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
public class ArgumentTypeResolver {
@NotNull private final TypeResolver typeResolver;
+ @NotNull private final CallResolver callResolver;
@NotNull private final ExpressionTypingServices expressionTypingServices;
@NotNull private final KotlinBuiltIns builtIns;
+ @NotNull private final ReflectionTypes reflectionTypes;
public ArgumentTypeResolver(
- @NotNull KotlinBuiltIns builtIns,
+ @NotNull TypeResolver typeResolver,
+ @NotNull CallResolver callResolver,
@NotNull ExpressionTypingServices expressionTypingServices,
- @NotNull TypeResolver typeResolver
+ @NotNull KotlinBuiltIns builtIns,
+ @NotNull ReflectionTypes reflectionTypes
) {
- this.builtIns = builtIns;
- this.expressionTypingServices = expressionTypingServices;
this.typeResolver = typeResolver;
+ this.callResolver = callResolver;
+ this.expressionTypingServices = expressionTypingServices;
+ this.builtIns = builtIns;
+ this.reflectionTypes = reflectionTypes;
}
public static boolean isSubtypeOfForArgumentType(
@@ -92,7 +102,7 @@ public class ArgumentTypeResolver {
@NotNull CallResolutionContext> context,
@NotNull ResolveArgumentsMode resolveFunctionArgumentBodies
) {
- if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return;
+ if (context.checkArguments != CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) return;
for (ValueArgument valueArgument : context.call.getValueArguments()) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
@@ -117,7 +127,7 @@ public class ArgumentTypeResolver {
}
public void checkTypesForFunctionArgumentsWithNoCallee(@NotNull CallResolutionContext> context) {
- if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return;
+ if (context.checkArguments != CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) return;
for (ValueArgument valueArgument : context.call.getValueArguments()) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
@@ -148,7 +158,7 @@ public class ArgumentTypeResolver {
}
@Nullable
- private static JetFunction getFunctionLiteralArgumentIfAny(
+ public static JetFunction getFunctionLiteralArgumentIfAny(
@NotNull JetExpression expression, @NotNull ResolutionContext context
) {
JetExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, context.statementFilter);
@@ -181,6 +191,18 @@ public class ArgumentTypeResolver {
return deparenthesizedExpression;
}
+ @Nullable
+ public static JetCallableReferenceExpression getCallableReferenceExpressionIfAny(
+ @NotNull JetExpression expression,
+ @NotNull CallResolutionContext> context
+ ) {
+ JetExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, context.statementFilter);
+ if (deparenthesizedExpression instanceof JetCallableReferenceExpression) {
+ return (JetCallableReferenceExpression) deparenthesizedExpression;
+ }
+ return null;
+ }
+
@NotNull
public JetTypeInfo getArgumentTypeInfo(
@Nullable JetExpression expression,
@@ -190,18 +212,58 @@ public class ArgumentTypeResolver {
if (expression == null) {
return TypeInfoFactoryPackage.noTypeInfo(context);
}
- if (isFunctionLiteralArgument(expression, context)) {
- return getFunctionLiteralTypeInfo(expression, getFunctionLiteralArgument(expression, context), context, resolveArgumentsMode);
+
+ JetFunction functionLiteralArgument = getFunctionLiteralArgumentIfAny(expression, context);
+ if (functionLiteralArgument != null) {
+ return getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, resolveArgumentsMode);
}
+
+ JetCallableReferenceExpression callableReferenceExpression = getCallableReferenceExpressionIfAny(expression, context);
+ if (callableReferenceExpression != null) {
+ return getCallableReferenceTypeInfo(expression, callableReferenceExpression, context, resolveArgumentsMode);
+ }
+
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
if (recordedTypeInfo != null) {
return recordedTypeInfo;
}
+
ResolutionContext newContext = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(DEPENDENT);
return expressionTypingServices.getTypeInfo(expression, newContext);
}
+ @NotNull
+ public JetTypeInfo getCallableReferenceTypeInfo(
+ @NotNull JetExpression expression,
+ @NotNull JetCallableReferenceExpression callableReferenceExpression,
+ @NotNull CallResolutionContext> context,
+ @NotNull ResolveArgumentsMode resolveArgumentsMode
+ ) {
+ if (resolveArgumentsMode == SHAPE_FUNCTION_ARGUMENTS) {
+ JetType type = getShapeTypeOfCallableReference(callableReferenceExpression, context, true);
+ return TypeInfoFactoryPackage.createTypeInfo(type);
+ }
+ return expressionTypingServices.getTypeInfo(expression, context.replaceContextDependency(INDEPENDENT));
+ }
+
+ @Nullable
+ public JetType getShapeTypeOfCallableReference(
+ @NotNull JetCallableReferenceExpression callableReferenceExpression,
+ @NotNull CallResolutionContext> context,
+ boolean expectedTypeIsUnknown
+ ) {
+ JetType receiverType =
+ CallableReferencesPackage.resolveCallableReferenceReceiverType(callableReferenceExpression, context, typeResolver);
+ OverloadResolutionResults overloadResolutionResults =
+ CallableReferencesPackage.resolvePossiblyAmbiguousCallableReference(
+ callableReferenceExpression, receiverType, context, ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS,
+ callResolver);
+ return CallableReferencesPackage.getResolvedCallableReferenceShapeType(
+ callableReferenceExpression, overloadResolutionResults, context, expectedTypeIsUnknown,
+ reflectionTypes, builtIns);
+ }
+
@NotNull
public JetTypeInfo getFunctionLiteralTypeInfo(
@NotNull JetExpression expression,
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt
index b5cf244d821..915cacf469f 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedT
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
-import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
@@ -194,7 +194,7 @@ public class CallCompleter(
context: BasicCallResolutionContext,
results: OverloadResolutionResultsImpl
) {
- if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return
+ if (context.checkArguments != CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) return
val getArgumentMapping: (ValueArgument) -> ArgumentMapping
val getDataFlowInfoForArgument: (ValueArgument) -> DataFlowInfo
@@ -247,10 +247,15 @@ public class CallCompleter(
// While the expected type is not known, the function literal arguments are not analyzed (to analyze function literal bodies once),
// but they should be analyzed when the expected type is known (during the call completion).
- if (ArgumentTypeResolver.isFunctionLiteralArgument(expression, context)) {
- argumentTypeResolver.getFunctionLiteralTypeInfo(
- expression, ArgumentTypeResolver.getFunctionLiteralArgument(expression, context),
- context, RESOLVE_FUNCTION_ARGUMENTS)
+ ArgumentTypeResolver.getFunctionLiteralArgumentIfAny(expression, context)?.let { functionLiteralArgument ->
+ argumentTypeResolver.getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, RESOLVE_FUNCTION_ARGUMENTS)
+ }
+
+ // While the expected type is not known, (possibly overloaded) callable references can have placeholder types
+ // (to avoid exponential search for overloaded higher-order functions).
+ // They should be analyzed now.
+ ArgumentTypeResolver.getCallableReferenceExpressionIfAny(expression, context)?.let { callableReferenceArgument ->
+ argumentTypeResolver.getCallableReferenceTypeInfo(expression, callableReferenceArgument, context, RESOLVE_FUNCTION_ARGUMENTS)
}
DataFlowUtils.checkType(updatedType, deparenthesized, context)
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java
index 1cb3a6cdac8..4cb5a14975f 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
-import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode;
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
@@ -78,7 +78,7 @@ public class CallExpressionResolver {
@Nullable
public ResolvedCall getResolvedCallForFunction(
@NotNull Call call, @NotNull JetExpression callExpression,
- @NotNull ResolutionContext context, @NotNull CheckValueArgumentsMode checkArguments,
+ @NotNull ResolutionContext context, @NotNull CheckArgumentTypesMode checkArguments,
@NotNull boolean[] result
) {
OverloadResolutionResults results = callResolver.resolveFunctionCall(
@@ -101,7 +101,7 @@ public class CallExpressionResolver {
Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression);
BasicCallResolutionContext contextForVariable = BasicCallResolutionContext.create(
context.replaceTraceAndCache(temporaryForVariable),
- call, CheckValueArgumentsMode.ENABLED);
+ call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
OverloadResolutionResults resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
// if the expression is a receiver in a qualified expression, it should be resolved after the selector is resolved
@@ -154,7 +154,7 @@ public class CallExpressionResolver {
context, "trace to resolve as function", nameExpression);
ResolutionContext newContext = context.replaceTraceAndCache(temporaryForFunction);
ResolvedCall resolvedCall = getResolvedCallForFunction(
- call, nameExpression, newContext, CheckValueArgumentsMode.ENABLED, result);
+ call, nameExpression, newContext, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, result);
if (result[0]) {
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
temporaryForFunction.commit();
@@ -198,7 +198,7 @@ public class CallExpressionResolver {
call, callExpression,
// It's possible start of a call so we should reset safe call chain
context.replaceTraceAndCache(temporaryForFunction).replaceInsideCallChain(false),
- CheckValueArgumentsMode.ENABLED, result);
+ CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, result);
if (result[0]) {
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
temporaryForFunction.commit();
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java
index 11ac9867533..c1c24de224f 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java
@@ -164,7 +164,7 @@ public class CallResolver {
@NotNull JetReferenceExpression functionReference,
@NotNull Name name
) {
- BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED);
+ BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
return computeTasksAndResolveCall(
callResolutionContext, name, functionReference,
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER);
@@ -263,7 +263,7 @@ public class CallResolver {
) {
return resolveFunctionCall(
BasicCallResolutionContext.create(
- trace, scope, call, expectedType, dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
+ trace, scope, call, expectedType, dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
additionalCheckerProvider.getCallChecker(), additionalCheckerProvider.getSymbolUsageValidator(),
additionalCheckerProvider.getTypeChecker(), isAnnotationContext)
);
@@ -344,7 +344,7 @@ public class CallResolver {
trace, scope,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
NO_EXPECTED_TYPE,
- dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
+ dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
callChecker, additionalCheckerProvider.getSymbolUsageValidator(), additionalCheckerProvider.getTypeChecker(), false);
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
@@ -430,7 +430,7 @@ public class CallResolver {
@Override
public OverloadResolutionResults invoke() {
BasicCallResolutionContext basicCallResolutionContext =
- BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED, dataFlowInfoForArguments);
+ BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, dataFlowInfoForArguments);
List> tasks =
taskPrioritizer.computePrioritizedTasksFromCandidates(
@@ -484,7 +484,7 @@ public class CallResolver {
CallCandidateResolutionContext candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
results.getResultingCall(), context, tracing);
- genericCandidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext);
+ genericCandidateResolver.completeTypeInferenceDependentOnFunctionArgumentsForCall(candidateContext);
}
private static void cacheResults(
@@ -515,7 +515,7 @@ public class CallResolver {
@NotNull CallTransformer callTransformer,
@NotNull TracingStrategy tracing
) {
- if (context.checkArguments == CheckValueArgumentsMode.ENABLED) {
+ if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
argumentTypeResolver.analyzeArgumentsAndRecordTypes(context);
}
Collection> allCandidates = Lists.newArrayList();
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt
index 0e24b91d302..00fbb5ab3d6 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.callResolverUtil
import com.google.common.collect.Lists
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
@@ -33,6 +34,8 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
+import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
+import java.util.*
public enum class ResolveArgumentsMode {
RESOLVE_FUNCTION_ARGUMENTS,
@@ -41,30 +44,34 @@ public enum class ResolveArgumentsMode {
public fun hasUnknownFunctionParameter(type: JetType): Boolean {
- assert(KotlinBuiltIns.isFunctionOrExtensionFunctionType(type))
- val arguments = type.getArguments()
- // last argument is return type of function type
- val functionParameters = arguments.subList(0, arguments.size() - 1)
- return functionParameters.any {
+ assert(ReflectionTypes.isCallableType(type), "type is not a function or property")
+ return getParameterArgumentsOfCallableType(type).any {
TypeUtils.containsSpecialType(it.getType(), DONT_CARE) || ErrorUtils.containsUninferredParameter(it.getType())
}
}
public fun hasUnknownReturnType(type: JetType): Boolean {
- assert(KotlinBuiltIns.isFunctionOrExtensionFunctionType(type))
- val returnTypeFromFunctionType = KotlinBuiltIns.getReturnTypeFromFunctionType(type)
- return ErrorUtils.containsErrorType(returnTypeFromFunctionType)
+ assert(ReflectionTypes.isCallableType(type), "type is not a function or property")
+ return ErrorUtils.containsErrorType(getReturnTypeForCallable(type))
}
public fun replaceReturnTypeByUnknown(type: JetType): JetType {
- assert(KotlinBuiltIns.isFunctionOrExtensionFunctionType(type))
- val arguments = type.getArguments()
+ assert(ReflectionTypes.isCallableType(type), "type is not a function or property")
val newArguments = Lists.newArrayList()
- newArguments.addAll(arguments.subList(0, arguments.size() - 1))
+ newArguments.addAll(getParameterArgumentsOfCallableType(type))
newArguments.add(TypeProjectionImpl(Variance.INVARIANT, DONT_CARE))
- return JetTypeImpl(type.getAnnotations(), type.getConstructor(), type.isMarkedNullable(), newArguments, type.getMemberScope())
+ return replaceTypeArguments(type, newArguments)
}
+private fun replaceTypeArguments(type: JetType, newArguments: List) =
+ JetTypeImpl(type.getAnnotations(), type.getConstructor(), type.isMarkedNullable(), newArguments, type.getMemberScope())
+
+private fun getParameterArgumentsOfCallableType(type: JetType) =
+ type.getArguments().dropLast(1)
+
+private fun getReturnTypeForCallable(type: JetType) =
+ type.getArguments().last().getType()
+
private fun CallableDescriptor.hasReturnTypeDependentOnUninferredParams(constraintSystem: ConstraintSystem): Boolean {
val returnType = getReturnType() ?: return false
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt
index 812ec018040..8700ae73848 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt
@@ -19,12 +19,14 @@ package org.jetbrains.kotlin.resolve.calls
import com.google.common.collect.Lists
import com.google.common.collect.Sets
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT
import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
+import org.jetbrains.kotlin.resolve.callableReferences.getReflectionTypeForCandidateDescriptor
import org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS
@@ -60,11 +62,14 @@ import java.util.ArrayList
public class CandidateResolver(
private val argumentTypeResolver: ArgumentTypeResolver,
- private val genericCandidateResolver: GenericCandidateResolver
+ private val genericCandidateResolver: GenericCandidateResolver,
+ private val reflectionTypes: ReflectionTypes
){
- public fun performResolutionForCandidateCall(context: CallCandidateResolutionContext,
- task: ResolutionTask): Unit = with(context) {
+ public fun performResolutionForCandidateCall(
+ context: CallCandidateResolutionContext,
+ task: ResolutionTask
+ ): Unit = with(context) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
if (ErrorUtils.isError(candidateDescriptor)) {
@@ -78,7 +83,13 @@ public class CandidateResolver(
}
checkVisibility()
- mapArguments(task)
+
+ when (task.checkArguments) {
+ CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
+ mapArguments()
+ CheckArgumentTypesMode.CHECK_CALLABLE_TYPE ->
+ checkExpectedCallableType()
+ }
checkReceiverTypeError()
checkExtensionReceiver()
@@ -143,15 +154,27 @@ public class CandidateResolver(
}
}
- private fun CallCandidateResolutionContext.mapArguments(task: ResolutionTask) = check {
- if (task.checkArguments == CheckValueArgumentsMode.ENABLED) {
- val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
- call, tracing, candidateCall, Sets.newLinkedHashSet())
- if (!argumentMappingStatus.isSuccess()) {
- candidateCall.addStatus(OTHER_ERROR)
+ private fun CallCandidateResolutionContext.mapArguments()
+ = check {
+ val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
+ call, tracing, candidateCall, Sets.newLinkedHashSet())
+ if (!argumentMappingStatus.isSuccess()) {
+ candidateCall.addStatus(OTHER_ERROR)
+ }
+ }
+
+ private fun CallCandidateResolutionContext.checkExpectedCallableType()
+ = check {
+ if (!noExpectedType(expectedType)) {
+ val candidate = candidateCall.getCandidateDescriptor()
+ val candidateReflectionType = getReflectionTypeForCandidateDescriptor(candidate, this, reflectionTypes);
+ if (candidateReflectionType != null) {
+ if (!JetTypeChecker.DEFAULT.isSubtypeOf(candidateReflectionType, expectedType)) {
+ candidateCall.addStatus(OTHER_ERROR)
+ }
+ }
+ }
}
- }
- }
private fun CallCandidateResolutionContext<*>.checkVisibility() = checkAndReport {
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(),
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt
index 129d4d252c9..60aefd312c8 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.resolve.calls
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
-import org.jetbrains.kotlin.psi.JetExpression
-import org.jetbrains.kotlin.psi.JetPsiUtil
-import org.jetbrains.kotlin.psi.ValueArgument
+import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver.getLastElementDeparenthesized
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.*
@@ -39,6 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
+import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
@@ -197,7 +196,7 @@ class GenericCandidateResolver(
return TypeUtils.intersect(JetTypeChecker.DEFAULT, possibleTypes)
}
- public fun completeTypeInferenceDependentOnFunctionLiteralsForCall(
+ public fun completeTypeInferenceDependentOnFunctionArgumentsForCall(
context: CallCandidateResolutionContext
) {
val resolvedCall = context.candidateCall
@@ -210,30 +209,35 @@ class GenericCandidateResolver(
val valueParameterDescriptor = entry.getKey()
for (valueArgument in resolvedValueArgument.getArguments()) {
- addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context)
+ valueArgument.getArgumentExpression()?.let { argumentExpression ->
+ ArgumentTypeResolver.getFunctionLiteralArgumentIfAny(argumentExpression, context)?.let { functionLiteral ->
+ addConstraintForFunctionLiteral(functionLiteral, valueArgument, valueParameterDescriptor, constraintSystem, context)
+ }
+ ArgumentTypeResolver.getCallableReferenceExpressionIfAny(argumentExpression, context)?.let { callableReference ->
+ addConstraintForCallableReference(callableReference, valueArgument, valueParameterDescriptor, constraintSystem, context)
+ }
+ }
}
}
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor())
}
private fun addConstraintForFunctionLiteral(
+ functionLiteral: JetFunction,
valueArgument: ValueArgument,
valueParameterDescriptor: ValueParameterDescriptor,
constraintSystem: ConstraintSystem,
context: CallCandidateResolutionContext
) {
val argumentExpression = valueArgument.getArgumentExpression() ?: return
- if (!ArgumentTypeResolver.isFunctionLiteralArgument(argumentExpression, context)) return
-
- val functionLiteral = ArgumentTypeResolver.getFunctionLiteralArgument(argumentExpression, context)
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
var expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) {
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false)
}
- if (expectedType == null || !KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType)
- || hasUnknownFunctionParameter(expectedType)) {
+ if (expectedType == null || !KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType) ||
+ hasUnknownFunctionParameter(expectedType)) {
return
}
val dataFlowInfoForArguments = context.candidateCall.getDataFlowInfoForArguments()
@@ -267,6 +271,56 @@ class GenericCandidateResolver(
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, position)
}
+
+ private fun addConstraintForCallableReference(
+ callableReference: JetCallableReferenceExpression,
+ valueArgument: ValueArgument,
+ valueParameterDescriptor: ValueParameterDescriptor,
+ constraintSystem: ConstraintSystem,
+ context: CallCandidateResolutionContext
+ ) {
+ val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
+ val expectedType = getExpectedTypeForCallableReference(callableReference, constraintSystem, context, effectiveExpectedType)
+ ?: return
+ val resolvedType = getResolvedTypeForCallableReference(callableReference, context, expectedType, valueArgument)
+ val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.getIndex())
+ constraintSystem.addSubtypeConstraint(resolvedType, effectiveExpectedType, position)
+ }
+
+ private fun getExpectedTypeForCallableReference(
+ callableReference: JetCallableReferenceExpression,
+ constraintSystem: ConstraintSystem,
+ context: CallCandidateResolutionContext,
+ effectiveExpectedType: JetType
+ ): JetType? {
+ val substitutedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
+ if (substitutedType != null && !TypeUtils.isDontCarePlaceholder(substitutedType))
+ return substitutedType
+
+ val shapeType = argumentTypeResolver.getShapeTypeOfCallableReference(callableReference, context, false)
+ if (shapeType != null && KotlinBuiltIns.isFunctionOrExtensionFunctionType(shapeType) && !hasUnknownFunctionParameter(shapeType))
+ return shapeType
+
+ return null
+ }
+
+ private fun getResolvedTypeForCallableReference(
+ callableReference: JetCallableReferenceExpression,
+ context: CallCandidateResolutionContext,
+ expectedType: JetType,
+ valueArgument: ValueArgument
+ ): JetType? {
+ val dataFlowInfoForArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(valueArgument)
+ val expectedTypeWithoutReturnType = if (!hasUnknownReturnType(expectedType)) replaceReturnTypeByUnknown(expectedType) else expectedType
+ val newContext = context
+ .replaceExpectedType(expectedTypeWithoutReturnType)
+ .replaceDataFlowInfo(dataFlowInfoForArgument)
+ .replaceContextDependency(INDEPENDENT)
+ val argumentExpression = valueArgument.getArgumentExpression()!!
+ val type = argumentTypeResolver.getCallableReferenceTypeInfo(
+ argumentExpression, callableReference, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
+ return type
+ }
}
fun getResolutionResultsCachedData(expression: JetExpression?, context: ResolutionContext<*>): ResolutionResultsCache.CachedData? {
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java
index 04602ae305a..46333524e10 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java
@@ -37,7 +37,7 @@ public class BasicCallResolutionContext extends CallResolutionContext
@NotNull JetType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull ContextDependency contextDependency,
- @NotNull CheckValueArgumentsMode checkArguments,
+ @NotNull CheckArgumentTypesMode checkArguments,
@NotNull ResolutionResultsCache resolutionResultsCache,
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
@NotNull CallChecker callChecker,
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java
index 70ecaec49ab..79e8ef837fc 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java
@@ -34,7 +34,7 @@ public abstract class CallResolutionContext extends C
@NotNull JetType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull ContextDependency contextDependency,
- @NotNull CheckValueArgumentsMode checkArguments,
+ @NotNull CheckArgumentTypesMode checkArguments,
@NotNull ResolutionResultsCache resolutionResultsCache,
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
@NotNull CallChecker callChecker,
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java
index 6a59fa9a9b7..3b1ee774e89 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java
@@ -30,17 +30,15 @@ import org.jetbrains.kotlin.JetNodeTypes;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
-import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
-import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
+import org.jetbrains.kotlin.resolve.callableReferences.CallableReferencesPackage;
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
-import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode;
-import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl;
@@ -57,17 +55,13 @@ import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
-import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
-import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
-import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryPackage;
import org.jetbrains.kotlin.types.expressions.unqualifiedSuper.UnqualifiedSuperPackage;
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
-import org.jetbrains.kotlin.utils.ThrowingList;
import java.util.Collection;
import java.util.Collections;
@@ -78,12 +72,10 @@ import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.lexer.JetTokens.AS_KEYWORD;
import static org.jetbrains.kotlin.lexer.JetTokens.AS_SAFE;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
-import static org.jetbrains.kotlin.resolve.DescriptorUtils.getStaticNestedClassesScope;
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.DEPENDENT;
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
import static org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue;
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
-import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
@@ -498,7 +490,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
trace.record(RESOLVED_CALL, call, resolvedCall);
trace.record(CALL, expression, call);
- BasicCallResolutionContext resolutionContext = BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.DISABLED);
+ BasicCallResolutionContext resolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_CALLABLE_TYPE);
context.callChecker.check(resolvedCall, resolutionContext);
context.symbolUsageValidator.validateCall(descriptor, trace, expression);
}
@@ -676,166 +668,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
) {
JetSimpleNameExpression reference = expression.getCallableReference();
- boolean[] result = new boolean[1];
- CallableDescriptor descriptor = resolveCallableReferenceTarget(
- lhsType, context.replaceContextDependency(INDEPENDENT), expression, result);
-
- if (!result[0]) {
+ boolean[] resolved = new boolean[1];
+ CallableDescriptor descriptor = CallableReferencesPackage.resolveCallableReferenceTarget(
+ expression, lhsType, context, resolved, components.callResolver);
+ if (!resolved[0]) {
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
}
if (descriptor == null) return null;
- ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
- ReceiverParameterDescriptor dispatchReceiver = descriptor.getDispatchReceiverParameter();
- if (extensionReceiver != null && dispatchReceiver != null && descriptor instanceof CallableMemberDescriptor) {
- context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, (CallableMemberDescriptor) descriptor));
- return null;
- }
-
- JetType receiverType = extensionReceiver != null ? extensionReceiver.getType() :
- dispatchReceiver != null ? dispatchReceiver.getType() :
- null;
-
- if (descriptor instanceof FunctionDescriptor) {
- return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType);
- }
- else if (descriptor instanceof PropertyDescriptor) {
- return createPropertyReferenceType(expression, context, (PropertyDescriptor) descriptor, receiverType);
- }
- else if (descriptor instanceof VariableDescriptor) {
- context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
- return null;
- }
-
- throw new UnsupportedOperationException("Callable reference resolved to an unsupported descriptor: " + descriptor);
- }
-
- @Nullable
- private JetType createFunctionReferenceType(
- @NotNull JetCallableReferenceExpression expression,
- @NotNull ExpressionTypingContext context,
- @NotNull FunctionDescriptor descriptor,
- @Nullable JetType receiverType
- ) {
- //noinspection ConstantConditions
- JetType type = components.reflectionTypes.getKFunctionType(
- Annotations.EMPTY,
- receiverType,
- getValueParametersTypes(descriptor.getValueParameters()),
- descriptor.getReturnType()
- );
-
- AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
- context.scope.getContainingDeclaration(),
- Annotations.EMPTY,
- CallableMemberDescriptor.Kind.DECLARATION,
- toSourceElement(expression)
- );
-
- FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
-
- context.trace.record(FUNCTION, expression, functionDescriptor);
-
- return type;
- }
-
- @Nullable
- private JetType createPropertyReferenceType(
- @NotNull JetCallableReferenceExpression expression,
- @NotNull ExpressionTypingContext context,
- @NotNull PropertyDescriptor descriptor,
- @Nullable JetType receiverType
- ) {
- JetType type = components.reflectionTypes.getKPropertyType(
- Annotations.EMPTY, receiverType, descriptor.getType(), descriptor.isVar()
- );
-
- LocalVariableDescriptor localVariable =
- new LocalVariableDescriptor(context.scope.getContainingDeclaration(), Annotations.EMPTY, Name.special(""),
- type, /* mutable = */ false, toSourceElement(expression));
-
- context.trace.record(VARIABLE, expression, localVariable);
-
- return type;
- }
-
- @Nullable
- private CallableDescriptor resolveCallableReferenceTarget(
- @Nullable JetType lhsType,
- @NotNull ExpressionTypingContext context,
- @NotNull JetCallableReferenceExpression expression,
- @NotNull boolean[] result
- ) {
- JetSimpleNameExpression reference = expression.getCallableReference();
-
- if (lhsType == null) {
- return resolveCallableNotCheckingArguments(reference, NO_RECEIVER, context, result);
- }
-
- ClassifierDescriptor classifier = lhsType.getConstructor().getDeclarationDescriptor();
- if (!(classifier instanceof ClassDescriptor)) {
- context.trace.report(CALLABLE_REFERENCE_LHS_NOT_A_CLASS.on(expression));
- return null;
- }
-
- JetScope staticScope = ((ClassDescriptor) classifier).getStaticScope();
- TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create(
- context, "trace to resolve callable reference in static scope", reference);
- CallableDescriptor possibleStatic = resolveCallableNotCheckingArguments(
- reference, NO_RECEIVER, context.replaceTraceAndCache(temporaryForStatic).replaceScope(staticScope), result);
- if (result[0]) {
- temporaryForStatic.commit();
- return possibleStatic;
- }
-
- JetScope staticNestedClasses = getStaticNestedClassesScope((ClassDescriptor) classifier);
- TemporaryTraceAndCache temporaryForNested = TemporaryTraceAndCache.create(
- context, "trace to resolve callable reference in static nested classes scope", reference);
- CallableDescriptor possibleNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER,
- context.replaceTraceAndCache(temporaryForNested).replaceScope(staticNestedClasses), result);
- if (result[0]) {
- temporaryForNested.commit();
- return possibleNestedClassConstructor;
- }
-
- ReceiverValue receiver = new TransientReceiver(lhsType);
- TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create(
- context, "trace to resolve callable reference with receiver", reference);
- CallableDescriptor descriptor = resolveCallableNotCheckingArguments(
- reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result);
- if (result[0]) {
- temporaryWithReceiver.commit();
- return descriptor;
- }
-
- return null;
- }
-
- @Nullable
- private CallableDescriptor resolveCallableNotCheckingArguments(
- @NotNull JetSimpleNameExpression reference,
- @NotNull ReceiverValue receiver,
- @NotNull ExpressionTypingContext context,
- @NotNull boolean[] result
- ) {
- Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.instance());
- TemporaryTraceAndCache temporaryTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
- reference);
-
- BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(
- context.replaceTraceAndCache(temporaryTrace).replaceExpectedType(NO_EXPECTED_TYPE), call, CheckValueArgumentsMode.DISABLED);
- OverloadResolutionResults results =
- components.callResolver.resolveCallForMember(reference, callResolutionContext);
- if (!results.isNothing()) {
- temporaryTrace.commit();
- result[0] = true;
- ResolvedCall callable =
- OverloadResolutionResultsUtil.getResultingCall(results, context.contextDependency);
- if (callable != null) {
- return callable.getResultingDescriptor();
- }
- }
- return null;
+ return CallableReferencesPackage.createReflectionTypeForResolvedCallableReference(expression, descriptor, context, components.reflectionTypes);
}
@Override
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java
index 9867e0b7776..05c9bd22c53 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java
@@ -21,14 +21,18 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.analyzer.AnalyzerPackage;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
+import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
+import org.jetbrains.kotlin.resolve.callableReferences.CallableReferencesPackage;
+import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode;
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
+import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
@@ -301,4 +305,5 @@ public class ExpressionTypingServices {
}
return result;
}
+
}
diff --git a/compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFun.kt b/compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFun.kt
new file mode 100644
index 00000000000..001cc71734a
--- /dev/null
+++ b/compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFun.kt
@@ -0,0 +1,22 @@
+import kotlin.test.assertEquals
+
+fun foo(): String = "foo1"
+fun foo(i: Int): String = "foo2"
+
+val f1: () -> String = ::foo
+val f2: (Int) -> String = ::foo
+
+fun foo1() {}
+fun foo2(i: Int) {}
+
+fun bar(f: () -> Unit): String = "bar1"
+fun bar(f: (Int) -> Unit): String = "bar2"
+
+fun box(): String {
+ assertEquals("foo1", f1())
+ assertEquals("foo2", f2(0))
+ assertEquals("bar1", bar(::foo1))
+ assertEquals("bar2", bar(::foo2))
+
+ return "OK"
+}
\ No newline at end of file
diff --git a/compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFunVsVal.kt b/compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFunVsVal.kt
new file mode 100644
index 00000000000..77ade044bc0
--- /dev/null
+++ b/compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFunVsVal.kt
@@ -0,0 +1,19 @@
+import kotlin.reflect.*
+import kotlin.test.assertEquals
+
+class A {
+ val x = 1
+ fun x(): String = "OK"
+}
+
+val f1: KProperty1 = A::x
+val f2: (A) -> String = A::x
+
+fun box(): String {
+ val a = A()
+
+ assertEquals(1, f1.get(a))
+ assertEquals("OK", f2(a))
+
+ return "OK"
+}
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.kt b/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.kt
index 94f12524c7f..3bf7de5a5db 100644
--- a/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.kt
+++ b/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.kt
@@ -5,5 +5,5 @@ fun foo(x: Any, y: Int) = y
fun main() {
::foo
- val fooRef: (Int, Any) -> Unit = ::foo
+ val fooRef: (Int, Any) -> Unit = ::foo
}
diff --git a/compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.kt b/compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.kt
new file mode 100644
index 00000000000..fef220c5282
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.kt
@@ -0,0 +1,22 @@
+// FILE: A.kt
+
+open class A(val x: T)
+
+// FILE: AFactory.kt
+
+abstract class AFactory {
+ abstract fun create(): A?
+}
+
+// FILE: Util.kt
+
+inline fun createWith(x: T, f: (T) -> A?)
+ = f(x)
+
+// FILE: B.kt
+
+class B(x: Int) : A(x) {
+ companion object : AFactory() {
+ override fun create(): A? = createWith(0, ::B)
+ }
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.txt b/compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.txt
new file mode 100644
index 00000000000..57f67fc4f2c
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.txt
@@ -0,0 +1,35 @@
+package
+
+kotlin.inline() internal fun *0*/ reified T> createWith(/*0*/ x: T, /*1*/ f: (T) -> A?): A?
+
+internal open class A*0*/ T> {
+ public constructor A*0*/ T>(/*0*/ x: T)
+ internal final val x: T
+ 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
+}
+
+internal abstract class AFactory {
+ public constructor AFactory()
+ internal abstract fun create(): A?
+ 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
+}
+
+internal final class B : A {
+ public constructor B(/*0*/ x: kotlin.Int)
+ internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
+ 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 companion object Companion : AFactory {
+ private constructor Companion()
+ internal open override /*1*/ fun create(): A?
+ 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
+ }
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.kt b/compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.kt
new file mode 100644
index 00000000000..4cae96f7f07
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.kt
@@ -0,0 +1,8 @@
+import kotlin.reflect.KProperty1
+
+fun getProperty(x: T, property: KProperty1): R =
+ property.get(x)
+
+class Person(val name: String)
+
+val name1 = getProperty(Person("John Smith"), Person::name)
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.txt b/compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.txt
new file mode 100644
index 00000000000..8e39134633d
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.txt
@@ -0,0 +1,12 @@
+package
+
+internal val name1: kotlin.String
+internal fun *0*/ T, /*1*/ R> getProperty(/*0*/ x: T, /*1*/ property: kotlin.reflect.KProperty1): R
+
+internal final class Person {
+ public constructor Person(/*0*/ name: kotlin.String)
+ internal final val name: 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
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.kt b/compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.kt
new file mode 100644
index 00000000000..1fd83f1c2a1
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.kt
@@ -0,0 +1,19 @@
+// FILE: Customer.java
+public class Customer {
+ private String name;
+
+ public Customer(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
+// FILE: test.kt
+val customerName = Customer::name
diff --git a/compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.txt b/compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.txt
new file mode 100644
index 00000000000..e9f2c8d60e7
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.txt
@@ -0,0 +1,13 @@
+package
+
+internal val customerName: kotlin.reflect.KMutableProperty1
+
+public open class Customer {
+ public constructor Customer(/*0*/ name: kotlin.String!)
+ private final var name: kotlin.String!
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open fun getName(): kotlin.String!
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open fun setName(/*0*/ name: kotlin.String!): kotlin.Unit
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt
new file mode 100644
index 00000000000..bcae8c1979b
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt
@@ -0,0 +1,10 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+fun foo() {}
+fun foo(s: String) {}
+
+fun fn(f: () -> Unit) {}
+
+fun test() {
+ fn(::foo)
+}
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.txt
new file mode 100644
index 00000000000..37722d29c07
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.txt
@@ -0,0 +1,6 @@
+package
+
+internal fun fn(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
+internal fun foo(): kotlin.Unit
+internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
+internal fun test(): kotlin.Unit
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.kt
new file mode 100644
index 00000000000..9c17a48e44b
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.kt
@@ -0,0 +1,10 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+fun ofType(x: T): T = x
+
+fun foo() {}
+fun foo(s: String) {}
+
+val x1 = ofType<() -> Unit>(::foo)
+val x2 = ofType<(String) -> Unit>(::foo)
+val x3 = ofType<(Int) -> Unit>(::foo)
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.txt
new file mode 100644
index 00000000000..58b76a166b8
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.txt
@@ -0,0 +1,8 @@
+package
+
+internal val x1: () -> kotlin.Unit
+internal val x2: (kotlin.String) -> kotlin.Unit
+internal val x3: (kotlin.Int) -> kotlin.Unit
+internal fun foo(): kotlin.Unit
+internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
+internal fun *0*/ T> ofType(/*0*/ x: T): T
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt
new file mode 100644
index 00000000000..4aa6dac8397
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt
@@ -0,0 +1,9 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+fun foo() {}
+fun foo(s: String) {}
+
+val x1 = ::foo
+val x2: () -> Unit = ::foo
+val x3: (String) -> Unit = ::foo
+val x4: (Int) -> Unit = ::foo
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/byValType.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/byValType.txt
new file mode 100644
index 00000000000..2ddd646a152
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/byValType.txt
@@ -0,0 +1,8 @@
+package
+
+internal val x1: [ERROR : Type for ::foo]
+internal val x2: () -> kotlin.Unit
+internal val x3: (kotlin.String) -> kotlin.Unit
+internal val x4: (kotlin.Int) -> kotlin.Unit
+internal fun foo(): kotlin.Unit
+internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt
new file mode 100644
index 00000000000..6cde9ce2b55
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt
@@ -0,0 +1,12 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+class Klass {
+ constructor(a: Int) {}
+ constructor(a: String) {}
+}
+
+fun user(f: (Int) -> Klass) {}
+
+fun fn() {
+ user(::Klass)
+}
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/constructor.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/constructor.txt
new file mode 100644
index 00000000000..aaf4efeeee9
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/constructor.txt
@@ -0,0 +1,12 @@
+package
+
+internal fun fn(): kotlin.Unit
+internal fun user(/*0*/ f: (kotlin.Int) -> Klass): kotlin.Unit
+
+internal final class Klass {
+ public constructor Klass(/*0*/ a: kotlin.Int)
+ public constructor Klass(/*0*/ a: 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
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.kt
new file mode 100644
index 00000000000..44b0d4c9074
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.kt
@@ -0,0 +1,11 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+import kotlin.reflect.*
+
+class A {
+ val x = 1
+ fun x() {}
+}
+
+fun f1(): KProperty = A::x // ok, property
+fun f2(): (A) -> Unit = A::x // ok, function
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.txt
new file mode 100644
index 00000000000..d106eb35399
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.txt
@@ -0,0 +1,13 @@
+package
+
+internal fun f1(): kotlin.reflect.KProperty
+internal fun f2(): (A) -> kotlin.Unit
+
+internal final class A {
+ public constructor A()
+ internal final val x: kotlin.Int = 1
+ 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
+ internal final fun x(): kotlin.Unit
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withAs.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withAs.kt
new file mode 100644
index 00000000000..ff34f30b9ea
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withAs.kt
@@ -0,0 +1,10 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+fun foo() {}
+fun foo(s: String) {}
+
+fun bar(f: () -> Unit) = 1
+fun bar(f: (String) -> Unit) = 2
+
+val x1 = ::foo as () -> Unit
+val x2 = bar(::foo as (String) -> Unit)
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withAs.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/withAs.txt
new file mode 100644
index 00000000000..28e5e7f7653
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withAs.txt
@@ -0,0 +1,8 @@
+package
+
+internal val x1: () -> kotlin.Unit
+internal val x2: kotlin.Int
+internal fun bar(/*0*/ f: () -> kotlin.Unit): kotlin.Int
+internal fun bar(/*0*/ f: (kotlin.String) -> kotlin.Unit): kotlin.Int
+internal fun foo(): kotlin.Unit
+internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.kt
new file mode 100644
index 00000000000..b1a24cb4906
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.kt
@@ -0,0 +1,28 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+import kotlin.reflect.*
+
+fun ofType(x: T): T = x
+
+class A {
+ val foo: Int = 0
+ fun foo() {}
+
+ fun bar() {}
+ val bar: Int = 0
+}
+
+fun A.foo(): String = "A"
+
+val x0 = A::foo // function A::foo wins by default
+val userOfX0 = x0(A())
+
+val x1 = ofType<(A) -> Unit>(A::foo)
+val x2 = ofType>(A::foo)
+val x3: KProperty1 = A::foo
+val x4: (A) -> String = A::foo
+
+val y0 = A::bar
+val y1 = ofType<(A) -> Unit>(A::bar)
+val y2 = ofType>(A::bar)
+val y3: KProperty1 = A::bar
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.txt
new file mode 100644
index 00000000000..0c5755d974e
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.txt
@@ -0,0 +1,25 @@
+package
+
+internal val userOfX0: kotlin.Unit
+internal val x0: kotlin.reflect.KFunction1
+internal val x1: (A) -> kotlin.Unit
+internal val x2: kotlin.reflect.KProperty1
+internal val x3: kotlin.reflect.KProperty1
+internal val x4: (A) -> kotlin.String
+internal val y0: kotlin.reflect.KFunction1
+internal val y1: (A) -> kotlin.Unit
+internal val y2: kotlin.reflect.KProperty1
+internal val y3: kotlin.reflect.KProperty1
+internal fun *0*/ T> ofType(/*0*/ x: T): T
+internal fun A.foo(): kotlin.String
+
+internal final class A {
+ public constructor A()
+ internal final val bar: kotlin.Int = 0
+ internal final val foo: kotlin.Int = 0
+ internal final fun bar(): kotlin.Unit
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ internal final fun foo(): kotlin.Unit
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+}
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.kt
new file mode 100644
index 00000000000..f4f17184fd5
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.kt
@@ -0,0 +1,10 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+fun apply(x: T, f: (T) -> R): R = f(x)
+
+fun foo(i: Int) {}
+fun foo(s: String) {}
+
+val x1 = apply(1, ::foo)
+val x2 = apply("hello", ::foo)
+val x3 = apply(true, ::foo)
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.txt
new file mode 100644
index 00000000000..01971e5dbda
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.txt
@@ -0,0 +1,8 @@
+package
+
+internal val x1: kotlin.Unit
+internal val x2: kotlin.Unit
+internal val x3: [ERROR : Type for apply(true, ::foo)]
+internal fun *0*/ T, /*1*/ R> apply(/*0*/ x: T, /*1*/ f: (T) -> R): R
+internal fun foo(/*0*/ i: kotlin.Int): kotlin.Unit
+internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.kt
new file mode 100644
index 00000000000..238a9821de2
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.kt
@@ -0,0 +1,26 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER,-CONFLICTING_JVM_DECLARATIONS
+
+fun foo(i: Int) = "$i"
+fun foo(s: String) = s
+
+fun bar(s: String) = s
+
+fun qux(i: Int, j: Int, k: Int): Int = i + j + k
+fun qux(a: String, b: String, c: String, d: String) {}
+
+fun fn1(x: Int, f1: (Int) -> String, f2: (String) -> String) = f2(f1(x))
+
+fun fn2(f1: (Int) -> String, f2: (String) -> String ) = f2(f1(0))
+fun fn2(f1: (Int) -> Int, f2: (Int) -> String ) = f2(f1(0))
+fun fn2(f1: (String) -> String, f2: (String) -> String ) = f2(f1(""))
+
+fun fn3(i: Int, f: (Int, Int, Int) -> Int): Int = f(i, i, i)
+
+val x1 = fn1(1, ::foo, ::foo)
+val x2 = fn1(1, ::foo, ::bar)
+
+val x3 = fn2(::bar, ::foo)
+val x4 = fn2(::foo, ::bar)
+val x5 = fn2(::foo, ::foo)
+
+val x6 = fn3(1, ::qux)
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.txt
new file mode 100644
index 00000000000..bf3809374a9
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.txt
@@ -0,0 +1,18 @@
+package
+
+internal val x1: kotlin.String
+internal val x2: kotlin.String
+internal val x3: kotlin.String
+internal val x4: [ERROR : Type for fn2(::foo, ::bar)]
+internal val x5: [ERROR : Type for fn2(::foo, ::foo)]
+internal val x6: kotlin.Int
+internal fun bar(/*0*/ s: kotlin.String): kotlin.String
+internal fun fn1(/*0*/ x: kotlin.Int, /*1*/ f1: (kotlin.Int) -> kotlin.String, /*2*/ f2: (kotlin.String) -> kotlin.String): kotlin.String
+internal fun fn2(/*0*/ f1: (kotlin.Int) -> kotlin.Int, /*1*/ f2: (kotlin.Int) -> kotlin.String): kotlin.String
+internal fun fn2(/*0*/ f1: (kotlin.Int) -> kotlin.String, /*1*/ f2: (kotlin.String) -> kotlin.String): kotlin.String
+internal fun fn2(/*0*/ f1: (kotlin.String) -> kotlin.String, /*1*/ f2: (kotlin.String) -> kotlin.String): kotlin.String
+internal fun fn3(/*0*/ i: kotlin.Int, /*1*/ f: (kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.Int): kotlin.Int
+internal fun foo(/*0*/ i: kotlin.Int): kotlin.String
+internal fun foo(/*0*/ s: kotlin.String): kotlin.String
+internal fun qux(/*0*/ i: kotlin.Int, /*1*/ j: kotlin.Int, /*2*/ k: kotlin.Int): kotlin.Int
+internal fun qux(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String, /*2*/ c: kotlin.String, /*3*/ d: kotlin.String): kotlin.Unit
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.kt
new file mode 100644
index 00000000000..e54c17dbfd8
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.kt
@@ -0,0 +1,10 @@
+// !DIAGNOSTICS: -UNUSED_PARAMETER
+
+fun foo(vararg ii: Int) {}
+fun foo(vararg ss: String) {}
+fun foo(i: Int) {}
+
+val fn1: (Int) -> Unit = ::foo
+val fn2: (IntArray) -> Unit = ::foo
+val fn3: (Int, Int) -> Unit = ::foo
+val fn4: (Array) -> Unit = ::foo
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.txt
new file mode 100644
index 00000000000..a510ae2753b
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.txt
@@ -0,0 +1,9 @@
+package
+
+internal val fn1: (kotlin.Int) -> kotlin.Unit
+internal val fn2: (kotlin.IntArray) -> kotlin.Unit
+internal val fn3: (kotlin.Int, kotlin.Int) -> kotlin.Unit
+internal val fn4: (kotlin.Array) -> kotlin.Unit
+internal fun foo(/*0*/ vararg ss: kotlin.String /*kotlin.Array*/): kotlin.Unit
+internal fun foo(/*0*/ i: kotlin.Int): kotlin.Unit
+internal fun foo(/*0*/ vararg ii: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java
index 5501b63a16a..ca049caf9b2 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java
@@ -1352,6 +1352,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
+ @TestMetadata("constructorFromCompanion.kt")
+ public void testConstructorFromCompanion() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/constructorFromCompanion.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("constructorFromExtension.kt")
public void testConstructorFromExtension() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/constructorFromExtension.kt");
@@ -1721,18 +1727,99 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
+ @TestMetadata("returnTypeDependentOnGenericProperty.kt")
+ public void testReturnTypeDependentOnGenericProperty() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/returnTypeDependentOnGenericProperty.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("samePriorityForFunctionsAndProperties.kt")
public void testSamePriorityForFunctionsAndProperties() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/samePriorityForFunctionsAndProperties.kt");
doTest(fileName);
}
+ @TestMetadata("syntheticProperties.kt")
+ public void testSyntheticProperties() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/syntheticProperties.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("topLevelFromTopLevel.kt")
public void testTopLevelFromTopLevel() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/topLevelFromTopLevel.kt");
doTest(fileName);
}
}
+
+ @TestMetadata("compiler/testData/diagnostics/tests/callableReference/resolve")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Resolve extends AbstractJetDiagnosticsTest {
+ public void testAllFilesPresentInResolve() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/resolve"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("byArgType.kt")
+ public void testByArgType() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("byGenericArgType.kt")
+ public void testByGenericArgType() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/byGenericArgType.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("byValType.kt")
+ public void testByValType() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("constructor.kt")
+ public void testConstructor() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("valVsFun.kt")
+ public void testValVsFun() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/valVsFun.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withAs.kt")
+ public void testWithAs() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/withAs.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withExtFun.kt")
+ public void testWithExtFun() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withGenericFun.kt")
+ public void testWithGenericFun() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/withGenericFun.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withPlaceholderTypes.kt")
+ public void testWithPlaceholderTypes() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/withPlaceholderTypes.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withVararg.kt")
+ public void testWithVararg() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.kt");
+ doTest(fileName);
+ }
+ }
}
@TestMetadata("compiler/testData/diagnostics/tests/cast")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java
index 2407669c3b4..590a7e9e258 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java
@@ -561,6 +561,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
+ @TestMetadata("overloadedFun.kt")
+ public void testOverloadedFun() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFun.kt");
+ doTestWithStdlib(fileName);
+ }
+
+ @TestMetadata("overloadedFunVsVal.kt")
+ public void testOverloadedFunVsVal() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/overloadedFunVsVal.kt");
+ doTestWithStdlib(fileName);
+ }
+
@TestMetadata("privateClassMember.kt")
public void testPrivateClassMember() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/privateClassMember.kt");
diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt
index 787d7a775da..37449a6f691 100644
--- a/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt
+++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.types.*
+import org.jetbrains.kotlin.utils.addToStdlib.singletonList
import java.util.ArrayList
val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
@@ -112,5 +113,33 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
val containingPackage = DescriptorUtils.getParentOfType(descriptor, javaClass())
return containingPackage != null && containingPackage.fqName == KOTLIN_REFLECT_FQ_NAME
}
+
+ private val PROPERTY_CLASS_NAMES = hashSetOf(
+ "KProperty", "KMutableProperty",
+ "KProperty0", "KMutableProperty0",
+ "KProperty1", "KMutableProperty1",
+ "KProperty2", "KMutableProperty2"
+ )
+
+ public fun isCallableType(type: JetType): Boolean =
+ KotlinBuiltIns.isFunctionOrExtensionFunctionType(type) ||
+ isPropertyType(type)
+
+ public fun isPropertyType(type: JetType): Boolean =
+ isExactPropertyType(type) ||
+ type.getConstructor().getSupertypes().any { isPropertyType(it) }
+
+ public fun isExactPropertyType(type: JetType): Boolean {
+ val descriptor = type.getConstructor().getDeclarationDescriptor()
+ if (descriptor is ClassDescriptor) {
+ val fqName = DescriptorUtils.getFqName(descriptor)
+ val parentName = fqName.parent().asString()
+ if (parentName != KOTLIN_REFLECT_FQ_NAME.asString())
+ return false
+ val shortName = fqName.shortName().asString()
+ return PROPERTY_CLASS_NAMES.contains(shortName)
+ }
+ return false
+ }
}
}
diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt
index 577e5bc0566..3ea039e175c 100644
--- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt
+++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
-import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
@@ -165,7 +165,7 @@ public class ShadowedDeclarationsFilter(
val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression)
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo,
- ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
+ ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false)
val callResolver = createContainerForMacros(project, moduleDescriptor).callResolver
val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context)
diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt
index 67a10814495..3f0f700675a 100644
--- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt
+++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.noErrorsInValueArguments
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
-import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode
+import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
@@ -155,7 +155,7 @@ class ExpectedInfos(
val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression)
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion")
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, truncatedCall, expectedType, dataFlowInfo,
- ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
+ ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false)
val callResolutionContext = context.replaceCollectAllCandidates(true)
val callResolver = createContainerForMacros(