Support overload ambiguity resolution for callable references by expected type.
Resolve callable references taking into account expected callable types. This affects call resolution procedure (resolve 'foo' in for 'foo(::bar)') similar to the approach used for function literals: * During "shape arguments" phase of call resolution, callable references are resolved in independent context without expected type. If the callable reference is ambiguous, its shape type is a function placeholder type without parameter types and return type information. Otherwise, it is a reflection type for the resolved function or property. Upper-level call is resolved without taking into account ambiguous callable references. * During "complete call" phase of call resolution, resolve callable reference arguments to actual descriptors (if possible), and update constraint system for the given call accordingly. #KT-6982 Fixed #KT-5780 Fixed
This commit is contained in:
Generated
+2
@@ -4,7 +4,9 @@
|
|||||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
<option name="BUILD_PROCESS_HEAP_SIZE" value="2000" />
|
<option name="BUILD_PROCESS_HEAP_SIZE" value="2000" />
|
||||||
<excludeFromCompile>
|
<excludeFromCompile>
|
||||||
|
<directory url="file://$PROJECT_DIR$/core/reflection" includeSubdirectories="true" />
|
||||||
<directory url="file://$PROJECT_DIR$/core/reflection.jvm" includeSubdirectories="true" />
|
<directory url="file://$PROJECT_DIR$/core/reflection.jvm" includeSubdirectories="true" />
|
||||||
|
<directory url="file://$PROJECT_DIR$/core/reflection.stub.jvm" includeSubdirectories="true" />
|
||||||
</excludeFromCompile>
|
</excludeFromCompile>
|
||||||
<resourceExtensions />
|
<resourceExtensions />
|
||||||
<wildcardResourcePatterns>
|
<wildcardResourcePatterns>
|
||||||
|
|||||||
+276
@@ -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 <D : CallableDescriptor> ResolveArgumentsMode.acceptResolution(results: OverloadResolutionResults<D>, 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<CallableDescriptor> {
|
||||||
|
val call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.instance<ValueArgument>())
|
||||||
|
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<CallableDescriptor>? {
|
||||||
|
val reference = callableReferenceExpression.getCallableReference()
|
||||||
|
|
||||||
|
fun resolveInScope(traceTitle: String, scope: JetScope): OverloadResolutionResults<CallableDescriptor> {
|
||||||
|
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<CallableDescriptor> {
|
||||||
|
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("<anonymous>"),
|
||||||
|
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<CallableDescriptor>?,
|
||||||
|
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)
|
||||||
|
}
|
||||||
+72
-10
@@ -20,16 +20,20 @@ import com.google.common.collect.Lists;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
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.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.*;
|
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.callResolverUtil.ResolveArgumentsMode;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext;
|
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.context.ResolutionContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
|
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.DataFlowInfo;
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
|
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 {
|
public class ArgumentTypeResolver {
|
||||||
@NotNull private final TypeResolver typeResolver;
|
@NotNull private final TypeResolver typeResolver;
|
||||||
|
@NotNull private final CallResolver callResolver;
|
||||||
@NotNull private final ExpressionTypingServices expressionTypingServices;
|
@NotNull private final ExpressionTypingServices expressionTypingServices;
|
||||||
@NotNull private final KotlinBuiltIns builtIns;
|
@NotNull private final KotlinBuiltIns builtIns;
|
||||||
|
@NotNull private final ReflectionTypes reflectionTypes;
|
||||||
|
|
||||||
public ArgumentTypeResolver(
|
public ArgumentTypeResolver(
|
||||||
@NotNull KotlinBuiltIns builtIns,
|
@NotNull TypeResolver typeResolver,
|
||||||
|
@NotNull CallResolver callResolver,
|
||||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||||
@NotNull TypeResolver typeResolver
|
@NotNull KotlinBuiltIns builtIns,
|
||||||
|
@NotNull ReflectionTypes reflectionTypes
|
||||||
) {
|
) {
|
||||||
this.builtIns = builtIns;
|
|
||||||
this.expressionTypingServices = expressionTypingServices;
|
|
||||||
this.typeResolver = typeResolver;
|
this.typeResolver = typeResolver;
|
||||||
|
this.callResolver = callResolver;
|
||||||
|
this.expressionTypingServices = expressionTypingServices;
|
||||||
|
this.builtIns = builtIns;
|
||||||
|
this.reflectionTypes = reflectionTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSubtypeOfForArgumentType(
|
public static boolean isSubtypeOfForArgumentType(
|
||||||
@@ -92,7 +102,7 @@ public class ArgumentTypeResolver {
|
|||||||
@NotNull CallResolutionContext<?> context,
|
@NotNull CallResolutionContext<?> context,
|
||||||
@NotNull ResolveArgumentsMode resolveFunctionArgumentBodies
|
@NotNull ResolveArgumentsMode resolveFunctionArgumentBodies
|
||||||
) {
|
) {
|
||||||
if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return;
|
if (context.checkArguments != CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) return;
|
||||||
|
|
||||||
for (ValueArgument valueArgument : context.call.getValueArguments()) {
|
for (ValueArgument valueArgument : context.call.getValueArguments()) {
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
@@ -117,7 +127,7 @@ public class ArgumentTypeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkTypesForFunctionArgumentsWithNoCallee(@NotNull CallResolutionContext<?> context) {
|
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()) {
|
for (ValueArgument valueArgument : context.call.getValueArguments()) {
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
@@ -148,7 +158,7 @@ public class ArgumentTypeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static JetFunction getFunctionLiteralArgumentIfAny(
|
public static JetFunction getFunctionLiteralArgumentIfAny(
|
||||||
@NotNull JetExpression expression, @NotNull ResolutionContext context
|
@NotNull JetExpression expression, @NotNull ResolutionContext context
|
||||||
) {
|
) {
|
||||||
JetExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, context.statementFilter);
|
JetExpression deparenthesizedExpression = getLastElementDeparenthesized(expression, context.statementFilter);
|
||||||
@@ -181,6 +191,18 @@ public class ArgumentTypeResolver {
|
|||||||
return deparenthesizedExpression;
|
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
|
@NotNull
|
||||||
public JetTypeInfo getArgumentTypeInfo(
|
public JetTypeInfo getArgumentTypeInfo(
|
||||||
@Nullable JetExpression expression,
|
@Nullable JetExpression expression,
|
||||||
@@ -190,18 +212,58 @@ public class ArgumentTypeResolver {
|
|||||||
if (expression == null) {
|
if (expression == null) {
|
||||||
return TypeInfoFactoryPackage.noTypeInfo(context);
|
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());
|
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||||
if (recordedTypeInfo != null) {
|
if (recordedTypeInfo != null) {
|
||||||
return recordedTypeInfo;
|
return recordedTypeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolutionContext newContext = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(DEPENDENT);
|
ResolutionContext newContext = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(DEPENDENT);
|
||||||
|
|
||||||
return expressionTypingServices.getTypeInfo(expression, newContext);
|
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<CallableDescriptor> overloadResolutionResults =
|
||||||
|
CallableReferencesPackage.resolvePossiblyAmbiguousCallableReference(
|
||||||
|
callableReferenceExpression, receiverType, context, ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS,
|
||||||
|
callResolver);
|
||||||
|
return CallableReferencesPackage.getResolvedCallableReferenceShapeType(
|
||||||
|
callableReferenceExpression, overloadResolutionResults, context, expectedTypeIsUnknown,
|
||||||
|
reflectionTypes, builtIns);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetTypeInfo getFunctionLiteralTypeInfo(
|
public JetTypeInfo getFunctionLiteralTypeInfo(
|
||||||
@NotNull JetExpression expression,
|
@NotNull JetExpression expression,
|
||||||
|
|||||||
@@ -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.callResolverUtil.isInvokeCallOnVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
|
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.ConstraintSystemImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
|
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
||||||
@@ -194,7 +194,7 @@ public class CallCompleter(
|
|||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
results: OverloadResolutionResultsImpl<D>
|
results: OverloadResolutionResultsImpl<D>
|
||||||
) {
|
) {
|
||||||
if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return
|
if (context.checkArguments != CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) return
|
||||||
|
|
||||||
val getArgumentMapping: (ValueArgument) -> ArgumentMapping
|
val getArgumentMapping: (ValueArgument) -> ArgumentMapping
|
||||||
val getDataFlowInfoForArgument: (ValueArgument) -> DataFlowInfo
|
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),
|
// 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).
|
// but they should be analyzed when the expected type is known (during the call completion).
|
||||||
if (ArgumentTypeResolver.isFunctionLiteralArgument(expression, context)) {
|
ArgumentTypeResolver.getFunctionLiteralArgumentIfAny(expression, context)?.let { functionLiteralArgument ->
|
||||||
argumentTypeResolver.getFunctionLiteralTypeInfo(
|
argumentTypeResolver.getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, RESOLVE_FUNCTION_ARGUMENTS)
|
||||||
expression, ArgumentTypeResolver.getFunctionLiteralArgument(expression, context),
|
}
|
||||||
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)
|
DataFlowUtils.checkType(updatedType, deparenthesized, context)
|
||||||
|
|||||||
+5
-5
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
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.ResolutionContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
|
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
@@ -78,7 +78,7 @@ public class CallExpressionResolver {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
|
public ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
|
||||||
@NotNull Call call, @NotNull JetExpression callExpression,
|
@NotNull Call call, @NotNull JetExpression callExpression,
|
||||||
@NotNull ResolutionContext context, @NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull ResolutionContext context, @NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@NotNull boolean[] result
|
@NotNull boolean[] result
|
||||||
) {
|
) {
|
||||||
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
|
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
|
||||||
@@ -101,7 +101,7 @@ public class CallExpressionResolver {
|
|||||||
Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression);
|
Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression);
|
||||||
BasicCallResolutionContext contextForVariable = BasicCallResolutionContext.create(
|
BasicCallResolutionContext contextForVariable = BasicCallResolutionContext.create(
|
||||||
context.replaceTraceAndCache(temporaryForVariable),
|
context.replaceTraceAndCache(temporaryForVariable),
|
||||||
call, CheckValueArgumentsMode.ENABLED);
|
call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
|
||||||
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
|
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
|
||||||
|
|
||||||
// if the expression is a receiver in a qualified expression, it should be resolved after the selector is resolved
|
// 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);
|
context, "trace to resolve as function", nameExpression);
|
||||||
ResolutionContext newContext = context.replaceTraceAndCache(temporaryForFunction);
|
ResolutionContext newContext = context.replaceTraceAndCache(temporaryForFunction);
|
||||||
ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(
|
ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(
|
||||||
call, nameExpression, newContext, CheckValueArgumentsMode.ENABLED, result);
|
call, nameExpression, newContext, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, result);
|
||||||
if (result[0]) {
|
if (result[0]) {
|
||||||
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
|
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
|
||||||
temporaryForFunction.commit();
|
temporaryForFunction.commit();
|
||||||
@@ -198,7 +198,7 @@ public class CallExpressionResolver {
|
|||||||
call, callExpression,
|
call, callExpression,
|
||||||
// It's possible start of a call so we should reset safe call chain
|
// It's possible start of a call so we should reset safe call chain
|
||||||
context.replaceTraceAndCache(temporaryForFunction).replaceInsideCallChain(false),
|
context.replaceTraceAndCache(temporaryForFunction).replaceInsideCallChain(false),
|
||||||
CheckValueArgumentsMode.ENABLED, result);
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, result);
|
||||||
if (result[0]) {
|
if (result[0]) {
|
||||||
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
|
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
|
||||||
temporaryForFunction.commit();
|
temporaryForFunction.commit();
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ public class CallResolver {
|
|||||||
@NotNull JetReferenceExpression functionReference,
|
@NotNull JetReferenceExpression functionReference,
|
||||||
@NotNull Name name
|
@NotNull Name name
|
||||||
) {
|
) {
|
||||||
BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED);
|
BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
|
||||||
return computeTasksAndResolveCall(
|
return computeTasksAndResolveCall(
|
||||||
callResolutionContext, name, functionReference,
|
callResolutionContext, name, functionReference,
|
||||||
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
||||||
@@ -263,7 +263,7 @@ public class CallResolver {
|
|||||||
) {
|
) {
|
||||||
return resolveFunctionCall(
|
return resolveFunctionCall(
|
||||||
BasicCallResolutionContext.create(
|
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.getCallChecker(), additionalCheckerProvider.getSymbolUsageValidator(),
|
||||||
additionalCheckerProvider.getTypeChecker(), isAnnotationContext)
|
additionalCheckerProvider.getTypeChecker(), isAnnotationContext)
|
||||||
);
|
);
|
||||||
@@ -344,7 +344,7 @@ public class CallResolver {
|
|||||||
trace, scope,
|
trace, scope,
|
||||||
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
|
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
|
||||||
NO_EXPECTED_TYPE,
|
NO_EXPECTED_TYPE,
|
||||||
dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
|
dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
callChecker, additionalCheckerProvider.getSymbolUsageValidator(), additionalCheckerProvider.getTypeChecker(), false);
|
callChecker, additionalCheckerProvider.getSymbolUsageValidator(), additionalCheckerProvider.getTypeChecker(), false);
|
||||||
|
|
||||||
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
|
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
|
||||||
@@ -430,7 +430,7 @@ public class CallResolver {
|
|||||||
@Override
|
@Override
|
||||||
public OverloadResolutionResults<FunctionDescriptor> invoke() {
|
public OverloadResolutionResults<FunctionDescriptor> invoke() {
|
||||||
BasicCallResolutionContext basicCallResolutionContext =
|
BasicCallResolutionContext basicCallResolutionContext =
|
||||||
BasicCallResolutionContext.create(context, call, CheckValueArgumentsMode.ENABLED, dataFlowInfoForArguments);
|
BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, dataFlowInfoForArguments);
|
||||||
|
|
||||||
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks =
|
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks =
|
||||||
taskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
|
taskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
|
||||||
@@ -484,7 +484,7 @@ public class CallResolver {
|
|||||||
|
|
||||||
CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
|
CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
|
||||||
results.getResultingCall(), context, tracing);
|
results.getResultingCall(), context, tracing);
|
||||||
genericCandidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext);
|
genericCandidateResolver.completeTypeInferenceDependentOnFunctionArgumentsForCall(candidateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <F extends CallableDescriptor> void cacheResults(
|
private static <F extends CallableDescriptor> void cacheResults(
|
||||||
@@ -515,7 +515,7 @@ public class CallResolver {
|
|||||||
@NotNull CallTransformer<D, F> callTransformer,
|
@NotNull CallTransformer<D, F> callTransformer,
|
||||||
@NotNull TracingStrategy tracing
|
@NotNull TracingStrategy tracing
|
||||||
) {
|
) {
|
||||||
if (context.checkArguments == CheckValueArgumentsMode.ENABLED) {
|
if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
|
||||||
argumentTypeResolver.analyzeArgumentsAndRecordTypes(context);
|
argumentTypeResolver.analyzeArgumentsAndRecordTypes(context);
|
||||||
}
|
}
|
||||||
Collection<ResolvedCall<F>> allCandidates = Lists.newArrayList();
|
Collection<ResolvedCall<F>> allCandidates = Lists.newArrayList();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.callResolverUtil
|
|||||||
import com.google.common.collect.Lists
|
import com.google.common.collect.Lists
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
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.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
public enum class ResolveArgumentsMode {
|
public enum class ResolveArgumentsMode {
|
||||||
RESOLVE_FUNCTION_ARGUMENTS,
|
RESOLVE_FUNCTION_ARGUMENTS,
|
||||||
@@ -41,30 +44,34 @@ public enum class ResolveArgumentsMode {
|
|||||||
|
|
||||||
|
|
||||||
public fun hasUnknownFunctionParameter(type: JetType): Boolean {
|
public fun hasUnknownFunctionParameter(type: JetType): Boolean {
|
||||||
assert(KotlinBuiltIns.isFunctionOrExtensionFunctionType(type))
|
assert(ReflectionTypes.isCallableType(type), "type is not a function or property")
|
||||||
val arguments = type.getArguments()
|
return getParameterArgumentsOfCallableType(type).any {
|
||||||
// last argument is return type of function type
|
|
||||||
val functionParameters = arguments.subList(0, arguments.size() - 1)
|
|
||||||
return functionParameters.any {
|
|
||||||
TypeUtils.containsSpecialType(it.getType(), DONT_CARE) || ErrorUtils.containsUninferredParameter(it.getType())
|
TypeUtils.containsSpecialType(it.getType(), DONT_CARE) || ErrorUtils.containsUninferredParameter(it.getType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun hasUnknownReturnType(type: JetType): Boolean {
|
public fun hasUnknownReturnType(type: JetType): Boolean {
|
||||||
assert(KotlinBuiltIns.isFunctionOrExtensionFunctionType(type))
|
assert(ReflectionTypes.isCallableType(type), "type is not a function or property")
|
||||||
val returnTypeFromFunctionType = KotlinBuiltIns.getReturnTypeFromFunctionType(type)
|
return ErrorUtils.containsErrorType(getReturnTypeForCallable(type))
|
||||||
return ErrorUtils.containsErrorType(returnTypeFromFunctionType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun replaceReturnTypeByUnknown(type: JetType): JetType {
|
public fun replaceReturnTypeByUnknown(type: JetType): JetType {
|
||||||
assert(KotlinBuiltIns.isFunctionOrExtensionFunctionType(type))
|
assert(ReflectionTypes.isCallableType(type), "type is not a function or property")
|
||||||
val arguments = type.getArguments()
|
|
||||||
val newArguments = Lists.newArrayList<TypeProjection>()
|
val newArguments = Lists.newArrayList<TypeProjection>()
|
||||||
newArguments.addAll(arguments.subList(0, arguments.size() - 1))
|
newArguments.addAll(getParameterArgumentsOfCallableType(type))
|
||||||
newArguments.add(TypeProjectionImpl(Variance.INVARIANT, DONT_CARE))
|
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<TypeProjection>) =
|
||||||
|
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 {
|
private fun CallableDescriptor.hasReturnTypeDependentOnUninferredParams(constraintSystem: ConstraintSystem): Boolean {
|
||||||
val returnType = getReturnType() ?: return false
|
val returnType = getReturnType() ?: return false
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,14 @@ package org.jetbrains.kotlin.resolve.calls
|
|||||||
import com.google.common.collect.Lists
|
import com.google.common.collect.Lists
|
||||||
import com.google.common.collect.Sets
|
import com.google.common.collect.Sets
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT
|
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.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.*
|
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.CallTransformer.CallForImplicitInvoke
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS
|
||||||
@@ -60,11 +62,14 @@ import java.util.ArrayList
|
|||||||
|
|
||||||
public class CandidateResolver(
|
public class CandidateResolver(
|
||||||
private val argumentTypeResolver: ArgumentTypeResolver,
|
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||||
private val genericCandidateResolver: GenericCandidateResolver
|
private val genericCandidateResolver: GenericCandidateResolver,
|
||||||
|
private val reflectionTypes: ReflectionTypes
|
||||||
){
|
){
|
||||||
|
|
||||||
public fun <D : CallableDescriptor, F : D> performResolutionForCandidateCall(context: CallCandidateResolutionContext<D>,
|
public fun <D : CallableDescriptor, F : D> performResolutionForCandidateCall(
|
||||||
task: ResolutionTask<D, F>): Unit = with(context) {
|
context: CallCandidateResolutionContext<D>,
|
||||||
|
task: ResolutionTask<D, F>
|
||||||
|
): Unit = with(context) {
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
if (ErrorUtils.isError(candidateDescriptor)) {
|
if (ErrorUtils.isError(candidateDescriptor)) {
|
||||||
@@ -78,7 +83,13 @@ public class CandidateResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkVisibility()
|
checkVisibility()
|
||||||
mapArguments(task)
|
|
||||||
|
when (task.checkArguments) {
|
||||||
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
|
||||||
|
mapArguments()
|
||||||
|
CheckArgumentTypesMode.CHECK_CALLABLE_TYPE ->
|
||||||
|
checkExpectedCallableType()
|
||||||
|
}
|
||||||
|
|
||||||
checkReceiverTypeError()
|
checkReceiverTypeError()
|
||||||
checkExtensionReceiver()
|
checkExtensionReceiver()
|
||||||
@@ -143,15 +154,27 @@ public class CandidateResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : CallableDescriptor, F : D> CallCandidateResolutionContext<D>.mapArguments(task: ResolutionTask<D, F>) = check {
|
private fun <D : CallableDescriptor, F : D> CallCandidateResolutionContext<D>.mapArguments()
|
||||||
if (task.checkArguments == CheckValueArgumentsMode.ENABLED) {
|
= check {
|
||||||
val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
|
val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
|
||||||
call, tracing, candidateCall, Sets.newLinkedHashSet<ValueArgument>())
|
call, tracing, candidateCall, Sets.newLinkedHashSet<ValueArgument>())
|
||||||
if (!argumentMappingStatus.isSuccess()) {
|
if (!argumentMappingStatus.isSuccess()) {
|
||||||
candidateCall.addStatus(OTHER_ERROR)
|
candidateCall.addStatus(OTHER_ERROR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <D : CallableDescriptor, F : D> CallCandidateResolutionContext<D>.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 {
|
private fun CallCandidateResolutionContext<*>.checkVisibility() = checkAndReport {
|
||||||
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(),
|
val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(),
|
||||||
|
|||||||
+64
-10
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.resolve.calls
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.JetPsiUtil
|
|
||||||
import org.jetbrains.kotlin.psi.ValueArgument
|
|
||||||
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
|
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
|
||||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver.getLastElementDeparenthesized
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver.getLastElementDeparenthesized
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.*
|
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
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
|
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.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
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
|
||||||
@@ -197,7 +196,7 @@ class GenericCandidateResolver(
|
|||||||
return TypeUtils.intersect(JetTypeChecker.DEFAULT, possibleTypes)
|
return TypeUtils.intersect(JetTypeChecker.DEFAULT, possibleTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <D : CallableDescriptor> completeTypeInferenceDependentOnFunctionLiteralsForCall(
|
public fun <D : CallableDescriptor> completeTypeInferenceDependentOnFunctionArgumentsForCall(
|
||||||
context: CallCandidateResolutionContext<D>
|
context: CallCandidateResolutionContext<D>
|
||||||
) {
|
) {
|
||||||
val resolvedCall = context.candidateCall
|
val resolvedCall = context.candidateCall
|
||||||
@@ -210,30 +209,35 @@ class GenericCandidateResolver(
|
|||||||
val valueParameterDescriptor = entry.getKey()
|
val valueParameterDescriptor = entry.getKey()
|
||||||
|
|
||||||
for (valueArgument in resolvedValueArgument.getArguments()) {
|
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())
|
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : CallableDescriptor> addConstraintForFunctionLiteral(
|
private fun <D : CallableDescriptor> addConstraintForFunctionLiteral(
|
||||||
|
functionLiteral: JetFunction,
|
||||||
valueArgument: ValueArgument,
|
valueArgument: ValueArgument,
|
||||||
valueParameterDescriptor: ValueParameterDescriptor,
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
constraintSystem: ConstraintSystem,
|
constraintSystem: ConstraintSystem,
|
||||||
context: CallCandidateResolutionContext<D>
|
context: CallCandidateResolutionContext<D>
|
||||||
) {
|
) {
|
||||||
val argumentExpression = valueArgument.getArgumentExpression() ?: return
|
val argumentExpression = valueArgument.getArgumentExpression() ?: return
|
||||||
if (!ArgumentTypeResolver.isFunctionLiteralArgument(argumentExpression, context)) return
|
|
||||||
|
|
||||||
val functionLiteral = ArgumentTypeResolver.getFunctionLiteralArgument(argumentExpression, context)
|
|
||||||
|
|
||||||
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
|
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
|
||||||
var expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
|
var expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
|
||||||
if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) {
|
if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) {
|
||||||
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false)
|
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false)
|
||||||
}
|
}
|
||||||
if (expectedType == null || !KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType)
|
if (expectedType == null || !KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType) ||
|
||||||
|| hasUnknownFunctionParameter(expectedType)) {
|
hasUnknownFunctionParameter(expectedType)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val dataFlowInfoForArguments = context.candidateCall.getDataFlowInfoForArguments()
|
val dataFlowInfoForArguments = context.candidateCall.getDataFlowInfoForArguments()
|
||||||
@@ -267,6 +271,56 @@ class GenericCandidateResolver(
|
|||||||
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
|
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
|
||||||
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, position)
|
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <D : CallableDescriptor> addConstraintForCallableReference(
|
||||||
|
callableReference: JetCallableReferenceExpression,
|
||||||
|
valueArgument: ValueArgument,
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
|
constraintSystem: ConstraintSystem,
|
||||||
|
context: CallCandidateResolutionContext<D>
|
||||||
|
) {
|
||||||
|
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 <D : CallableDescriptor> getExpectedTypeForCallableReference(
|
||||||
|
callableReference: JetCallableReferenceExpression,
|
||||||
|
constraintSystem: ConstraintSystem,
|
||||||
|
context: CallCandidateResolutionContext<D>,
|
||||||
|
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 <D : CallableDescriptor> getResolvedTypeForCallableReference(
|
||||||
|
callableReference: JetCallableReferenceExpression,
|
||||||
|
context: CallCandidateResolutionContext<D>,
|
||||||
|
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? {
|
fun getResolutionResultsCachedData(expression: JetExpression?, context: ResolutionContext<*>): ResolutionResultsCache.CachedData? {
|
||||||
|
|||||||
+4
-4
@@ -37,7 +37,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull DataFlowInfo dataFlowInfo,
|
@NotNull DataFlowInfo dataFlowInfo,
|
||||||
@NotNull ContextDependency contextDependency,
|
@NotNull ContextDependency contextDependency,
|
||||||
@NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@NotNull ResolutionResultsCache resolutionResultsCache,
|
@NotNull ResolutionResultsCache resolutionResultsCache,
|
||||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
||||||
@NotNull CallChecker callChecker,
|
@NotNull CallChecker callChecker,
|
||||||
@@ -60,7 +60,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull DataFlowInfo dataFlowInfo,
|
@NotNull DataFlowInfo dataFlowInfo,
|
||||||
@NotNull ContextDependency contextDependency,
|
@NotNull ContextDependency contextDependency,
|
||||||
@NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@NotNull CallChecker callChecker,
|
@NotNull CallChecker callChecker,
|
||||||
@NotNull SymbolUsageValidator symbolUsageValidator,
|
@NotNull SymbolUsageValidator symbolUsageValidator,
|
||||||
@NotNull AdditionalTypeChecker additionalTypeChecker,
|
@NotNull AdditionalTypeChecker additionalTypeChecker,
|
||||||
@@ -73,7 +73,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static BasicCallResolutionContext create(
|
public static BasicCallResolutionContext create(
|
||||||
@NotNull ResolutionContext context, @NotNull Call call, @NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull ResolutionContext context, @NotNull Call call, @NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments
|
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments
|
||||||
) {
|
) {
|
||||||
return new BasicCallResolutionContext(
|
return new BasicCallResolutionContext(
|
||||||
@@ -85,7 +85,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static BasicCallResolutionContext create(
|
public static BasicCallResolutionContext create(
|
||||||
@NotNull ResolutionContext context, @NotNull Call call, @NotNull CheckValueArgumentsMode checkArguments
|
@NotNull ResolutionContext context, @NotNull Call call, @NotNull CheckArgumentTypesMode checkArguments
|
||||||
) {
|
) {
|
||||||
return create(context, call, checkArguments, null);
|
return create(context, call, checkArguments, null);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull DataFlowInfo dataFlowInfo,
|
@NotNull DataFlowInfo dataFlowInfo,
|
||||||
@NotNull ContextDependency contextDependency,
|
@NotNull ContextDependency contextDependency,
|
||||||
@NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@NotNull ResolutionResultsCache resolutionResultsCache,
|
@NotNull ResolutionResultsCache resolutionResultsCache,
|
||||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
||||||
@NotNull CallChecker callChecker,
|
@NotNull CallChecker callChecker,
|
||||||
|
|||||||
+3
-3
@@ -34,7 +34,7 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
|
|||||||
@NotNull
|
@NotNull
|
||||||
public final Call call;
|
public final Call call;
|
||||||
@NotNull
|
@NotNull
|
||||||
public final CheckValueArgumentsMode checkArguments;
|
public final CheckArgumentTypesMode checkArguments;
|
||||||
@NotNull
|
@NotNull
|
||||||
public final MutableDataFlowInfoForArguments dataFlowInfoForArguments;
|
public final MutableDataFlowInfoForArguments dataFlowInfoForArguments;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull DataFlowInfo dataFlowInfo,
|
@NotNull DataFlowInfo dataFlowInfo,
|
||||||
@NotNull ContextDependency contextDependency,
|
@NotNull ContextDependency contextDependency,
|
||||||
@NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@NotNull ResolutionResultsCache resolutionResultsCache,
|
@NotNull ResolutionResultsCache resolutionResultsCache,
|
||||||
@SuppressWarnings("NullableProblems")
|
@SuppressWarnings("NullableProblems")
|
||||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
||||||
@@ -65,7 +65,7 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
|
|||||||
if (dataFlowInfoForArguments != null) {
|
if (dataFlowInfoForArguments != null) {
|
||||||
this.dataFlowInfoForArguments = dataFlowInfoForArguments;
|
this.dataFlowInfoForArguments = dataFlowInfoForArguments;
|
||||||
}
|
}
|
||||||
else if (checkArguments == CheckValueArgumentsMode.ENABLED) {
|
else if (checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
|
||||||
this.dataFlowInfoForArguments = new DataFlowInfoForArgumentsImpl(call);
|
this.dataFlowInfoForArguments = new DataFlowInfoForArgumentsImpl(call);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
+9
-3
@@ -16,7 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.context;
|
package org.jetbrains.kotlin.resolve.calls.context;
|
||||||
|
|
||||||
public enum CheckValueArgumentsMode {
|
public enum CheckArgumentTypesMode {
|
||||||
ENABLED,
|
/**
|
||||||
DISABLED
|
* Check value argument types for particular call.
|
||||||
|
*/
|
||||||
|
CHECK_VALUE_ARGUMENTS,
|
||||||
|
/**
|
||||||
|
* Match callable reference type against expected (callable) type.
|
||||||
|
*/
|
||||||
|
CHECK_CALLABLE_TYPE
|
||||||
}
|
}
|
||||||
+2
-2
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode;
|
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask;
|
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask;
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ public class ResolutionResultsHandler {
|
|||||||
boolean allCandidatesIncomplete = allIncomplete(results.getResultingCalls());
|
boolean allCandidatesIncomplete = allIncomplete(results.getResultingCalls());
|
||||||
// This check is needed for the following case:
|
// This check is needed for the following case:
|
||||||
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
|
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
|
||||||
if (task.checkArguments == CheckValueArgumentsMode.DISABLED ||
|
if (task.checkArguments != CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ||
|
||||||
!CallUtilPackage.hasUnresolvedArguments(task.call, task)) {
|
!CallUtilPackage.hasUnresolvedArguments(task.call, task)) {
|
||||||
if (allCandidatesIncomplete) {
|
if (allCandidatesIncomplete) {
|
||||||
task.tracing.cannotCompleteResolve(task.trace, results.getResultingCalls());
|
task.tracing.cannotCompleteResolve(task.trace, results.getResultingCalls());
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull DataFlowInfo dataFlowInfo,
|
@NotNull DataFlowInfo dataFlowInfo,
|
||||||
@NotNull ContextDependency contextDependency,
|
@NotNull ContextDependency contextDependency,
|
||||||
@NotNull CheckValueArgumentsMode checkArguments,
|
@NotNull CheckArgumentTypesMode checkArguments,
|
||||||
@NotNull ResolutionResultsCache resolutionResultsCache,
|
@NotNull ResolutionResultsCache resolutionResultsCache,
|
||||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
||||||
@NotNull CallChecker callChecker,
|
@NotNull CallChecker callChecker,
|
||||||
|
|||||||
+8
-167
@@ -30,17 +30,15 @@ import org.jetbrains.kotlin.JetNodeTypes;
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
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.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.*;
|
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.CallExpressionResolver;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
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.TemporaryTraceAndCache;
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
|
import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl;
|
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.calls.util.CallMaker;
|
||||||
import org.jetbrains.kotlin.resolve.constants.*;
|
import org.jetbrains.kotlin.resolve.constants.*;
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
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.WritableScopeImpl;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
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.*;
|
||||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryPackage;
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryPackage;
|
||||||
import org.jetbrains.kotlin.types.expressions.unqualifiedSuper.UnqualifiedSuperPackage;
|
import org.jetbrains.kotlin.types.expressions.unqualifiedSuper.UnqualifiedSuperPackage;
|
||||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||||
import org.jetbrains.kotlin.utils.ThrowingList;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
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_KEYWORD;
|
||||||
import static org.jetbrains.kotlin.lexer.JetTokens.AS_SAFE;
|
import static org.jetbrains.kotlin.lexer.JetTokens.AS_SAFE;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
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.DEPENDENT;
|
||||||
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
|
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.calls.smartcasts.DataFlowValueFactory.createDataFlowValue;
|
||||||
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
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.NO_EXPECTED_TYPE;
|
||||||
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
|
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
|
||||||
import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
|
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(RESOLVED_CALL, call, resolvedCall);
|
||||||
trace.record(CALL, expression, call);
|
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.callChecker.check(resolvedCall, resolutionContext);
|
||||||
context.symbolUsageValidator.validateCall(descriptor, trace, expression);
|
context.symbolUsageValidator.validateCall(descriptor, trace, expression);
|
||||||
}
|
}
|
||||||
@@ -676,166 +668,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
) {
|
) {
|
||||||
JetSimpleNameExpression reference = expression.getCallableReference();
|
JetSimpleNameExpression reference = expression.getCallableReference();
|
||||||
|
|
||||||
boolean[] result = new boolean[1];
|
boolean[] resolved = new boolean[1];
|
||||||
CallableDescriptor descriptor = resolveCallableReferenceTarget(
|
CallableDescriptor descriptor = CallableReferencesPackage.resolveCallableReferenceTarget(
|
||||||
lhsType, context.replaceContextDependency(INDEPENDENT), expression, result);
|
expression, lhsType, context, resolved, components.callResolver);
|
||||||
|
if (!resolved[0]) {
|
||||||
if (!result[0]) {
|
|
||||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
||||||
}
|
}
|
||||||
if (descriptor == null) return null;
|
if (descriptor == null) return null;
|
||||||
|
|
||||||
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
|
return CallableReferencesPackage.createReflectionTypeForResolvedCallableReference(expression, descriptor, context, components.reflectionTypes);
|
||||||
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("<anonymous>"),
|
|
||||||
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.<ValueArgument>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<CallableDescriptor> results =
|
|
||||||
components.callResolver.resolveCallForMember(reference, callResolutionContext);
|
|
||||||
if (!results.isNothing()) {
|
|
||||||
temporaryTrace.commit();
|
|
||||||
result[0] = true;
|
|
||||||
ResolvedCall<CallableDescriptor> callable =
|
|
||||||
OverloadResolutionResultsUtil.getResultingCall(results, context.contextDependency);
|
|
||||||
if (callable != null) {
|
|
||||||
return callable.getResultingDescriptor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+5
@@ -21,14 +21,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.analyzer.AnalyzerPackage;
|
import org.jetbrains.kotlin.analyzer.AnalyzerPackage;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
|
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.*;
|
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.ContextDependency;
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
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.calls.smartcasts.DataFlowInfo;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
|
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
|
||||||
@@ -301,4 +305,5 @@ public class ExpressionTypingServices {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -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"
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val x = 1
|
||||||
|
fun x(): String = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
val f1: KProperty1<A, Int> = 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"
|
||||||
|
}
|
||||||
Vendored
+1
-1
@@ -5,5 +5,5 @@ fun foo(<!UNUSED_PARAMETER!>x<!>: Any, y: Int) = y
|
|||||||
fun main() {
|
fun main() {
|
||||||
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
||||||
|
|
||||||
val fooRef: (Int, Any) -> Unit = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
val fooRef: (Int, Any) -> Unit = ::<!NONE_APPLICABLE!>foo<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// FILE: A.kt
|
||||||
|
|
||||||
|
open class A<T>(val x: T)
|
||||||
|
|
||||||
|
// FILE: AFactory.kt
|
||||||
|
|
||||||
|
abstract class AFactory {
|
||||||
|
abstract fun create(): A<Int>?
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Util.kt
|
||||||
|
|
||||||
|
inline fun <reified T> createWith(x: T, f: (T) -> A<T>?)
|
||||||
|
= f(x)
|
||||||
|
|
||||||
|
// FILE: B.kt
|
||||||
|
|
||||||
|
class B(x: Int) : A<Int>(x) {
|
||||||
|
companion object : AFactory() {
|
||||||
|
override fun create(): A<Int>? = createWith(0, ::B)
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
kotlin.inline() internal fun </*0*/ reified T> createWith(/*0*/ x: T, /*1*/ f: (T) -> A<T>?): A<T>?
|
||||||
|
|
||||||
|
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<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
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class B : A<kotlin.Int> {
|
||||||
|
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<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
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import kotlin.reflect.KProperty1
|
||||||
|
|
||||||
|
fun <T, R> getProperty(x: T, property: KProperty1<T, R>): R =
|
||||||
|
property.get(x)
|
||||||
|
|
||||||
|
class Person(val name: String)
|
||||||
|
|
||||||
|
val name1 = getProperty(Person("John Smith"), Person::name)
|
||||||
+12
@@ -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<T, R>): 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
|
||||||
|
}
|
||||||
+19
@@ -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
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal val customerName: kotlin.reflect.KMutableProperty1<Customer, kotlin.String!>
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
fun foo() {}
|
||||||
|
fun foo(s: String) {}
|
||||||
|
|
||||||
|
fun fn(f: () -> Unit) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
fn(::foo)
|
||||||
|
}
|
||||||
@@ -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
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
fun <T> 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>(::<!NONE_APPLICABLE!>foo<!>)
|
||||||
+8
@@ -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
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
fun foo() {}
|
||||||
|
fun foo(s: String) {}
|
||||||
|
|
||||||
|
val x1 = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
||||||
|
val x2: () -> Unit = ::foo
|
||||||
|
val x3: (String) -> Unit = ::foo
|
||||||
|
val x4: (Int) -> Unit = ::<!NONE_APPLICABLE!>foo<!>
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
class Klass {
|
||||||
|
constructor(a: Int) {}
|
||||||
|
constructor(a: String) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun user(f: (Int) -> Klass) {}
|
||||||
|
|
||||||
|
fun fn() {
|
||||||
|
user(::Klass)
|
||||||
|
}
|
||||||
+12
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val x = 1
|
||||||
|
fun x() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f1(): KProperty<Int> = A::x // ok, property
|
||||||
|
fun f2(): (A) -> Unit = A::x // ok, function
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal fun f1(): kotlin.reflect.KProperty<kotlin.Int>
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -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 = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> as () -> Unit
|
||||||
|
val x2 = bar(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> as (String) -> Unit)
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
|
||||||
|
fun <T> 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<KProperty1<A, Int>>(A::foo)
|
||||||
|
val x3: KProperty1<A, Int> = A::foo
|
||||||
|
val x4: (A) -> String = A::foo
|
||||||
|
|
||||||
|
val y0 = A::bar
|
||||||
|
val y1 = ofType<(A) -> Unit>(A::bar)
|
||||||
|
val y2 = ofType<KProperty1<A, Int>>(A::bar)
|
||||||
|
val y3: KProperty1<A, Int> = A::bar
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal val userOfX0: kotlin.Unit
|
||||||
|
internal val x0: kotlin.reflect.KFunction1<A, kotlin.Unit>
|
||||||
|
internal val x1: (A) -> kotlin.Unit
|
||||||
|
internal val x2: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||||
|
internal val x3: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||||
|
internal val x4: (A) -> kotlin.String
|
||||||
|
internal val y0: kotlin.reflect.KFunction1<A, kotlin.Unit>
|
||||||
|
internal val y1: (A) -> kotlin.Unit
|
||||||
|
internal val y2: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||||
|
internal val y3: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||||
|
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
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
fun <T, R> 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, ::<!NONE_APPLICABLE!>foo<!>)
|
||||||
+8
@@ -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
|
||||||
+26
@@ -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(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>, ::bar)
|
||||||
|
val x5 = fn2(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>, ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>)
|
||||||
|
|
||||||
|
val x6 = fn3(1, ::qux)
|
||||||
+18
@@ -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
|
||||||
@@ -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 = <!TYPE_MISMATCH!>::foo<!>
|
||||||
|
val fn4: (Array<String>) -> Unit = ::foo
|
||||||
@@ -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.String>) -> kotlin.Unit
|
||||||
|
internal fun foo(/*0*/ vararg ss: kotlin.String /*kotlin.Array<out kotlin.String>*/): kotlin.Unit
|
||||||
|
internal fun foo(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||||
|
internal fun foo(/*0*/ vararg ii: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
|
||||||
@@ -1352,6 +1352,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("constructorFromExtension.kt")
|
||||||
public void testConstructorFromExtension() throws Exception {
|
public void testConstructorFromExtension() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/constructorFromExtension.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/constructorFromExtension.kt");
|
||||||
@@ -1721,18 +1727,99 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("samePriorityForFunctionsAndProperties.kt")
|
||||||
public void testSamePriorityForFunctionsAndProperties() throws Exception {
|
public void testSamePriorityForFunctionsAndProperties() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/samePriorityForFunctionsAndProperties.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/samePriorityForFunctionsAndProperties.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("topLevelFromTopLevel.kt")
|
||||||
public void testTopLevelFromTopLevel() throws Exception {
|
public void testTopLevelFromTopLevel() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/topLevelFromTopLevel.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/property/topLevelFromTopLevel.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("compiler/testData/diagnostics/tests/cast")
|
||||||
|
|||||||
+12
@@ -561,6 +561,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
doTestWithStdlib(fileName);
|
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")
|
@TestMetadata("privateClassMember.kt")
|
||||||
public void testPrivateClassMember() throws Exception {
|
public void testPrivateClassMember() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/privateClassMember.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/privateClassMember.kt");
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
|
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<PackageFragmentDescriptor>())
|
val containingPackage = DescriptorUtils.getParentOfType(descriptor, javaClass<PackageFragmentDescriptor>())
|
||||||
return containingPackage != null && containingPackage.fqName == KOTLIN_REFLECT_FQ_NAME
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.AdditionalTypeChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
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.context.ContextDependency
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
|
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
|
||||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||||
@@ -165,7 +165,7 @@ public class ShadowedDeclarationsFilter(
|
|||||||
|
|
||||||
val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression)
|
val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression)
|
||||||
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo,
|
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)
|
CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false)
|
||||||
val callResolver = createContainerForMacros(project, moduleDescriptor).callResolver
|
val callResolver = createContainerForMacros(project, moduleDescriptor).callResolver
|
||||||
val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context)
|
val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context)
|
||||||
|
|||||||
@@ -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.AdditionalTypeChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
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.context.ContextDependency
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
||||||
@@ -155,7 +155,7 @@ class ExpectedInfos(
|
|||||||
val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression)
|
val dataFlowInfo = bindingContext.getDataFlowInfo(calleeExpression)
|
||||||
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion")
|
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace for completion")
|
||||||
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, truncatedCall, expectedType, dataFlowInfo,
|
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)
|
CompositeChecker(listOf()), SymbolUsageValidator.Empty, AdditionalTypeChecker.Composite(listOf()), false)
|
||||||
val callResolutionContext = context.replaceCollectAllCandidates(true)
|
val callResolutionContext = context.replaceCollectAllCandidates(true)
|
||||||
val callResolver = createContainerForMacros(
|
val callResolver = createContainerForMacros(
|
||||||
|
|||||||
Reference in New Issue
Block a user