Use concrete candidate to resolve collection literal

This helps to avoid resolution errors when there is local array-like function with the same signature as in built-ins
This commit is contained in:
Mikhail Zarechenskiy
2017-03-22 17:52:51 +03:00
parent 222f101d10
commit 2a93dea0c4
6 changed files with 78 additions and 10 deletions
@@ -21,8 +21,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED_FEATURE
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtClass
@@ -54,6 +56,7 @@ object CollectionLiteralResolver {
fun resolveCollectionLiteral(collectionLiteralExpression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
callResolver: CallResolver,
builtIns: KotlinBuiltIns,
languageVersionSettings: LanguageVersionSettings
): KotlinTypeInfo {
if (!isInsideAnnotationEntryOrClass(collectionLiteralExpression)) {
@@ -62,28 +65,39 @@ object CollectionLiteralResolver {
checkSupportsArrayLiterals(collectionLiteralExpression, context, languageVersionSettings)
return resolveCollectionLiteralSpecialMethod(collectionLiteralExpression, context, callResolver)
return resolveCollectionLiteralSpecialMethod(collectionLiteralExpression, context, callResolver, builtIns)
}
private fun resolveCollectionLiteralSpecialMethod(
collectionLiteralExpression: KtCollectionLiteralExpression,
expression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
callResolver: CallResolver
callResolver: CallResolver,
builtIns: KotlinBuiltIns
): KotlinTypeInfo {
val collectionLiteralCallName = getArrayFunctionCallName(context.expectedType)
val call = CallMaker.makeCallForCollectionLiteral(collectionLiteralExpression)
val resolutionResults = callResolver.resolveCallWithGivenName(context, call, collectionLiteralExpression, collectionLiteralCallName)
val call = CallMaker.makeCallForCollectionLiteral(expression)
val functionDescriptor = getFunctionDescriptorForCollectionLiteral(expression, context, builtIns)
// TODO: check that resolved function is from package `kotlin`, otherwise report an error
val resolutionResults = callResolver.resolveCollectionLiteralCallWithGivenDescriptor(context, expression, call, functionDescriptor)
// No single result after resolving one candidate?
if (!resolutionResults.isSingleResult) {
return noTypeInfo(context)
}
context.trace.record(COLLECTION_LITERAL_CALL, collectionLiteralExpression, resolutionResults.resultingCall)
context.trace.record(COLLECTION_LITERAL_CALL, expression, resolutionResults.resultingCall)
return createTypeInfo(resolutionResults.resultingDescriptor.returnType, context)
}
fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression,
private fun getFunctionDescriptorForCollectionLiteral(
expression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
builtIns: KotlinBuiltIns
): SimpleFunctionDescriptor {
val callName = getArrayFunctionCallName(context.expectedType)
return builtIns.builtInsPackageScope.getContributedFunctions(callName, KotlinLookupLocation(expression)).single()
}
private fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
languageVersionSettings: LanguageVersionSettings
) {
@@ -234,6 +234,21 @@ public class CallResolver {
);
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCollectionLiteralCallWithGivenDescriptor(
@NotNull ExpressionTypingContext context,
@NotNull KtCollectionLiteralExpression expression,
@NotNull Call call,
@NotNull FunctionDescriptor functionDescriptor
) {
BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
ResolutionCandidate<FunctionDescriptor> candidate = ResolutionCandidate.create(
call, functionDescriptor, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
return computeTasksFromCandidatesAndResolvedCall(
callResolutionContext, Collections.singleton(candidate), TracingStrategyImpl.create(expression, call));
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(
@NotNull BindingTrace trace,
@@ -1505,7 +1505,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull KtCollectionLiteralExpression expression, ExpressionTypingContext context
) {
return CollectionLiteralResolver.INSTANCE.resolveCollectionLiteral(
expression, context, components.callResolver, components.languageVersionSettings);
expression, context, components.callResolver, components.builtIns, components.languageVersionSettings);
}
@Override