diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index ee270970805..6e5e24d745c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -483,8 +483,7 @@ public class CallResolver { } @NotNull - private - Pair>, BasicCallResolutionContext> prepareCandidatesAndContextForConstructorCall( + private static Pair>, BasicCallResolutionContext> prepareCandidatesAndContextForConstructorCall( @NotNull KotlinType superType, @NotNull BasicCallResolutionContext context ) { @@ -506,8 +505,7 @@ public class CallResolver { } Collection> candidates = - taskPrioritizer.convertWithImpliedThisAndNoReceiver( - context.scope, superClass.getConstructors(), context.call, knownTypeParametersSubstitutor); + CallResolverUtilKt.createResolutionCandidatesForConstructors(context.scope, context.call, superClass, knownTypeParametersSubstitutor); return new Pair>, BasicCallResolutionContext>(candidates, context); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt index b65a6e21546..ec1525f0e00 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -19,20 +19,23 @@ package org.jetbrains.kotlin.resolve.calls.callResolverUtil import com.google.common.collect.Lists import com.intellij.util.containers.ContainerUtil import org.jetbrains.kotlin.builtins.ReflectionTypes -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind +import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate +import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy import org.jetbrains.kotlin.resolve.validation.InfixValidator import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE +import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.util.OperatorNameConventions enum class ResolveArgumentsMode { @@ -163,3 +166,35 @@ fun getEffectiveExpectedType(parameterDescriptor: ValueParameterDescriptor, argu return parameterDescriptor.type } + +fun createResolutionCandidatesForConstructors( + lexicalScope: LexicalScope, + call: Call, + classWithConstructors: ClassDescriptor, + knownSubstitutor: TypeSubstitutor? = null +): Collection> { + val constructors = classWithConstructors.constructors + + if (constructors.isEmpty()) return emptyList() + + val receiverKind: ExplicitReceiverKind + val dispatchReceiver: ReceiverValue? + + if (classWithConstructors.isInner) { + val outerClassType = (classWithConstructors.containingDeclaration as? ClassDescriptor)?.defaultType ?: return emptyList() + val substitutedOuterClassType = knownSubstitutor?.let { it.substitute(outerClassType, Variance.INVARIANT) } ?: outerClassType + + val receiver = lexicalScope.getImplicitReceiversHierarchy().firstOrNull { + KotlinTypeChecker.DEFAULT.isSubtypeOf(it.type, substitutedOuterClassType) + } ?: return emptyList() + + receiverKind = ExplicitReceiverKind.DISPATCH_RECEIVER + dispatchReceiver = receiver.value + } + else { + receiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + dispatchReceiver = null + } + + return constructors.map { ResolutionCandidate.create(call, it, dispatchReceiver, null, receiverKind, knownSubstitutor) } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt index 22c79c2b926..14ceca341c8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -425,7 +425,7 @@ class TaskPrioritizer( } } - fun convertWithImpliedThisAndNoReceiver( + private fun convertWithImpliedThisAndNoReceiver( scope: LexicalScope, descriptors: Collection, call: Call, @@ -434,7 +434,7 @@ class TaskPrioritizer( return convertWithImpliedThis(scope, null, descriptors, NO_EXPLICIT_RECEIVER, call, knownSubstitutor) } - fun convertWithImpliedThis( + private fun convertWithImpliedThis( scope: LexicalScope, receiverValue: ReceiverValue?, descriptors: Collection, diff --git a/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingPrimary.txt b/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingPrimary.txt index 6c6c2045e38..82d4ee1d30d 100644 --- a/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingPrimary.txt +++ b/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingPrimary.txt @@ -10,7 +10,7 @@ Resolved call: Resulting descriptor: constructor B(arg: String) defined in A.B -Explicit receiver kind = NO_EXPLICIT_RECEIVER +Explicit receiver kind = DISPATCH_RECEIVER Dispatch receiver = Class{A} Extension receiver = NO_RECEIVER diff --git a/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingSecondary.txt b/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingSecondary.txt index 96be52748d7..a482ca812d1 100644 --- a/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingSecondary.txt +++ b/compiler/testData/resolveConstructorDelegationCalls/innerClassDelegatingSecondary.txt @@ -11,7 +11,7 @@ Resolved call: Resulting descriptor: constructor B(x: String) defined in A.B -Explicit receiver kind = NO_EXPLICIT_RECEIVER +Explicit receiver kind = DISPATCH_RECEIVER Dispatch receiver = Class{A} Extension receiver = NO_RECEIVER