Use the new type inference for top-level callable reference resolution
^KT-47797 Fixed ^KT-47987 Fixed ^KT-45034 Fixed ^KT-48446 Fixed ^KT-13934 Fixed
This commit is contained in:
-6
@@ -2813,12 +2813,6 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestMetadata("referenceAdaptationHasDependencyOnApi14.kt")
|
|
||||||
public void testReferenceAdaptationHasDependencyOnApi14() throws Exception {
|
|
||||||
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationHasDependencyOnApi14.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("referenceToCompanionObjectMemberViaClassName.kt")
|
@TestMetadata("referenceToCompanionObjectMemberViaClassName.kt")
|
||||||
public void testReferenceToCompanionObjectMemberViaClassName() throws Exception {
|
public void testReferenceToCompanionObjectMemberViaClassName() throws Exception {
|
||||||
|
|||||||
-6
@@ -2813,12 +2813,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestMetadata("referenceAdaptationHasDependencyOnApi14.kt")
|
|
||||||
public void testReferenceAdaptationHasDependencyOnApi14() throws Exception {
|
|
||||||
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationHasDependencyOnApi14.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("referenceToCompanionObjectMemberViaClassName.kt")
|
@TestMetadata("referenceToCompanionObjectMemberViaClassName.kt")
|
||||||
public void testReferenceToCompanionObjectMemberViaClassName() throws Exception {
|
public void testReferenceToCompanionObjectMemberViaClassName() throws Exception {
|
||||||
|
|||||||
-6
@@ -2813,12 +2813,6 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationCompatibility.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestMetadata("referenceAdaptationHasDependencyOnApi14.kt")
|
|
||||||
public void testReferenceAdaptationHasDependencyOnApi14() throws Exception {
|
|
||||||
runTest("compiler/testData/diagnostics/tests/callableReference/referenceAdaptationHasDependencyOnApi14.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("referenceToCompanionObjectMemberViaClassName.kt")
|
@TestMetadata("referenceToCompanionObjectMemberViaClassName.kt")
|
||||||
public void testReferenceToCompanionObjectMemberViaClassName() throws Exception {
|
public void testReferenceToCompanionObjectMemberViaClassName() throws Exception {
|
||||||
|
|||||||
+9
-2
@@ -20,16 +20,23 @@ import com.intellij.psi.PsiElement
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.CALLABLE_REFERENCE_TO_JAVA_SYNTHETIC_PROPERTY
|
import org.jetbrains.kotlin.diagnostics.Errors.CALLABLE_REFERENCE_TO_JAVA_SYNTHETIC_PROPERTY
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
|
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.isCallableReference
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.unwrapParenthesesLabelsAndAnnotationsDeeply
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.extractCallableReferenceExpression
|
||||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||||
|
|
||||||
class UnsupportedSyntheticCallableReferenceChecker : CallChecker {
|
class UnsupportedSyntheticCallableReferenceChecker : CallChecker {
|
||||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||||
// TODO: support references to synthetic Java extension properties (KT-8575)
|
// TODO: support references to synthetic Java extension properties (KT-8575)
|
||||||
if (resolvedCall.call.isCallableReference() && resolvedCall.resultingDescriptor is SyntheticJavaPropertyDescriptor) {
|
val callableReferenceExpression = resolvedCall.call.extractCallableReferenceExpression() ?: return
|
||||||
|
|
||||||
|
// We allow resolve of top-level callable reference to synthetic Java extension properties in delegate position
|
||||||
|
if (callableReferenceExpression.unwrapParenthesesLabelsAndAnnotationsDeeply() is KtPropertyDelegate) return
|
||||||
|
|
||||||
|
if (resolvedCall.resultingDescriptor is SyntheticJavaPropertyDescriptor) {
|
||||||
val diagnostic = if (
|
val diagnostic = if (
|
||||||
context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) &&
|
context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) &&
|
||||||
context.languageVersionSettings.supportsFeature(LanguageFeature.ReferencesToSyntheticJavaProperties)
|
context.languageVersionSettings.supportsFeature(LanguageFeature.ReferencesToSyntheticJavaProperties)
|
||||||
|
|||||||
+32
-10
@@ -156,16 +156,16 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
MixingNamedAndPositionArguments::class.java ->
|
MixingNamedAndPositionArguments::class.java ->
|
||||||
trace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(callArgument.psiCallArgument.valueArgument.asElement()))
|
trace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(callArgument.psiCallArgument.valueArgument.asElement()))
|
||||||
|
|
||||||
NoneCallableReferenceCandidates::class.java -> {
|
NoneCallableReferenceCallCandidates::class.java -> {
|
||||||
val expression = diagnostic.cast<NoneCallableReferenceCandidates>()
|
val expression = diagnostic.cast<NoneCallableReferenceCallCandidates>()
|
||||||
.argument.safeAs<CallableReferenceKotlinCallArgumentImpl>()?.ktCallableReferenceExpression
|
.argument.safeAs<CallableReferenceKotlinCallArgumentImpl>()?.ktCallableReferenceExpression
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
trace.report(UNRESOLVED_REFERENCE.on(expression.callableReference, expression.callableReference))
|
trace.report(UNRESOLVED_REFERENCE.on(expression.callableReference, expression.callableReference))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableReferenceCandidatesAmbiguity::class.java -> {
|
CallableReferenceCallCandidatesAmbiguity::class.java -> {
|
||||||
val ambiguityDiagnostic = diagnostic as CallableReferenceCandidatesAmbiguity
|
val ambiguityDiagnostic = diagnostic as CallableReferenceCallCandidatesAmbiguity
|
||||||
val expression = when (val psiExpression = ambiguityDiagnostic.argument.psiExpression) {
|
val expression = when (val psiExpression = ambiguityDiagnostic.argument.psiExpression) {
|
||||||
is KtPsiUtil.KtExpressionWrapper -> psiExpression.baseExpression
|
is KtPsiUtil.KtExpressionWrapper -> psiExpression.baseExpression
|
||||||
else -> psiExpression
|
else -> psiExpression
|
||||||
@@ -197,14 +197,18 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
"diagnostic ($diagnostic) should have type CallableReferencesDefaultArgumentUsed"
|
"diagnostic ($diagnostic) should have type CallableReferencesDefaultArgumentUsed"
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostic.argument.psiExpression?.let {
|
val callableReferenceExpression = diagnostic.argument.call.extractCallableReferenceExpression()
|
||||||
trace.report(
|
|
||||||
UNSUPPORTED_FEATURE.on(
|
require(callableReferenceExpression != null) {
|
||||||
it, LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType to context.languageVersionSettings
|
"A call element must be callable reference for `CallableReferencesDefaultArgumentUsed`"
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace.report(
|
||||||
|
UNSUPPORTED_FEATURE.on(
|
||||||
|
callableReferenceExpression,
|
||||||
|
LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType to context.languageVersionSettings
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolvedToSamWithVarargDiagnostic::class.java -> {
|
ResolvedToSamWithVarargDiagnostic::class.java -> {
|
||||||
@@ -342,7 +346,25 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun reportCallableReferenceConstraintError(
|
||||||
|
error: NewConstraintMismatch,
|
||||||
|
rhsExpression: KtSimpleNameExpression
|
||||||
|
) {
|
||||||
|
trace.report(TYPE_MISMATCH.on(rhsExpression, error.lowerKotlinType, error.upperKotlinType))
|
||||||
|
}
|
||||||
|
|
||||||
private fun reportConstraintErrorByPosition(error: NewConstraintMismatch, position: ConstraintPosition) {
|
private fun reportConstraintErrorByPosition(error: NewConstraintMismatch, position: ConstraintPosition) {
|
||||||
|
if (position is CallableReferenceConstraintPositionImpl) {
|
||||||
|
val callableReferenceExpression = position.callableReferenceCall.call.extractCallableReferenceExpression()
|
||||||
|
|
||||||
|
require(callableReferenceExpression != null) {
|
||||||
|
"There should be the corresponding callable reference expression for `CallableReferenceConstraintPositionImpl`"
|
||||||
|
}
|
||||||
|
|
||||||
|
reportCallableReferenceConstraintError(error, callableReferenceExpression.callableReference)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val argument =
|
val argument =
|
||||||
when (position) {
|
when (position) {
|
||||||
is ArgumentConstraintPositionImpl -> position.argument
|
is ArgumentConstraintPositionImpl -> position.argument
|
||||||
|
|||||||
+30
-9
@@ -20,15 +20,21 @@ import org.jetbrains.kotlin.psi.psiUtil.getBinaryWithTypeParent
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.extractCallableReferenceExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.SimpleResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
|
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
@@ -71,7 +77,8 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
private val deprecationResolver: DeprecationResolver,
|
private val deprecationResolver: DeprecationResolver,
|
||||||
private val moduleDescriptor: ModuleDescriptor,
|
private val moduleDescriptor: ModuleDescriptor,
|
||||||
private val topLevelCallContext: BasicCallResolutionContext,
|
private val topLevelCallContext: BasicCallResolutionContext,
|
||||||
private val missingSupertypesResolver: MissingSupertypesResolver
|
private val missingSupertypesResolver: MissingSupertypesResolver,
|
||||||
|
private val kotlinCallResolver: KotlinCallResolver,
|
||||||
) : KotlinResolutionCallbacks {
|
) : KotlinResolutionCallbacks {
|
||||||
class LambdaInfo(val expectedType: UnwrappedType, val contextDependency: ContextDependency) {
|
class LambdaInfo(val expectedType: UnwrappedType, val contextDependency: ContextDependency) {
|
||||||
val returnStatements = ArrayList<Pair<KtReturnExpression, LambdaContextInfo?>>()
|
val returnStatements = ArrayList<Pair<KtReturnExpression, LambdaContextInfo?>>()
|
||||||
@@ -82,6 +89,19 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun resolveCallableReferenceArgument(
|
||||||
|
argument: CallableReferenceKotlinCallArgument,
|
||||||
|
expectedType: UnwrappedType?,
|
||||||
|
baseSystem: ConstraintStorage,
|
||||||
|
): Collection<CallableReferenceResolutionCandidate> =
|
||||||
|
kotlinCallResolver.resolveCallableReferenceArgument(argument, expectedType, baseSystem, this)
|
||||||
|
|
||||||
|
override fun getCandidateFactoryForInvoke(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
kotlinCall: KotlinCall
|
||||||
|
): PSICallResolver.FactoryProviderForInvoke =
|
||||||
|
psiCallResolver.FactoryProviderForInvoke(topLevelCallContext, scopeTower, kotlinCall as PSIKotlinCallImpl)
|
||||||
|
|
||||||
override fun analyzeAndGetLambdaReturnArguments(
|
override fun analyzeAndGetLambdaReturnArguments(
|
||||||
lambdaArgument: LambdaKotlinCallArgument,
|
lambdaArgument: LambdaKotlinCallArgument,
|
||||||
isSuspend: Boolean,
|
isSuspend: Boolean,
|
||||||
@@ -113,21 +133,22 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val deparenthesizedExpression = KtPsiUtil.deparenthesize(ktExpression) ?: ktExpression
|
val deparenthesizedExpression = KtPsiUtil.deparenthesize(ktExpression) ?: ktExpression
|
||||||
if (deparenthesizedExpression is KtCallableReferenceExpression) {
|
|
||||||
return psiCallResolver.createCallableReferenceKotlinCallArgument(
|
return if (deparenthesizedExpression is KtCallableReferenceExpression) {
|
||||||
|
psiCallResolver.createCallableReferenceKotlinCallArgument(
|
||||||
newContext, deparenthesizedExpression, DataFlowInfo.EMPTY,
|
newContext, deparenthesizedExpression, DataFlowInfo.EMPTY,
|
||||||
CallMaker.makeExternalValueArgument(deparenthesizedExpression),
|
CallMaker.makeExternalValueArgument(deparenthesizedExpression),
|
||||||
argumentName = null,
|
argumentName = null,
|
||||||
outerCallContext,
|
outerCallContext,
|
||||||
tracingStrategy = TracingStrategyImpl.create(deparenthesizedExpression.callableReference, newContext.call)
|
tracingStrategy = TracingStrategyImpl.create(deparenthesizedExpression.callableReference, newContext.call)
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
createSimplePSICallArgument(
|
||||||
|
trace.bindingContext, outerCallContext.statementFilter, outerCallContext.scope.ownerDescriptor,
|
||||||
|
CallMaker.makeExternalValueArgument(ktExpression), DataFlowInfo.EMPTY, typeInfo, languageVersionSettings,
|
||||||
|
dataFlowValueFactory, outerCallContext.call
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return createSimplePSICallArgument(
|
|
||||||
trace.bindingContext, outerCallContext.statementFilter, outerCallContext.scope.ownerDescriptor,
|
|
||||||
CallMaker.makeExternalValueArgument(ktExpression), DataFlowInfo.EMPTY, typeInfo, languageVersionSettings,
|
|
||||||
dataFlowValueFactory, outerCallContext.call
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val lambdaInfo = LambdaInfo(
|
val lambdaInfo = LambdaInfo(
|
||||||
|
|||||||
+6
-3
@@ -213,7 +213,10 @@ class KotlinToResolvedCallTransformer(
|
|||||||
|
|
||||||
return if (completedSimpleAtom.atom.callKind == KotlinCallKind.CALLABLE_REFERENCE) {
|
return if (completedSimpleAtom.atom.callKind == KotlinCallKind.CALLABLE_REFERENCE) {
|
||||||
NewCallableReferenceResolvedCall(
|
NewCallableReferenceResolvedCall(
|
||||||
completedSimpleAtom as ResolvedCallableReferenceCallAtom, typeApproximator, resultSubstitutor
|
completedSimpleAtom as ResolvedCallableReferenceCallAtom,
|
||||||
|
typeApproximator,
|
||||||
|
expressionTypingServices.languageVersionSettings,
|
||||||
|
resultSubstitutor
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
NewResolvedCallImpl(
|
NewResolvedCallImpl(
|
||||||
@@ -384,7 +387,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getResolvedCallForArgumentExpression(expression: KtExpression, context: BasicCallResolutionContext) =
|
fun getResolvedCallForArgumentExpression(expression: KtExpression, context: BasicCallResolutionContext) =
|
||||||
if (!ExpressionTypingUtils.dependsOnExpectedType(expression))
|
if (!ExpressionTypingUtils.dependsOnExpectedType(expression))
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
@@ -486,7 +489,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
|
|
||||||
outerTracingStrategy.bindReference(trace, variableCall)
|
outerTracingStrategy.bindReference(trace, variableCall)
|
||||||
outerTracingStrategy.bindResolvedCall(trace, variableAsFunction)
|
outerTracingStrategy.bindResolvedCall(trace, variableAsFunction)
|
||||||
functionCall.kotlinCall.psiKotlinCall.tracingStrategy.bindReference(trace, functionCall)
|
functionCall.psiKotlinCall.tracingStrategy.bindReference(trace, functionCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportCallDiagnostic(
|
fun reportCallDiagnostic(
|
||||||
|
|||||||
+125
-26
@@ -7,54 +7,68 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.Call
|
||||||
import org.jetbrains.kotlin.psi.ValueArgument
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.isNotSimpleCall
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeApproximator
|
||||||
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
|
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
|
||||||
|
|
||||||
sealed class NewAbstractResolvedCall<D : CallableDescriptor> : ResolvedCall<D> {
|
sealed class NewAbstractResolvedCall<D : CallableDescriptor> : ResolvedCall<D> {
|
||||||
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||||
abstract val kotlinCall: KotlinCall
|
abstract val kotlinCall: KotlinCall?
|
||||||
abstract val languageVersionSettings: LanguageVersionSettings
|
abstract val languageVersionSettings: LanguageVersionSettings
|
||||||
abstract val resolvedCallAtom: ResolvedCallAtom?
|
abstract val resolvedCallAtom: ResolvedCallAtom?
|
||||||
abstract val psiKotlinCall: PSIKotlinCall
|
abstract val psiKotlinCall: PSIKotlinCall
|
||||||
abstract val isCompleted: Boolean
|
abstract val typeApproximator: TypeApproximator
|
||||||
|
abstract val freshSubstitutor: FreshVariableNewTypeSubstitutor?
|
||||||
|
|
||||||
protected var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
|
protected open val positionDependentApproximation = false
|
||||||
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
|
||||||
|
|
||||||
|
private var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
|
||||||
|
private var valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
||||||
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
|
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
|
||||||
|
private var isCompleted: Boolean = false
|
||||||
|
|
||||||
|
abstract fun updateDispatchReceiverType(newType: KotlinType)
|
||||||
|
abstract fun updateExtensionReceiverType(newType: KotlinType)
|
||||||
abstract fun containsOnlyOnlyInputTypesErrors(): Boolean
|
abstract fun containsOnlyOnlyInputTypesErrors(): Boolean
|
||||||
|
abstract fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?)
|
||||||
|
abstract fun argumentToParameterMap(
|
||||||
|
resultingDescriptor: CallableDescriptor,
|
||||||
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
||||||
|
): Map<ValueArgument, ArgumentMatchImpl>
|
||||||
|
|
||||||
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
|
override fun getCall(): Call = psiKotlinCall.psiCall
|
||||||
|
|
||||||
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
|
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
|
||||||
if (_valueArguments == null) {
|
if (valueArguments == null) {
|
||||||
_valueArguments = createValueArguments()
|
valueArguments = createValueArguments()
|
||||||
}
|
}
|
||||||
return _valueArguments!!
|
return valueArguments!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setValueArguments(m: Map<ValueParameterDescriptor, ResolvedValueArgument>) {
|
|
||||||
_valueArguments = m
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {}
|
|
||||||
|
|
||||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
||||||
val arguments = ArrayList<ResolvedValueArgument?>(candidateDescriptor.valueParameters.size)
|
val arguments = ArrayList<ResolvedValueArgument?>(candidateDescriptor.valueParameters.size)
|
||||||
for (i in 0 until candidateDescriptor.valueParameters.size) {
|
for (i in 0 until candidateDescriptor.valueParameters.size) {
|
||||||
arguments.add(null)
|
arguments.add(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((parameterDescriptor, value) in valueArguments) {
|
for ((parameterDescriptor, value) in getValueArguments()) {
|
||||||
val oldValue = arguments.set(parameterDescriptor.index, value)
|
val oldValue = arguments.set(parameterDescriptor.index, value)
|
||||||
if (oldValue != null) {
|
if (oldValue != null) {
|
||||||
return null
|
return null
|
||||||
@@ -69,36 +83,121 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor> : ResolvedCall<D> {
|
|||||||
|
|
||||||
override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping {
|
override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping {
|
||||||
if (argumentToParameterMap == null) {
|
if (argumentToParameterMap == null) {
|
||||||
argumentToParameterMap = argumentToParameterMap(resultingDescriptor, valueArguments)
|
updateArgumentsMapping(argumentToParameterMap(resultingDescriptor, getValueArguments()))
|
||||||
}
|
}
|
||||||
return argumentToParameterMap!![valueArgument] ?: ArgumentUnmapped
|
return argumentToParameterMap!![valueArgument] ?: ArgumentUnmapped
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments {
|
override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments {
|
||||||
override fun getResultInfo(): DataFlowInfo = nonTrivialUpdatedResultInfo ?: kotlinCall.psiKotlinCall.resultDataFlowInfo
|
override fun getResultInfo(): DataFlowInfo = nonTrivialUpdatedResultInfo ?: psiKotlinCall.resultDataFlowInfo
|
||||||
|
|
||||||
override fun getInfo(valueArgument: ValueArgument): DataFlowInfo {
|
override fun getInfo(valueArgument: ValueArgument): DataFlowInfo {
|
||||||
val externalPsiCallArgument = kotlinCall.externalArgument?.psiCallArgument
|
val externalPsiCallArgument = kotlinCall?.externalArgument?.psiCallArgument
|
||||||
if (externalPsiCallArgument?.valueArgument == valueArgument) {
|
if (externalPsiCallArgument?.valueArgument == valueArgument) {
|
||||||
return externalPsiCallArgument.dataFlowInfoAfterThisArgument
|
return externalPsiCallArgument.dataFlowInfoAfterThisArgument
|
||||||
}
|
}
|
||||||
return kotlinCall.psiKotlinCall.dataFlowInfoForArguments.getInfo(valueArgument)
|
return psiKotlinCall.dataFlowInfoForArguments.getInfo(valueArgument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateValueArguments(newValueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>?) {
|
||||||
|
valueArguments = newValueArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
fun substituteReceivers(substitutor: NewTypeSubstitutor?) {
|
||||||
|
if (substitutor != null) {
|
||||||
|
// todo: add asset that we do not complete call many times
|
||||||
|
isCompleted = true
|
||||||
|
|
||||||
|
dispatchReceiver?.type?.let {
|
||||||
|
val newType = substitutor.safeSubstitute(it.unwrap())
|
||||||
|
updateDispatchReceiverType(newType)
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionReceiver?.type?.let {
|
||||||
|
val newType = substitutor.safeSubstitute(it.unwrap())
|
||||||
|
updateExtensionReceiverType(newType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isCompleted() = isCompleted
|
||||||
|
|
||||||
// Currently, updated only with info from effect system
|
// Currently, updated only with info from effect system
|
||||||
internal fun updateResultingDataFlowInfo(dataFlowInfo: DataFlowInfo) {
|
internal fun updateResultingDataFlowInfo(dataFlowInfo: DataFlowInfo) {
|
||||||
if (dataFlowInfo == DataFlowInfo.EMPTY) return
|
if (dataFlowInfo == DataFlowInfo.EMPTY) return
|
||||||
assert(nonTrivialUpdatedResultInfo == null) {
|
assert(nonTrivialUpdatedResultInfo == null) {
|
||||||
"Attempt to rewrite resulting dataFlowInfo enhancement for call: $kotlinCall"
|
"Attempt to rewrite resulting dataFlowInfo enhancement for call: $kotlinCall"
|
||||||
}
|
}
|
||||||
nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo)
|
nonTrivialUpdatedResultInfo = dataFlowInfo.and(psiKotlinCall.resultDataFlowInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun argumentToParameterMap(
|
protected fun updateArgumentsMapping(newMapping: Map<ValueArgument, ArgumentMatchImpl>?) {
|
||||||
resultingDescriptor: CallableDescriptor,
|
argumentToParameterMap = newMapping
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
}
|
||||||
): Map<ValueArgument, ArgumentMatchImpl>
|
|
||||||
|
protected fun substitutedResultingDescriptor(substitutor: NewTypeSubstitutor?) =
|
||||||
|
when (val candidateDescriptor = candidateDescriptor) {
|
||||||
|
is ClassConstructorDescriptor, is SyntheticMemberDescriptor<*> -> {
|
||||||
|
val explicitTypeArguments = resolvedCallAtom?.atom?.typeArguments?.filterIsInstance<SimpleTypeArgument>() ?: emptyList()
|
||||||
|
|
||||||
|
candidateDescriptor.substituteInferredVariablesAndApproximate(
|
||||||
|
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is FunctionDescriptor -> {
|
||||||
|
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor, candidateDescriptor.isNotSimpleCall())
|
||||||
|
}
|
||||||
|
is PropertyDescriptor -> {
|
||||||
|
if (candidateDescriptor.isNotSimpleCall()) {
|
||||||
|
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
||||||
|
} else {
|
||||||
|
candidateDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> candidateDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CallableDescriptor.substituteInferredVariablesAndApproximate(
|
||||||
|
substitutor: NewTypeSubstitutor?,
|
||||||
|
shouldApproximate: Boolean = true
|
||||||
|
): CallableDescriptor {
|
||||||
|
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||||
|
|
||||||
|
val freshVariablesSubstituted = freshSubstitutor?.let(::substitute) ?: this
|
||||||
|
val knownTypeParameterSubstituted = resolvedCallAtom?.knownParametersSubstitutor?.let(freshVariablesSubstituted::substitute)
|
||||||
|
?: freshVariablesSubstituted
|
||||||
|
|
||||||
|
return knownTypeParameterSubstituted.substituteAndApproximateTypes(
|
||||||
|
inferredTypeVariablesSubstitutor,
|
||||||
|
typeApproximator = if (shouldApproximate) typeApproximator else null,
|
||||||
|
positionDependentApproximation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSubstitutorWithoutFlexibleTypes(
|
||||||
|
currentSubstitutor: NewTypeSubstitutor?,
|
||||||
|
explicitTypeArguments: List<SimpleTypeArgument>,
|
||||||
|
): NewTypeSubstitutor? {
|
||||||
|
if (currentSubstitutor !is NewTypeSubstitutorByConstructorMap || explicitTypeArguments.isEmpty()) return currentSubstitutor
|
||||||
|
if (!currentSubstitutor.map.any { (_, value) -> value.isFlexible() }) return currentSubstitutor
|
||||||
|
|
||||||
|
val typeVariables = freshSubstitutor?.freshVariables ?: return null
|
||||||
|
val newSubstitutorMap = currentSubstitutor.map.toMutableMap()
|
||||||
|
|
||||||
|
explicitTypeArguments.forEachIndexed { index, typeArgument ->
|
||||||
|
val typeVariableConstructor = typeVariables.getOrNull(index)?.freshTypeConstructor ?: return@forEachIndexed
|
||||||
|
|
||||||
|
newSubstitutorMap[typeVariableConstructor] =
|
||||||
|
newSubstitutorMap[typeVariableConstructor]?.withNullabilityFromExplicitTypeArgument(typeArgument)
|
||||||
|
?: return@forEachIndexed
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewTypeSubstitutorByConstructorMap(newSubstitutorMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinType.withNullabilityFromExplicitTypeArgument(typeArgument: SimpleTypeArgument) =
|
||||||
|
(if (typeArgument.type.isMarkedNullable) makeNullable() else makeNotNullable()).unwrap()
|
||||||
|
|
||||||
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
|
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
|
||||||
LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>().also { result ->
|
LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>().also { result ->
|
||||||
|
|||||||
@@ -325,7 +325,10 @@ internal fun createSimplePSICallArgument(
|
|||||||
call: Call
|
call: Call
|
||||||
): SimplePSIKotlinCallArgument? {
|
): SimplePSIKotlinCallArgument? {
|
||||||
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null
|
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null
|
||||||
val partiallyResolvedCall = ktExpression.getCall(bindingContext)?.let {
|
val ktExpressionToExtractResolvedCall =
|
||||||
|
if (ktExpression is KtCallableReferenceExpression) ktExpression.callableReference else ktExpression
|
||||||
|
|
||||||
|
val partiallyResolvedCall = ktExpressionToExtractResolvedCall.getCall(bindingContext)?.let {
|
||||||
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
||||||
}
|
}
|
||||||
// todo hack for if expression: sometimes we not write properly type information for branches
|
// todo hack for if expression: sometimes we not write properly type information for branches
|
||||||
|
|||||||
+59
-185
@@ -7,61 +7,53 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.ValueArgument
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.isNotSimpleCall
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.toResolutionStatus
|
import org.jetbrains.kotlin.resolve.calls.util.toResolutionStatus
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
|
||||||
|
|
||||||
class NewCallableReferenceResolvedCall<D : CallableDescriptor>(
|
class NewCallableReferenceResolvedCall<D : CallableDescriptor>(
|
||||||
val resolvedAtom: ResolvedCallableReferenceAtom,
|
val resolvedAtom: ResolvedCallableReferenceAtom,
|
||||||
val typeApproximator: TypeApproximator,
|
override val typeApproximator: TypeApproximator,
|
||||||
substitutor: NewTypeSubstitutor?,
|
override val languageVersionSettings: LanguageVersionSettings,
|
||||||
|
substitutor: NewTypeSubstitutor? = null,
|
||||||
) : NewAbstractResolvedCall<D>() {
|
) : NewAbstractResolvedCall<D>() {
|
||||||
override var isCompleted = false
|
override val positionDependentApproximation: Boolean = true
|
||||||
private set
|
override val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument> = emptyMap()
|
||||||
|
|
||||||
override val resolvedCallAtom: MutableResolvedCallAtom? = when (resolvedAtom) {
|
override val resolvedCallAtom: ResolvedCallableReferenceCallAtom?
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom
|
get() = when (resolvedAtom) {
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.resolvedCall
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom
|
||||||
}
|
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.resolvedCall
|
||||||
|
}
|
||||||
|
|
||||||
override val psiKotlinCall: PSIKotlinCall = when (resolvedAtom) {
|
override val psiKotlinCall: PSIKotlinCall =
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.atom.psiKotlinCall
|
when (resolvedAtom) {
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.atom.call.psiKotlinCall
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom.atom.psiKotlinCall
|
||||||
}
|
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.atom.call.psiKotlinCall
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
override val freshSubstitutor: FreshVariableNewTypeSubstitutor?
|
||||||
setResultingSubstitutor(substitutor)
|
get() = when (resolvedAtom) {
|
||||||
}
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
||||||
|
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.freshVariablesSubstitutor
|
||||||
|
}
|
||||||
|
|
||||||
|
override val kotlinCall: KotlinCall?
|
||||||
|
get() = when (resolvedAtom) {
|
||||||
|
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.kotlinCall?.call
|
||||||
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom.atom
|
||||||
|
}
|
||||||
|
|
||||||
var diagnostics: Collection<KotlinCallDiagnostic> = mutableListOf()
|
|
||||||
private lateinit var resultingDescriptor: D
|
private lateinit var resultingDescriptor: D
|
||||||
|
private lateinit var typeArguments: List<UnwrappedType>
|
||||||
|
|
||||||
override fun getStatus(): ResolutionStatus {
|
private var extensionReceiver: ReceiverValue? = when (resolvedAtom) {
|
||||||
return getResultApplicability(diagnostics).toResolutionStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCandidateDescriptor(): D = when (resolvedAtom) {
|
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.candidateDescriptor as D
|
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.candidate as D
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getResultingDescriptor(): D = resultingDescriptor
|
|
||||||
|
|
||||||
private var extensionReceiver = when (resolvedAtom) {
|
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.extensionReceiverArgument?.receiverValue
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom.extensionReceiverArgument?.receiverValue
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.extensionReceiver?.receiver?.receiverValue
|
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.extensionReceiver?.receiver?.receiverValue
|
||||||
}
|
}
|
||||||
@@ -72,35 +64,25 @@ class NewCallableReferenceResolvedCall<D : CallableDescriptor>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getExtensionReceiver(): ReceiverValue? = extensionReceiver
|
override fun getExtensionReceiver(): ReceiverValue? = extensionReceiver
|
||||||
|
|
||||||
override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
|
override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
|
||||||
|
|
||||||
override fun getExplicitReceiverKind(): ExplicitReceiverKind = when (resolvedAtom) {
|
override fun updateDispatchReceiverType(newType: KotlinType) {
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.explicitReceiverKind
|
if (dispatchReceiver?.type == newType) return
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.explicitReceiverKind
|
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> = _valueArguments ?: emptyMap()
|
override fun updateExtensionReceiverType(newType: KotlinType) {
|
||||||
|
if (extensionReceiver?.type == newType) return
|
||||||
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
|
extensionReceiver = extensionReceiver?.replaceType(newType)
|
||||||
val arguments = ArrayList<ResolvedValueArgument?>(candidateDescriptor.valueParameters.size)
|
|
||||||
for (i in 0 until candidateDescriptor.valueParameters.size) {
|
|
||||||
arguments.add(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
for ((parameterDescriptor, value) in valueArguments) {
|
|
||||||
val oldValue = arguments.set(parameterDescriptor.index, value)
|
|
||||||
if (oldValue != null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.any { it == null }) return null
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return arguments as List<ResolvedValueArgument>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun getCandidateDescriptor(): D = when (resolvedAtom) {
|
||||||
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom.candidateDescriptor as D
|
||||||
|
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate?.candidate as D
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getResultingDescriptor(): D = resultingDescriptor
|
||||||
override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping = ArgumentUnmapped
|
override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping = ArgumentUnmapped
|
||||||
|
|
||||||
override fun getTypeArguments(): Map<TypeParameterDescriptor, KotlinType> {
|
override fun getTypeArguments(): Map<TypeParameterDescriptor, KotlinType> {
|
||||||
@@ -108,150 +90,42 @@ class NewCallableReferenceResolvedCall<D : CallableDescriptor>(
|
|||||||
return typeParameters.zip(typeArguments).toMap()
|
return typeParameters.zip(typeArguments).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var typeArguments: List<UnwrappedType>
|
override fun getStatus() = CandidateApplicability.RESOLVED.toResolutionStatus()
|
||||||
|
|
||||||
|
override fun getExplicitReceiverKind() = when (resolvedAtom) {
|
||||||
|
is ResolvedCallableReferenceArgumentAtom ->
|
||||||
|
resolvedAtom.candidate?.explicitReceiverKind ?: ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||||
|
is ResolvedCallableReferenceCallAtom -> resolvedAtom.explicitReceiverKind
|
||||||
|
}
|
||||||
|
|
||||||
override fun getDataFlowInfoForArguments(): DataFlowInfoForArguments =
|
override fun getDataFlowInfoForArguments(): DataFlowInfoForArguments =
|
||||||
MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
||||||
|
|
||||||
override fun getSmartCastDispatchReceiverType(): KotlinType? = null
|
override fun getSmartCastDispatchReceiverType(): KotlinType? = null
|
||||||
|
|
||||||
|
|
||||||
private fun updateDispatchReceiverType(newType: KotlinType) {
|
|
||||||
if (dispatchReceiver?.type == newType) return
|
|
||||||
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateExtensionReceiverType(newType: KotlinType) {
|
|
||||||
if (extensionReceiver?.type == newType) return
|
|
||||||
extensionReceiver = extensionReceiver?.replaceType(newType)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||||
//clear cached values
|
substituteReceivers(substitutor)
|
||||||
if (substitutor != null) {
|
|
||||||
isCompleted = true
|
|
||||||
dispatchReceiver?.type?.let {
|
|
||||||
val newType = substitutor.safeSubstitute(it.unwrap())
|
|
||||||
updateDispatchReceiverType(newType)
|
|
||||||
}
|
|
||||||
|
|
||||||
extensionReceiver?.type?.let {
|
|
||||||
val newType = substitutor.safeSubstitute(it.unwrap())
|
|
||||||
updateExtensionReceiverType(newType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
resultingDescriptor = substitutedResultingDescriptor(substitutor) as D
|
resultingDescriptor = substitutedResultingDescriptor(substitutor) as D
|
||||||
|
|
||||||
val sub = when (resolvedAtom) {
|
freshSubstitutor?.let { freshSubstitutor ->
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
typeArguments = freshSubstitutor.freshVariables.map {
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.freshVariablesSubstitutor!!
|
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
||||||
}
|
typeApproximator.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
||||||
|
?: substituted
|
||||||
typeArguments = sub.freshVariables.map {
|
|
||||||
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
|
||||||
typeApproximator
|
|
||||||
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
|
||||||
?: substituted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSubstitutorWithoutFlexibleTypes(
|
|
||||||
currentSubstitutor: NewTypeSubstitutor?,
|
|
||||||
explicitTypeArguments: List<SimpleTypeArgument>,
|
|
||||||
): NewTypeSubstitutor? {
|
|
||||||
if (currentSubstitutor !is NewTypeSubstitutorByConstructorMap || explicitTypeArguments.isEmpty()) return currentSubstitutor
|
|
||||||
if (!currentSubstitutor.map.any { (_, value) -> value.isFlexible() }) return currentSubstitutor
|
|
||||||
|
|
||||||
val sub = when (resolvedAtom) {
|
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.freshVariablesSubstitutor!!
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeVariables = sub.freshVariables
|
|
||||||
val newSubstitutorMap = currentSubstitutor.map.toMutableMap()
|
|
||||||
|
|
||||||
explicitTypeArguments.forEachIndexed { index, typeArgument ->
|
|
||||||
val typeVariableConstructor = typeVariables.getOrNull(index)?.freshTypeConstructor ?: return@forEachIndexed
|
|
||||||
|
|
||||||
newSubstitutorMap[typeVariableConstructor] =
|
|
||||||
newSubstitutorMap[typeVariableConstructor]?.withNullabilityFromExplicitTypeArgument(typeArgument)
|
|
||||||
?: return@forEachIndexed
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewTypeSubstitutorByConstructorMap(newSubstitutorMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun KotlinType.withNullabilityFromExplicitTypeArgument(typeArgument: SimpleTypeArgument) =
|
|
||||||
(if (typeArgument.type.isMarkedNullable) makeNullable() else makeNotNullable()).unwrap()
|
|
||||||
|
|
||||||
private fun substitutedResultingDescriptor(substitutor: NewTypeSubstitutor?): CallableDescriptor {
|
|
||||||
val candidateDescriptor = when (resolvedAtom) {
|
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.candidateDescriptor
|
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.candidate
|
|
||||||
}
|
|
||||||
|
|
||||||
return when (candidateDescriptor) {
|
|
||||||
is ClassConstructorDescriptor, is SyntheticMemberDescriptor<*> -> {
|
|
||||||
val explicitTypeArguments = emptyList<SimpleTypeArgument>()
|
|
||||||
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(
|
|
||||||
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
is FunctionDescriptor -> {
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor, candidateDescriptor.isNotSimpleCall())
|
|
||||||
}
|
|
||||||
is PropertyDescriptor -> {
|
|
||||||
if (candidateDescriptor.isNotSimpleCall()) {
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
|
||||||
} else {
|
|
||||||
candidateDescriptor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> candidateDescriptor
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CallableDescriptor.substituteInferredVariablesAndApproximate(
|
override fun containsOnlyOnlyInputTypesErrors(): Boolean = false
|
||||||
substitutor: NewTypeSubstitutor?,
|
|
||||||
shouldApproximate: Boolean = true
|
|
||||||
): CallableDescriptor {
|
|
||||||
val sub = when (resolvedAtom) {
|
|
||||||
is ResolvedCallableReferenceArgumentAtom -> resolvedAtom.candidate!!.freshVariablesSubstitutor!!
|
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.freshVariablesSubstitutor
|
|
||||||
}
|
|
||||||
|
|
||||||
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
|
||||||
|
|
||||||
return substitute(sub).substituteAndApproximateTypes(
|
|
||||||
inferredTypeVariablesSubstitutor,
|
|
||||||
typeApproximator = if (shouldApproximate) typeApproximator else null,
|
|
||||||
positionDependentApproximation = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
|
||||||
get() = TODO("Not yet implemented")
|
|
||||||
|
|
||||||
override val kotlinCall: KotlinCall
|
|
||||||
get() = when (resolvedAtom) {
|
|
||||||
is ResolvedCallableReferenceArgumentAtom ->
|
|
||||||
(resolvedAtom.candidate?.kotlinCall as CallableReferenceKotlinCallArgument).call
|
|
||||||
is ResolvedCallableReferenceCallAtom -> resolvedAtom.atom
|
|
||||||
}
|
|
||||||
override val languageVersionSettings: LanguageVersionSettings
|
|
||||||
get() = TODO("Not yet implemented")
|
|
||||||
|
|
||||||
override fun containsOnlyOnlyInputTypesErrors(): Boolean {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun argumentToParameterMap(
|
override fun argumentToParameterMap(
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
||||||
): Map<ValueArgument, ArgumentMatchImpl> {
|
): Map<ValueArgument, ArgumentMatchImpl> = emptyMap()
|
||||||
TODO("Not yet implemented")
|
|
||||||
|
init {
|
||||||
|
setResultingSubstitutor(substitutor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+112
-191
@@ -7,67 +7,68 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.ValueArgument
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateTypes
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.isNotSimpleCall
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.toResolutionStatus
|
import org.jetbrains.kotlin.resolve.calls.util.toResolutionStatus
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class NewResolvedCallImpl<D : CallableDescriptor>(
|
class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||||
override val resolvedCallAtom: ResolvedCallAtom,
|
override val resolvedCallAtom: ResolvedCallAtom,
|
||||||
substitutor: NewTypeSubstitutor?,
|
substitutor: NewTypeSubstitutor?,
|
||||||
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
private val typeApproximator: TypeApproximator,
|
override val typeApproximator: TypeApproximator,
|
||||||
override val languageVersionSettings: LanguageVersionSettings,
|
override val languageVersionSettings: LanguageVersionSettings,
|
||||||
) : NewAbstractResolvedCall<D>() {
|
) : NewAbstractResolvedCall<D>() {
|
||||||
override val psiKotlinCall: PSIKotlinCall = resolvedCallAtom.atom.psiKotlinCall
|
override val psiKotlinCall: PSIKotlinCall = resolvedCallAtom.atom.psiKotlinCall
|
||||||
|
override val kotlinCall: KotlinCall = resolvedCallAtom.atom
|
||||||
|
|
||||||
override var isCompleted = false
|
override val freshSubstitutor: FreshVariableNewTypeSubstitutor
|
||||||
private set
|
get() = resolvedCallAtom.freshVariablesSubstitutor
|
||||||
private lateinit var resultingDescriptor: D
|
|
||||||
|
|
||||||
private lateinit var typeArguments: List<UnwrappedType>
|
|
||||||
|
|
||||||
private var extensionReceiver = resolvedCallAtom.extensionReceiverArgument?.receiver?.receiverValue
|
|
||||||
private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue
|
|
||||||
private var smartCastDispatchReceiverType: KotlinType? = null
|
|
||||||
private var expectedTypeForSamConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
|
|
||||||
private var expectedTypeForSuspendConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
|
|
||||||
private var expectedTypeForUnitConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
|
|
||||||
private var argumentTypeForConstantConvertedMap: MutableMap<KtExpression, IntegerValueTypeConstant>? = null
|
|
||||||
|
|
||||||
|
|
||||||
override val kotlinCall: KotlinCall get() = resolvedCallAtom.atom
|
|
||||||
|
|
||||||
override fun getStatus(): ResolutionStatus = getResultApplicability(diagnostics).toResolutionStatus()
|
|
||||||
|
|
||||||
override val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
override val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||||
get() = resolvedCallAtom.argumentMappingByOriginal
|
get() = resolvedCallAtom.argumentMappingByOriginal
|
||||||
|
|
||||||
|
private lateinit var resultingDescriptor: D
|
||||||
|
private lateinit var typeArguments: List<UnwrappedType>
|
||||||
|
private var smartCastDispatchReceiverType: KotlinType? = null
|
||||||
|
private var expectedTypeForSamConvertedArgumentMap: Map<ValueArgument, UnwrappedType>? = null
|
||||||
|
private var expectedTypeForSuspendConvertedArgumentMap: Map<ValueArgument, UnwrappedType>? = null
|
||||||
|
private var expectedTypeForUnitConvertedArgumentMap: Map<ValueArgument, UnwrappedType>? = null
|
||||||
|
private var argumentTypeForConstantConvertedMap: Map<KtExpression, IntegerValueTypeConstant>? = null
|
||||||
|
private var extensionReceiver = resolvedCallAtom.extensionReceiverArgument?.receiver?.receiverValue
|
||||||
|
private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue
|
||||||
|
|
||||||
|
override fun getExtensionReceiver(): ReceiverValue? = extensionReceiver
|
||||||
|
override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun getCandidateDescriptor(): D = resolvedCallAtom.candidateDescriptor as D
|
override fun getCandidateDescriptor(): D = resolvedCallAtom.candidateDescriptor as D
|
||||||
override fun getResultingDescriptor(): D = resultingDescriptor
|
override fun getResultingDescriptor(): D = resultingDescriptor
|
||||||
override fun getExtensionReceiver(): ReceiverValue? = extensionReceiver
|
|
||||||
override fun getDispatchReceiver(): ReceiverValue? = dispatchReceiver
|
|
||||||
override fun getExplicitReceiverKind(): ExplicitReceiverKind = resolvedCallAtom.explicitReceiverKind
|
override fun getExplicitReceiverKind(): ExplicitReceiverKind = resolvedCallAtom.explicitReceiverKind
|
||||||
|
|
||||||
|
override fun updateDispatchReceiverType(newType: KotlinType) {
|
||||||
|
if (dispatchReceiver?.type == newType) return
|
||||||
|
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateExtensionReceiverType(newType: KotlinType) {
|
||||||
|
if (extensionReceiver?.type == newType) return
|
||||||
|
extensionReceiver = extensionReceiver?.replaceType(newType)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStatus(): ResolutionStatus = getResultApplicability(diagnostics).toResolutionStatus()
|
||||||
|
|
||||||
override fun getTypeArguments(): Map<TypeParameterDescriptor, KotlinType> {
|
override fun getTypeArguments(): Map<TypeParameterDescriptor, KotlinType> {
|
||||||
val typeParameters = candidateDescriptor.typeParameters.takeIf { it.isNotEmpty() } ?: return emptyMap()
|
val typeParameters = candidateDescriptor.typeParameters.takeIf { it.isNotEmpty() } ?: return emptyMap()
|
||||||
return typeParameters.zip(typeArguments).toMap()
|
return typeParameters.zip(typeArguments).toMap()
|
||||||
@@ -78,56 +79,17 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
|
|
||||||
override fun getSmartCastDispatchReceiverType(): KotlinType? = smartCastDispatchReceiverType
|
override fun getSmartCastDispatchReceiverType(): KotlinType? = smartCastDispatchReceiverType
|
||||||
|
|
||||||
fun updateExtensionReceiverWithSmartCastIfNeeded(smartCastExtensionReceiverType: KotlinType) {
|
|
||||||
if (extensionReceiver is ImplicitClassReceiver) {
|
|
||||||
extensionReceiver = CastImplicitClassReceiver(
|
|
||||||
(extensionReceiver as ImplicitClassReceiver).classDescriptor,
|
|
||||||
smartCastExtensionReceiverType,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSmartCastDispatchReceiverType(smartCastDispatchReceiverType: KotlinType) {
|
|
||||||
this.smartCastDispatchReceiverType = smartCastDispatchReceiverType
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateDiagnostics(completedDiagnostics: Collection<KotlinCallDiagnostic>) {
|
|
||||||
diagnostics = completedDiagnostics
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateExtensionReceiverType(newType: KotlinType) {
|
|
||||||
if (extensionReceiver?.type == newType) return
|
|
||||||
extensionReceiver = extensionReceiver?.replaceType(newType)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateDispatchReceiverType(newType: KotlinType) {
|
|
||||||
if (dispatchReceiver?.type == newType) return
|
|
||||||
dispatchReceiver = dispatchReceiver?.replaceType(newType)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||||
//clear cached values
|
//clear cached values
|
||||||
argumentToParameterMap = null
|
updateArgumentsMapping(null)
|
||||||
_valueArguments = null
|
updateValueArguments(null)
|
||||||
if (substitutor != null) {
|
|
||||||
// todo: add asset that we do not complete call many times
|
|
||||||
isCompleted = true
|
|
||||||
|
|
||||||
dispatchReceiver?.type?.let {
|
substituteReceivers(substitutor)
|
||||||
val newType = substitutor.safeSubstitute(it.unwrap())
|
|
||||||
updateDispatchReceiverType(newType)
|
|
||||||
}
|
|
||||||
|
|
||||||
extensionReceiver?.type?.let {
|
|
||||||
val newType = substitutor.safeSubstitute(it.unwrap())
|
|
||||||
updateExtensionReceiverType(newType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
resultingDescriptor = substitutedResultingDescriptor(substitutor) as D
|
resultingDescriptor = substitutedResultingDescriptor(substitutor) as D
|
||||||
|
|
||||||
typeArguments = resolvedCallAtom.freshVariablesSubstitutor.freshVariables.map {
|
typeArguments = freshSubstitutor.freshVariables.map {
|
||||||
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
||||||
typeApproximator
|
typeApproximator
|
||||||
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
||||||
@@ -140,126 +102,6 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
calculateExpectedTypeForConstantConvertedArgumentMap()
|
calculateExpectedTypeForConstantConvertedArgumentMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.withNullabilityFromExplicitTypeArgument(typeArgument: SimpleTypeArgument) =
|
|
||||||
(if (typeArgument.type.isMarkedNullable) makeNullable() else makeNotNullable()).unwrap()
|
|
||||||
|
|
||||||
private fun getSubstitutorWithoutFlexibleTypes(
|
|
||||||
currentSubstitutor: NewTypeSubstitutor?,
|
|
||||||
explicitTypeArguments: List<SimpleTypeArgument>,
|
|
||||||
): NewTypeSubstitutor? {
|
|
||||||
if (currentSubstitutor !is NewTypeSubstitutorByConstructorMap || explicitTypeArguments.isEmpty()) return currentSubstitutor
|
|
||||||
if (!currentSubstitutor.map.any { (_, value) -> value.isFlexible() }) return currentSubstitutor
|
|
||||||
|
|
||||||
val typeVariables = resolvedCallAtom.freshVariablesSubstitutor.freshVariables
|
|
||||||
val newSubstitutorMap = currentSubstitutor.map.toMutableMap()
|
|
||||||
|
|
||||||
explicitTypeArguments.forEachIndexed { index, typeArgument ->
|
|
||||||
val typeVariableConstructor = typeVariables.getOrNull(index)?.freshTypeConstructor ?: return@forEachIndexed
|
|
||||||
|
|
||||||
newSubstitutorMap[typeVariableConstructor] =
|
|
||||||
newSubstitutorMap[typeVariableConstructor]?.withNullabilityFromExplicitTypeArgument(typeArgument)
|
|
||||||
?: return@forEachIndexed
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewTypeSubstitutorByConstructorMap(newSubstitutorMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun substitutedResultingDescriptor(substitutor: NewTypeSubstitutor?) =
|
|
||||||
when (val candidateDescriptor = resolvedCallAtom.candidateDescriptor) {
|
|
||||||
is ClassConstructorDescriptor, is SyntheticMemberDescriptor<*> -> {
|
|
||||||
val explicitTypeArguments = resolvedCallAtom.atom.typeArguments.filterIsInstance<SimpleTypeArgument>()
|
|
||||||
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(
|
|
||||||
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is FunctionDescriptor -> {
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor, candidateDescriptor.isNotSimpleCall())
|
|
||||||
}
|
|
||||||
is PropertyDescriptor -> {
|
|
||||||
if (candidateDescriptor.isNotSimpleCall()) {
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
|
||||||
} else {
|
|
||||||
candidateDescriptor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> candidateDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun CallableDescriptor.substituteInferredVariablesAndApproximate(
|
|
||||||
substitutor: NewTypeSubstitutor?,
|
|
||||||
shouldApproximate: Boolean = true
|
|
||||||
): CallableDescriptor {
|
|
||||||
val inferredTypeVariablesSubstitutor = substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
|
||||||
|
|
||||||
// TODO: merge last two substitutors to avoid redundant descriptor substitutions
|
|
||||||
return substitute(resolvedCallAtom.freshVariablesSubstitutor)
|
|
||||||
.substitute(resolvedCallAtom.knownParametersSubstitutor)
|
|
||||||
.substituteAndApproximateTypes(
|
|
||||||
inferredTypeVariablesSubstitutor,
|
|
||||||
typeApproximator.takeIf { shouldApproximate }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
|
||||||
val expression = valueArgument.getArgumentExpression() ?: return null
|
|
||||||
return argumentTypeForConstantConvertedMap?.get(expression)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
|
||||||
expectedTypeForSamConvertedArgumentMap?.get(valueArgument)
|
|
||||||
|
|
||||||
fun getExpectedTypeForSuspendConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
|
||||||
expectedTypeForSuspendConvertedArgumentMap?.get(valueArgument)
|
|
||||||
|
|
||||||
fun getExpectedTypeForUnitConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
|
||||||
expectedTypeForUnitConvertedArgumentMap?.get(valueArgument)
|
|
||||||
|
|
||||||
private fun calculateExpectedTypeForConstantConvertedArgumentMap() {
|
|
||||||
if (resolvedCallAtom.argumentsWithConstantConversion.isEmpty()) return
|
|
||||||
|
|
||||||
argumentTypeForConstantConvertedMap = hashMapOf()
|
|
||||||
for ((argument, convertedConstant) in resolvedCallAtom.argumentsWithConstantConversion) {
|
|
||||||
val expression = argument.psiExpression ?: continue
|
|
||||||
argumentTypeForConstantConvertedMap!![expression] = convertedConstant
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateExpectedTypeForSamConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
|
||||||
if (resolvedCallAtom.argumentsWithConversion.isEmpty()) return
|
|
||||||
|
|
||||||
expectedTypeForSamConvertedArgumentMap = hashMapOf()
|
|
||||||
for ((argument, description) in resolvedCallAtom.argumentsWithConversion) {
|
|
||||||
val typeWithFreshVariables =
|
|
||||||
resolvedCallAtom.freshVariablesSubstitutor.safeSubstitute(description.convertedTypeByCandidateParameter)
|
|
||||||
val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables
|
|
||||||
expectedTypeForSamConvertedArgumentMap!![argument.psiCallArgument.valueArgument] = expectedType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateExpectedTypeForSuspendConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
|
||||||
if (resolvedCallAtom.argumentsWithSuspendConversion.isEmpty()) return
|
|
||||||
|
|
||||||
expectedTypeForSuspendConvertedArgumentMap = hashMapOf()
|
|
||||||
for ((argument, convertedType) in resolvedCallAtom.argumentsWithSuspendConversion) {
|
|
||||||
val typeWithFreshVariables = resolvedCallAtom.freshVariablesSubstitutor.safeSubstitute(convertedType)
|
|
||||||
val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables
|
|
||||||
expectedTypeForSuspendConvertedArgumentMap!![argument.psiCallArgument.valueArgument] = expectedType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateExpectedTypeForUnitConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
|
||||||
if (resolvedCallAtom.argumentsWithUnitConversion.isEmpty()) return
|
|
||||||
|
|
||||||
expectedTypeForUnitConvertedArgumentMap = hashMapOf()
|
|
||||||
for ((argument, convertedType) in resolvedCallAtom.argumentsWithUnitConversion) {
|
|
||||||
val typeWithFreshVariables = resolvedCallAtom.freshVariablesSubstitutor.safeSubstitute(convertedType)
|
|
||||||
val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables
|
|
||||||
expectedTypeForUnitConvertedArgumentMap!![argument.psiCallArgument.valueArgument] = expectedType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun argumentToParameterMap(
|
override fun argumentToParameterMap(
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
||||||
@@ -279,6 +121,85 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateExtensionReceiverWithSmartCastIfNeeded(smartCastExtensionReceiverType: KotlinType) {
|
||||||
|
if (extensionReceiver is ImplicitClassReceiver) {
|
||||||
|
extensionReceiver = CastImplicitClassReceiver(
|
||||||
|
(extensionReceiver as ImplicitClassReceiver).classDescriptor,
|
||||||
|
smartCastExtensionReceiverType,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSmartCastDispatchReceiverType(smartCastDispatchReceiverType: KotlinType) {
|
||||||
|
this.smartCastDispatchReceiverType = smartCastDispatchReceiverType
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDiagnostics(completedDiagnostics: Collection<KotlinCallDiagnostic>) {
|
||||||
|
diagnostics = completedDiagnostics
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
||||||
|
val expression = valueArgument.getArgumentExpression() ?: return null
|
||||||
|
return argumentTypeForConstantConvertedMap?.get(expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
||||||
|
expectedTypeForSamConvertedArgumentMap?.get(valueArgument)
|
||||||
|
|
||||||
|
fun getExpectedTypeForSuspendConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
||||||
|
expectedTypeForSuspendConvertedArgumentMap?.get(valueArgument)
|
||||||
|
|
||||||
|
fun getExpectedTypeForUnitConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
||||||
|
expectedTypeForUnitConvertedArgumentMap?.get(valueArgument)
|
||||||
|
|
||||||
|
private fun calculateExpectedTypeForConvertedArguments(
|
||||||
|
arguments: Map<KotlinCallArgument, UnwrappedType>,
|
||||||
|
substitutor: NewTypeSubstitutor?,
|
||||||
|
): Map<ValueArgument, UnwrappedType>? {
|
||||||
|
if (arguments.isEmpty()) return null
|
||||||
|
|
||||||
|
val expectedTypeForConvertedArguments = hashMapOf<ValueArgument, UnwrappedType>()
|
||||||
|
for ((argument, convertedType) in arguments) {
|
||||||
|
val typeWithFreshVariables = resolvedCallAtom.freshVariablesSubstitutor.safeSubstitute(convertedType)
|
||||||
|
val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables
|
||||||
|
expectedTypeForConvertedArguments[argument.psiCallArgument.valueArgument] = expectedType
|
||||||
|
}
|
||||||
|
|
||||||
|
return expectedTypeForConvertedArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateExpectedTypeForConstantConvertedArgumentMap() {
|
||||||
|
if (resolvedCallAtom.argumentsWithConstantConversion.isEmpty()) return
|
||||||
|
|
||||||
|
val expectedTypeForConvertedArguments = hashMapOf<KtExpression, IntegerValueTypeConstant>()
|
||||||
|
|
||||||
|
for ((argument, convertedConstant) in resolvedCallAtom.argumentsWithConstantConversion) {
|
||||||
|
val expression = argument.psiExpression ?: continue
|
||||||
|
expectedTypeForConvertedArguments[expression] = convertedConstant
|
||||||
|
}
|
||||||
|
|
||||||
|
argumentTypeForConstantConvertedMap = expectedTypeForConvertedArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateExpectedTypeForSamConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
||||||
|
expectedTypeForSamConvertedArgumentMap = calculateExpectedTypeForConvertedArguments(
|
||||||
|
resolvedCallAtom.argumentsWithConversion.mapValues { it.value.convertedTypeByCandidateParameter },
|
||||||
|
substitutor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateExpectedTypeForSuspendConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
||||||
|
expectedTypeForSuspendConvertedArgumentMap = calculateExpectedTypeForConvertedArguments(
|
||||||
|
resolvedCallAtom.argumentsWithSuspendConversion, substitutor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateExpectedTypeForUnitConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
||||||
|
expectedTypeForUnitConvertedArgumentMap = calculateExpectedTypeForConvertedArguments(
|
||||||
|
resolvedCallAtom.argumentsWithUnitConversion, substitutor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun collectErrorPositions(): Map<ValueArgument, List<KotlinCallDiagnostic>> {
|
private fun collectErrorPositions(): Map<ValueArgument, List<KotlinCallDiagnostic>> {
|
||||||
val result = mutableListOf<Pair<ValueArgument, KotlinCallDiagnostic>>()
|
val result = mutableListOf<Pair<ValueArgument, KotlinCallDiagnostic>>()
|
||||||
|
|
||||||
|
|||||||
+24
-11
@@ -5,21 +5,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.tower
|
package org.jetbrains.kotlin.resolve.calls.tower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallAtom
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeApproximator
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
class NewVariableAsFunctionResolvedCallImpl(
|
class NewVariableAsFunctionResolvedCallImpl(
|
||||||
override val variableCall: NewAbstractResolvedCall<VariableDescriptor>,
|
override val variableCall: NewAbstractResolvedCall<VariableDescriptor>,
|
||||||
override val functionCall: NewAbstractResolvedCall<FunctionDescriptor>,
|
override val functionCall: NewAbstractResolvedCall<FunctionDescriptor>,
|
||||||
) : VariableAsFunctionResolvedCall, NewAbstractResolvedCall<FunctionDescriptor>() {
|
) : VariableAsFunctionResolvedCall, NewAbstractResolvedCall<FunctionDescriptor>() {
|
||||||
override val resolvedCallAtom = functionCall.resolvedCallAtom
|
val baseCall: PSIKotlinCallImpl = functionCall.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
||||||
|
|
||||||
|
override val resolvedCallAtom: ResolvedCallAtom? = functionCall.resolvedCallAtom
|
||||||
override val psiKotlinCall: PSIKotlinCall = functionCall.psiKotlinCall
|
override val psiKotlinCall: PSIKotlinCall = functionCall.psiKotlinCall
|
||||||
val baseCall get() = functionCall.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
override val typeApproximator: TypeApproximator = functionCall.typeApproximator
|
||||||
|
override val freshSubstitutor: FreshVariableNewTypeSubstitutor? = functionCall.freshSubstitutor
|
||||||
|
override val argumentMappingByOriginal = functionCall.argumentMappingByOriginal
|
||||||
|
override val kotlinCall = functionCall.kotlinCall
|
||||||
|
override val languageVersionSettings = functionCall.languageVersionSettings
|
||||||
|
|
||||||
override fun getStatus() = functionCall.status
|
override fun getStatus() = functionCall.status
|
||||||
override fun getCandidateDescriptor() = functionCall.candidateDescriptor
|
override fun getCandidateDescriptor() = functionCall.candidateDescriptor
|
||||||
override fun getResultingDescriptor() = functionCall.resultingDescriptor
|
override fun getResultingDescriptor() = functionCall.resultingDescriptor
|
||||||
@@ -28,13 +38,16 @@ class NewVariableAsFunctionResolvedCallImpl(
|
|||||||
override fun getExplicitReceiverKind() = functionCall.explicitReceiverKind
|
override fun getExplicitReceiverKind() = functionCall.explicitReceiverKind
|
||||||
override fun getTypeArguments() = functionCall.typeArguments
|
override fun getTypeArguments() = functionCall.typeArguments
|
||||||
override fun getSmartCastDispatchReceiverType() = functionCall.smartCastDispatchReceiverType
|
override fun getSmartCastDispatchReceiverType() = functionCall.smartCastDispatchReceiverType
|
||||||
override val argumentMappingByOriginal = functionCall.argumentMappingByOriginal
|
|
||||||
override val kotlinCall = functionCall.kotlinCall
|
|
||||||
override val languageVersionSettings = functionCall.languageVersionSettings
|
|
||||||
override fun containsOnlyOnlyInputTypesErrors() = functionCall.containsOnlyOnlyInputTypesErrors()
|
override fun containsOnlyOnlyInputTypesErrors() = functionCall.containsOnlyOnlyInputTypesErrors()
|
||||||
|
override fun updateDispatchReceiverType(newType: KotlinType) = functionCall.updateDispatchReceiverType(newType)
|
||||||
|
override fun updateExtensionReceiverType(newType: KotlinType) = functionCall.updateExtensionReceiverType(newType)
|
||||||
override fun argumentToParameterMap(
|
override fun argumentToParameterMap(
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
||||||
) = functionCall.argumentToParameterMap(resultingDescriptor, valueArguments)
|
) = functionCall.argumentToParameterMap(resultingDescriptor, valueArguments)
|
||||||
override val isCompleted: Boolean = functionCall.isCompleted
|
|
||||||
}
|
override fun setResultingSubstitutor(substitutor: NewTypeSubstitutor?) {
|
||||||
|
functionCall.setResultingSubstitutor(substitutor)
|
||||||
|
variableCall.setResultingSubstitutor(substitutor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ class PSICallResolver(
|
|||||||
val defaultResolutionKinds = setOf(
|
val defaultResolutionKinds = setOf(
|
||||||
NewResolutionOldInference.ResolutionKind.Function,
|
NewResolutionOldInference.ResolutionKind.Function,
|
||||||
NewResolutionOldInference.ResolutionKind.Variable,
|
NewResolutionOldInference.ResolutionKind.Variable,
|
||||||
NewResolutionOldInference.ResolutionKind.Invoke
|
NewResolutionOldInference.ResolutionKind.Invoke,
|
||||||
|
NewResolutionOldInference.ResolutionKind.CallableReference
|
||||||
)
|
)
|
||||||
|
|
||||||
fun <D : CallableDescriptor> runResolutionAndInference(
|
fun <D : CallableDescriptor> runResolutionAndInference(
|
||||||
@@ -98,10 +99,9 @@ class PSICallResolver(
|
|||||||
val resolutionCallbacks = createResolutionCallbacks(context)
|
val resolutionCallbacks = createResolutionCallbacks(context)
|
||||||
|
|
||||||
val expectedType = calculateExpectedType(context)
|
val expectedType = calculateExpectedType(context)
|
||||||
var result =
|
var result = kotlinCallResolver.resolveAndCompleteCall(
|
||||||
kotlinCallResolver.resolveCall(scopeTower, resolutionCallbacks, kotlinCall, expectedType, context.collectAllCandidates) {
|
scopeTower, resolutionCallbacks, kotlinCall, expectedType, context.collectAllCandidates
|
||||||
FactoryProviderForInvoke(context, scopeTower, kotlinCall)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
|
val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
|
||||||
if (isBinaryRemOperator && shouldUseOperatorRem && (result.isEmpty() || result.areAllInapplicable())) {
|
if (isBinaryRemOperator && shouldUseOperatorRem && (result.isEmpty() || result.areAllInapplicable())) {
|
||||||
@@ -141,7 +141,7 @@ class PSICallResolver(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = kotlinCallResolver.resolveGivenCandidates(
|
val result = kotlinCallResolver.resolveAndCompleteGivenCandidates(
|
||||||
scopeTower, resolutionCallbacks, kotlinCall, calculateExpectedType(context), givenCandidates, context.collectAllCandidates
|
scopeTower, resolutionCallbacks, kotlinCall, calculateExpectedType(context), givenCandidates, context.collectAllCandidates
|
||||||
)
|
)
|
||||||
val overloadResolutionResults = convertToOverloadResolutionResults<D>(context, result, tracingStrategy)
|
val overloadResolutionResults = convertToOverloadResolutionResults<D>(context, result, tracingStrategy)
|
||||||
@@ -169,11 +169,9 @@ class PSICallResolver(
|
|||||||
val callWithDeprecatedName = toKotlinCall(
|
val callWithDeprecatedName = toKotlinCall(
|
||||||
context, kotlinCallKind, context.call, deprecatedName, tracingStrategy, isSpecialFunction = false
|
context, kotlinCallKind, context.call, deprecatedName, tracingStrategy, isSpecialFunction = false
|
||||||
)
|
)
|
||||||
return kotlinCallResolver.resolveCall(
|
return kotlinCallResolver.resolveAndCompleteCall(
|
||||||
scopeTower, resolutionCallbacks, callWithDeprecatedName, expectedType, context.collectAllCandidates
|
scopeTower, resolutionCallbacks, callWithDeprecatedName, expectedType, context.collectAllCandidates
|
||||||
) {
|
)
|
||||||
FactoryProviderForInvoke(context, scopeTower, callWithDeprecatedName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refineNameForRemOperator(isBinaryRemOperator: Boolean, name: Name): Name {
|
private fun refineNameForRemOperator(isBinaryRemOperator: Boolean, name: Name): Name {
|
||||||
@@ -190,17 +188,14 @@ class PSICallResolver(
|
|||||||
argumentTypeResolver, languageVersionSettings, kotlinToResolvedCallTransformer,
|
argumentTypeResolver, languageVersionSettings, kotlinToResolvedCallTransformer,
|
||||||
dataFlowValueFactory, inferenceSession, constantExpressionEvaluator, typeResolver,
|
dataFlowValueFactory, inferenceSession, constantExpressionEvaluator, typeResolver,
|
||||||
this, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents,
|
this, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents,
|
||||||
doubleColonExpressionResolver, deprecationResolver, moduleDescriptor, context, missingSupertypesResolver
|
doubleColonExpressionResolver, deprecationResolver, moduleDescriptor, context, missingSupertypesResolver, kotlinCallResolver
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun calculateExpectedType(context: BasicCallResolutionContext): UnwrappedType? {
|
private fun calculateExpectedType(context: BasicCallResolutionContext): UnwrappedType? {
|
||||||
val expectedType = context.expectedType.unwrap()
|
val expectedType = context.expectedType.unwrap()
|
||||||
|
|
||||||
return if (context.contextDependency == ContextDependency.DEPENDENT) {
|
return if (context.contextDependency == ContextDependency.DEPENDENT) {
|
||||||
assert(TypeUtils.noExpectedType(expectedType)) {
|
if (TypeUtils.noExpectedType(expectedType)) null else expectedType
|
||||||
"Should have no expected type, got: $expectedType"
|
|
||||||
}
|
|
||||||
null
|
|
||||||
} else {
|
} else {
|
||||||
if (expectedType.isError) TypeUtils.NO_EXPECTED_TYPE else expectedType
|
if (expectedType.isError) TypeUtils.NO_EXPECTED_TYPE else expectedType
|
||||||
}
|
}
|
||||||
@@ -282,7 +277,7 @@ class PSICallResolver(
|
|||||||
): ManyCandidates<D> {
|
): ManyCandidates<D> {
|
||||||
val resolvedCalls = diagnostic.candidates.map {
|
val resolvedCalls = diagnostic.candidates.map {
|
||||||
kotlinToResolvedCallTransformer.onlyTransform<D>(
|
kotlinToResolvedCallTransformer.onlyTransform<D>(
|
||||||
it.resolvedCall, it.diagnosticsFromResolutionParts + it.getSystem().errors.asDiagnostics()
|
it.resolvedCall, it.diagnostics + it.getSystem().errors.asDiagnostics()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +449,7 @@ class PSICallResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class FactoryProviderForInvoke(
|
inner class FactoryProviderForInvoke(
|
||||||
val context: BasicCallResolutionContext,
|
val context: BasicCallResolutionContext,
|
||||||
val scopeTower: ImplicitScopeTower,
|
val scopeTower: ImplicitScopeTower,
|
||||||
val kotlinCall: PSIKotlinCallImpl
|
val kotlinCall: PSIKotlinCallImpl
|
||||||
@@ -472,9 +467,7 @@ class PSICallResolver(
|
|||||||
override fun factoryForVariable(stripExplicitReceiver: Boolean): CandidateFactory<ResolutionCandidate> {
|
override fun factoryForVariable(stripExplicitReceiver: Boolean): CandidateFactory<ResolutionCandidate> {
|
||||||
val explicitReceiver = if (stripExplicitReceiver) null else kotlinCall.explicitReceiver
|
val explicitReceiver = if (stripExplicitReceiver) null else kotlinCall.explicitReceiver
|
||||||
val variableCall = PSIKotlinCallForVariable(kotlinCall, explicitReceiver, kotlinCall.name)
|
val variableCall = PSIKotlinCallForVariable(kotlinCall, explicitReceiver, kotlinCall.name)
|
||||||
return SimpleCandidateFactory(
|
return SimpleCandidateFactory(callComponents, scopeTower, variableCall, createResolutionCallbacks(context))
|
||||||
callComponents, scopeTower, variableCall, createResolutionCallbacks(context), callableReferenceResolver
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun factoryForInvoke(variable: ResolutionCandidate, useExplicitReceiver: Boolean):
|
override fun factoryForInvoke(variable: ResolutionCandidate, useExplicitReceiver: Boolean):
|
||||||
@@ -554,7 +547,7 @@ class PSICallResolver(
|
|||||||
is NewResolutionOldInference.ResolutionKind.Function -> KotlinCallKind.FUNCTION
|
is NewResolutionOldInference.ResolutionKind.Function -> KotlinCallKind.FUNCTION
|
||||||
is NewResolutionOldInference.ResolutionKind.Variable -> KotlinCallKind.VARIABLE
|
is NewResolutionOldInference.ResolutionKind.Variable -> KotlinCallKind.VARIABLE
|
||||||
is NewResolutionOldInference.ResolutionKind.Invoke -> KotlinCallKind.INVOKE
|
is NewResolutionOldInference.ResolutionKind.Invoke -> KotlinCallKind.INVOKE
|
||||||
is NewResolutionOldInference.ResolutionKind.CallableReference -> KotlinCallKind.UNSUPPORTED
|
is NewResolutionOldInference.ResolutionKind.CallableReference -> KotlinCallKind.CALLABLE_REFERENCE
|
||||||
is NewResolutionOldInference.ResolutionKind.GivenCandidates -> KotlinCallKind.UNSUPPORTED
|
is NewResolutionOldInference.ResolutionKind.GivenCandidates -> KotlinCallKind.UNSUPPORTED
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -822,52 +815,22 @@ class PSICallResolver(
|
|||||||
startDataFlowInfo: DataFlowInfo,
|
startDataFlowInfo: DataFlowInfo,
|
||||||
valueArgument: ValueArgument,
|
valueArgument: ValueArgument,
|
||||||
argumentName: Name?,
|
argumentName: Name?,
|
||||||
outerCallContext: BasicCallResolutionContext
|
outerCallContext: BasicCallResolutionContext,
|
||||||
|
tracingStrategy: TracingStrategy
|
||||||
): CallableReferenceKotlinCallArgumentImpl {
|
): CallableReferenceKotlinCallArgumentImpl {
|
||||||
checkNoSpread(outerCallContext, valueArgument)
|
checkNoSpread(outerCallContext, valueArgument)
|
||||||
|
|
||||||
val expressionTypingContext = ExpressionTypingContext.newContext(context)
|
val (doubleColonLhs, lhsResult) = getLhsResult(context, ktExpression)
|
||||||
val lhsResult = if (ktExpression.isEmptyLHS) null else doubleColonExpressionResolver.resolveDoubleColonLHS(
|
val newDataFlowInfo = (doubleColonLhs as? DoubleColonLHS.Expression)?.dataFlowInfo ?: startDataFlowInfo
|
||||||
ktExpression,
|
val rhsExpression = ktExpression.callableReference
|
||||||
expressionTypingContext
|
val rhsName = rhsExpression.getReferencedNameAsName()
|
||||||
)
|
val call = outerCallContext.trace[BindingContext.CALL, rhsExpression]
|
||||||
val newDataFlowInfo = (lhsResult as? DoubleColonLHS.Expression)?.dataFlowInfo ?: startDataFlowInfo
|
?: CallMaker.makeCall(rhsExpression, null, null, rhsExpression, emptyList())
|
||||||
val name = ktExpression.callableReference.getReferencedNameAsName()
|
val kotlinCall = toKotlinCall(context, KotlinCallKind.CALLABLE_REFERENCE, call, rhsName, tracingStrategy, isSpecialFunction = false)
|
||||||
|
|
||||||
val lhsNewResult = when (lhsResult) {
|
|
||||||
null -> LHSResult.Empty
|
|
||||||
is DoubleColonLHS.Expression -> {
|
|
||||||
if (lhsResult.isObjectQualifier) {
|
|
||||||
val classifier = lhsResult.type.constructor.declarationDescriptor
|
|
||||||
val calleeExpression = ktExpression.receiverExpression?.getCalleeExpressionIfAny()
|
|
||||||
if (calleeExpression is KtSimpleNameExpression && classifier is ClassDescriptor) {
|
|
||||||
LHSResult.Object(ClassQualifier(calleeExpression, classifier))
|
|
||||||
} else {
|
|
||||||
LHSResult.Error
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val fakeArgument = FakeValueArgumentForLeftCallableReference(ktExpression)
|
|
||||||
|
|
||||||
val kotlinCallArgument = createSimplePSICallArgument(context, fakeArgument, lhsResult.typeInfo)
|
|
||||||
kotlinCallArgument?.let { LHSResult.Expression(it as SimpleKotlinCallArgument) } ?: LHSResult.Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is DoubleColonLHS.Type -> {
|
|
||||||
val qualifiedExpression = ktExpression.receiverExpression!!
|
|
||||||
val qualifier = expressionTypingContext.trace.get(BindingContext.QUALIFIER, qualifiedExpression)
|
|
||||||
val classifier = lhsResult.type.constructor.declarationDescriptor
|
|
||||||
if (classifier !is ClassDescriptor) {
|
|
||||||
expressionTypingContext.trace.report(Errors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS.on(ktExpression))
|
|
||||||
LHSResult.Error
|
|
||||||
} else {
|
|
||||||
LHSResult.Type(qualifier, lhsResult.type.unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CallableReferenceKotlinCallArgumentImpl(
|
return CallableReferenceKotlinCallArgumentImpl(
|
||||||
ASTScopeTower(context, ktExpression.callableReference), valueArgument, startDataFlowInfo, newDataFlowInfo,
|
ASTScopeTower(context, rhsExpression), valueArgument, startDataFlowInfo,
|
||||||
ktExpression, argumentName, lhsNewResult, name
|
newDataFlowInfo, ktExpression, argumentName, lhsResult, rhsName, kotlinCall
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+108
-69
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReference
|
|||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
|
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.ComposedSubstitutor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
@@ -33,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.extractCallableReferenceExpression
|
||||||
import org.jetbrains.kotlin.resolve.checkers.MissingDependencySupertypeChecker
|
import org.jetbrains.kotlin.resolve.checkers.MissingDependencySupertypeChecker
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
@@ -68,7 +71,7 @@ class ResolvedAtomCompleter(
|
|||||||
val dispatchReceiver: ReceiverValue?,
|
val dispatchReceiver: ReceiverValue?,
|
||||||
val extensionReceiver: ReceiverValue?,
|
val extensionReceiver: ReceiverValue?,
|
||||||
val explicitReceiver: ReceiverValue?,
|
val explicitReceiver: ReceiverValue?,
|
||||||
val substitutor: TypeSubstitutor,
|
val substitutor: NewTypeSubstitutor,
|
||||||
val resultType: KotlinType
|
val resultType: KotlinType
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,18 +112,32 @@ class ResolvedAtomCompleter(
|
|||||||
complete(resolvedAtom)
|
complete(resolvedAtom)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun completeSubCallArgument(resolvedSubCallArgument: ResolvedSubCallArgument) {
|
private fun completeSubCallArgument(resolvedSubCallArgument: ResolvedSubCallArgument) {
|
||||||
val contextWithoutExpectedType = topLevelCallContext.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)
|
val deparenthesizedExpression =
|
||||||
kotlinToResolvedCallTransformer.updateRecordedType(
|
KtPsiUtil.getLastElementDeparenthesized(resolvedSubCallArgument.atom.psiExpression, topLevelCallContext.statementFilter)
|
||||||
resolvedSubCallArgument.atom.psiExpression ?: return,
|
|
||||||
parameter = null,
|
if (deparenthesizedExpression is KtCallableReferenceExpression) {
|
||||||
context = contextWithoutExpectedType,
|
val callableReferenceResolvedCall = kotlinToResolvedCallTransformer.getResolvedCallForArgumentExpression(
|
||||||
reportErrorForTypeMismatch = true,
|
deparenthesizedExpression.callableReference, topLevelCallContext
|
||||||
convertedArgumentType = null
|
) as? NewCallableReferenceResolvedCall<*>
|
||||||
)
|
if (callableReferenceResolvedCall != null) {
|
||||||
|
completeCallableReferenceCall(callableReferenceResolvedCall)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
kotlinToResolvedCallTransformer.updateRecordedType(
|
||||||
|
resolvedSubCallArgument.atom.psiExpression ?: return,
|
||||||
|
parameter = null,
|
||||||
|
context = topLevelCallContext.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE),
|
||||||
|
reportErrorForTypeMismatch = true,
|
||||||
|
convertedArgumentType = null
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun completeResolvedCall(resolvedCallAtom: ResolvedCallAtom, diagnostics: Collection<KotlinCallDiagnostic>): ResolvedCall<*>? {
|
fun completeResolvedCall(
|
||||||
|
resolvedCallAtom: ResolvedCallAtom,
|
||||||
|
diagnostics: Collection<KotlinCallDiagnostic>
|
||||||
|
): NewAbstractResolvedCall<*>? {
|
||||||
val diagnosticsFromPartiallyResolvedCall = extractDiagnosticsFromPartiallyResolvedCall(resolvedCallAtom)
|
val diagnosticsFromPartiallyResolvedCall = extractDiagnosticsFromPartiallyResolvedCall(resolvedCallAtom)
|
||||||
|
|
||||||
clearPartiallyResolvedCall(resolvedCallAtom)
|
clearPartiallyResolvedCall(resolvedCallAtom)
|
||||||
@@ -137,9 +154,11 @@ class ResolvedAtomCompleter(
|
|||||||
allDiagnostics
|
allDiagnostics
|
||||||
)
|
)
|
||||||
|
|
||||||
val lastCall = if (resolvedCall is VariableAsFunctionResolvedCall) resolvedCall.functionCall else resolvedCall
|
val lastCall = if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||||
|
resolvedCall.functionCall as NewAbstractResolvedCall<*>
|
||||||
|
} else resolvedCall
|
||||||
if (ErrorUtils.isError(resolvedCall.candidateDescriptor)) {
|
if (ErrorUtils.isError(resolvedCall.candidateDescriptor)) {
|
||||||
kotlinToResolvedCallTransformer.runArgumentsChecks(topLevelCallContext, lastCall as NewResolvedCallImpl<*>)
|
kotlinToResolvedCallTransformer.runArgumentsChecks(topLevelCallContext, lastCall)
|
||||||
checkMissingReceiverSupertypes(resolvedCall, missingSupertypesResolver, topLevelTrace)
|
checkMissingReceiverSupertypes(resolvedCall, missingSupertypesResolver, topLevelTrace)
|
||||||
return resolvedCall
|
return resolvedCall
|
||||||
}
|
}
|
||||||
@@ -173,7 +192,7 @@ class ResolvedAtomCompleter(
|
|||||||
|
|
||||||
kotlinToResolvedCallTransformer.bind(topLevelTrace, resolvedCall)
|
kotlinToResolvedCallTransformer.bind(topLevelTrace, resolvedCall)
|
||||||
|
|
||||||
kotlinToResolvedCallTransformer.runArgumentsChecks(topLevelCallContext, lastCall as NewResolvedCallImpl<*>)
|
kotlinToResolvedCallTransformer.runArgumentsChecks(topLevelCallContext, lastCall)
|
||||||
kotlinToResolvedCallTransformer.runCallCheckers(resolvedCall, callCheckerContext)
|
kotlinToResolvedCallTransformer.runCallCheckers(resolvedCall, callCheckerContext)
|
||||||
kotlinToResolvedCallTransformer.runAdditionalReceiversCheckers(resolvedCall, topLevelCallContext)
|
kotlinToResolvedCallTransformer.runAdditionalReceiversCheckers(resolvedCall, topLevelCallContext)
|
||||||
|
|
||||||
@@ -340,25 +359,20 @@ class ResolvedAtomCompleter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCallableReferenceResultType(
|
private fun updateCallableReferenceResultType(callableCandidate: CallableReferenceResolutionCandidate): CallableReferenceResultTypeInfo? {
|
||||||
callableCandidate: CallableReferenceCandidate,
|
val callableReferenceExpression =
|
||||||
callableReferenceExpression: KtCallableReferenceExpression
|
callableCandidate.resolvedCall.atom.psiKotlinCall.psiCall.callElement.parent as? KtCallableReferenceExpression ?: return null
|
||||||
): CallableReferenceResultTypeInfo {
|
val freshSubstitutor = callableCandidate.freshVariablesSubstitutor ?: return null
|
||||||
val resultTypeParameters =
|
val resultTypeParameters = freshSubstitutor.freshVariables.map { resultSubstitutor.safeSubstitute(it.defaultType) }
|
||||||
callableCandidate.freshSubstitutor!!.freshVariables.map { resultSubstitutor.safeSubstitute(it.defaultType) }
|
|
||||||
|
|
||||||
val typeParametersSubstitutor = NewTypeSubstitutorByConstructorMap(
|
val typeParametersSubstitutor = NewTypeSubstitutorByConstructorMap(
|
||||||
(callableCandidate.candidate.typeParameters.map { it.typeConstructor } zip resultTypeParameters).toMap()
|
callableCandidate.candidate.typeParameters.map { it.typeConstructor }.zip(resultTypeParameters).toMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
val resultSubstitutor = if (callableCandidate.candidate.isSupportedForCallableReference()) {
|
val resultSubstitutor = if (callableCandidate.candidate.isSupportedForCallableReference()) {
|
||||||
val firstSubstitution = typeParametersSubstitutor.toOldSubstitution()
|
ComposedSubstitutor(typeParametersSubstitutor, resultSubstitutor)
|
||||||
val secondSubstitution = resultSubstitutor.toOldSubstitution()
|
} else EmptySubstitutor
|
||||||
TypeSubstitutor.createChainedSubstitutor(firstSubstitution, secondSubstitution)
|
|
||||||
} else TypeSubstitutor.EMPTY
|
|
||||||
|
|
||||||
// write down type for callable reference expression
|
// write down type for callable reference expression
|
||||||
val resultType = resultSubstitutor.safeSubstitute(callableCandidate.reflectionCandidateType, Variance.INVARIANT)
|
val resultType = resultSubstitutor.safeSubstitute(callableCandidate.reflectionCandidateType)
|
||||||
|
|
||||||
argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
|
argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
|
||||||
topLevelTrace, expressionTypingServices.statementFilter, resultType, callableReferenceExpression
|
topLevelTrace, expressionTypingServices.statementFilter, resultType, callableReferenceExpression
|
||||||
@@ -415,7 +429,7 @@ class ResolvedAtomCompleter(
|
|||||||
dispatchReceiver,
|
dispatchReceiver,
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
explicitCallableReceiver,
|
explicitCallableReceiver,
|
||||||
TypeSubstitutor.EMPTY,
|
EmptySubstitutor,
|
||||||
callableCandidate.reflectionCandidateType.replaceFunctionTypeArgumentsByDescriptor(recordedDescriptor)
|
callableCandidate.reflectionCandidateType.replaceFunctionTypeArgumentsByDescriptor(recordedDescriptor)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -437,79 +451,106 @@ class ResolvedAtomCompleter(
|
|||||||
else -> this
|
else -> this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun completeCallableReference(resolvedAtom: ResolvedCallableReferenceAtom) {
|
fun completeCallableReferenceCall(resolvedCall: NewCallableReferenceResolvedCall<*>): KotlinType? {
|
||||||
|
val candidate = resolvedCall.resolvedCallAtom?.candidate ?: return null
|
||||||
|
return completeCallableReference(candidate, resolvedCall.resultingDescriptor, resolvedCall)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun completeCallableReferenceArgument(resolvedAtom: ResolvedCallableReferenceArgumentAtom): KotlinType? {
|
||||||
|
if (resolvedAtom.completed) return null
|
||||||
|
|
||||||
val psiCallArgument = resolvedAtom.atom.psiCallArgument as CallableReferenceKotlinCallArgumentImpl
|
val psiCallArgument = resolvedAtom.atom.psiCallArgument as CallableReferenceKotlinCallArgumentImpl
|
||||||
val callableReferenceExpression = psiCallArgument.ktCallableReferenceExpression
|
val callableReferenceCallCandidate = resolvedAtom.candidate ?: return null
|
||||||
val callableCandidate = resolvedAtom.candidate
|
val descriptor = when (callableReferenceCallCandidate.candidate) {
|
||||||
if (callableCandidate == null || resolvedAtom.completed) {
|
is FunctionDescriptor -> topLevelCallContext.trace.get(BindingContext.FUNCTION, psiCallArgument.ktCallableReferenceExpression)
|
||||||
// todo report meanfull diagnostic here
|
is PropertyDescriptor -> topLevelCallContext.trace.get(BindingContext.VARIABLE, psiCallArgument.ktCallableReferenceExpression)
|
||||||
return
|
|
||||||
}
|
|
||||||
val recorderDescriptor = when (callableCandidate.candidate) {
|
|
||||||
is FunctionDescriptor -> topLevelCallContext.trace.get(BindingContext.FUNCTION, callableReferenceExpression)
|
|
||||||
is PropertyDescriptor -> topLevelCallContext.trace.get(BindingContext.VARIABLE, callableReferenceExpression)
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
val dataFlowInfo = resolvedAtom.atom.psiCallArgument.dataFlowInfoAfterThisArgument
|
||||||
|
val resolvedCall = NewCallableReferenceResolvedCall<CallableDescriptor>(
|
||||||
|
resolvedAtom,
|
||||||
|
typeApproximator,
|
||||||
|
expressionTypingServices.languageVersionSettings
|
||||||
|
)
|
||||||
|
|
||||||
|
return completeCallableReference(callableReferenceCallCandidate, descriptor, resolvedCall, dataFlowInfo)
|
||||||
|
.also { resolvedAtom.completed = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun completeCallableReference(
|
||||||
|
callableCandidate: CallableReferenceResolutionCandidate,
|
||||||
|
recordedDescriptor: CallableDescriptor?,
|
||||||
|
resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
|
additionalDataFlowInfo: DataFlowInfo? = null,
|
||||||
|
): KotlinType? {
|
||||||
val rawExtensionReceiver = callableCandidate.extensionReceiver
|
val rawExtensionReceiver = callableCandidate.extensionReceiver
|
||||||
|
|
||||||
val unrestrictedBuilderInferenceSupported =
|
val unrestrictedBuilderInferenceSupported =
|
||||||
topLevelCallContext.languageVersionSettings.supportsFeature(LanguageFeature.UnrestrictedBuilderInference)
|
topLevelCallContext.languageVersionSettings.supportsFeature(LanguageFeature.UnrestrictedBuilderInference)
|
||||||
|
val callableReferenceExpression =
|
||||||
|
callableCandidate.resolvedCall.atom.psiKotlinCall.extractCallableReferenceExpression() ?: return null
|
||||||
|
|
||||||
if (rawExtensionReceiver != null && !unrestrictedBuilderInferenceSupported && rawExtensionReceiver.receiver.receiverValue.type.contains { it is StubTypeForBuilderInference }) {
|
if (rawExtensionReceiver != null && !unrestrictedBuilderInferenceSupported && rawExtensionReceiver.receiver.receiverValue.type.contains { it is StubTypeForBuilderInference }) {
|
||||||
topLevelTrace.reportDiagnosticOnce(Errors.TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE.on(callableReferenceExpression))
|
topLevelTrace.reportDiagnosticOnce(Errors.TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE.on(callableReferenceExpression))
|
||||||
return
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// For some callable references we can already have recorder descriptor (see `DoubleColonExpressionResolver.getCallableReferenceType`)
|
val resultTypeInfo = if (recordedDescriptor != null) {
|
||||||
val resultTypeInfo = if (recorderDescriptor != null) {
|
extractCallableReferenceResultTypeInfoFromDescriptor(callableCandidate, recordedDescriptor)
|
||||||
extractCallableReferenceResultTypeInfoFromDescriptor(callableCandidate, recorderDescriptor)
|
|
||||||
} else {
|
} else {
|
||||||
updateCallableReferenceResultType(callableCandidate, psiCallArgument.ktCallableReferenceExpression)
|
updateCallableReferenceResultType(callableCandidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
val reference = callableReferenceExpression.callableReference
|
if (resultTypeInfo == null) return null
|
||||||
val psiCall = CallMaker.makeCall(reference, resultTypeInfo.explicitReceiver, null, reference, emptyList())
|
|
||||||
|
|
||||||
val tracing = TracingStrategyImpl.create(reference, psiCall)
|
resolvedCall.apply {
|
||||||
val temporaryTrace = TemporaryBindingTrace.create(topLevelTrace, "callable reference fake call")
|
if (resultTypeInfo.dispatchReceiver != null) {
|
||||||
|
updateDispatchReceiverType(resultTypeInfo.dispatchReceiver.type)
|
||||||
val resolvedCall = ResolvedCallImpl(
|
}
|
||||||
psiCall, callableCandidate.candidate, resultTypeInfo.dispatchReceiver,
|
if (resultTypeInfo.extensionReceiver != null) {
|
||||||
resultTypeInfo.extensionReceiver, callableCandidate.explicitReceiverKind,
|
updateExtensionReceiverType(resultTypeInfo.extensionReceiver.type)
|
||||||
null, temporaryTrace, tracing, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
}
|
||||||
)
|
setResultingSubstitutor(resultTypeInfo.substitutor)
|
||||||
|
}
|
||||||
resolvedCall.setSubstitutor(resultTypeInfo.substitutor)
|
|
||||||
|
|
||||||
recordArgumentAdaptationForCallableReference(resolvedCall, callableCandidate.callableReferenceAdaptation)
|
recordArgumentAdaptationForCallableReference(resolvedCall, callableCandidate.callableReferenceAdaptation)
|
||||||
|
|
||||||
|
val psiCall = CallMaker.makeCall(
|
||||||
|
callableReferenceExpression.callableReference,
|
||||||
|
resultTypeInfo.explicitReceiver,
|
||||||
|
null,
|
||||||
|
callableReferenceExpression.callableReference,
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
val tracing = TracingStrategyImpl.create(callableReferenceExpression.callableReference, psiCall)
|
||||||
|
|
||||||
tracing.bindCall(topLevelTrace, psiCall)
|
tracing.bindCall(topLevelTrace, psiCall)
|
||||||
tracing.bindReference(topLevelTrace, resolvedCall)
|
tracing.bindReference(topLevelTrace, resolvedCall)
|
||||||
tracing.bindResolvedCall(topLevelTrace, resolvedCall)
|
tracing.bindResolvedCall(topLevelTrace, resolvedCall)
|
||||||
|
|
||||||
resolvedCall.setStatusToSuccess()
|
|
||||||
resolvedCall.markCallAsCompleted()
|
|
||||||
|
|
||||||
// TODO: probably we should also record key 'DATA_FLOW_INFO_BEFORE', see ExpressionTypingVisitorDispatcher.getTypeInfo
|
// TODO: probably we should also record key 'DATA_FLOW_INFO_BEFORE', see ExpressionTypingVisitorDispatcher.getTypeInfo
|
||||||
val typeInfo = createTypeInfo(resultTypeInfo.resultType, resolvedAtom.atom.psiCallArgument.dataFlowInfoAfterThisArgument)
|
val typeInfo = if (additionalDataFlowInfo != null) {
|
||||||
|
createTypeInfo(resultTypeInfo.resultType, additionalDataFlowInfo)
|
||||||
|
} else {
|
||||||
|
createTypeInfo(resultTypeInfo.resultType)
|
||||||
|
}
|
||||||
|
|
||||||
topLevelTrace.record(BindingContext.EXPRESSION_TYPE_INFO, callableReferenceExpression, typeInfo)
|
topLevelTrace.record(BindingContext.EXPRESSION_TYPE_INFO, callableReferenceExpression, typeInfo)
|
||||||
topLevelTrace.record(BindingContext.PROCESSED, callableReferenceExpression)
|
topLevelTrace.record(BindingContext.PROCESSED, callableReferenceExpression)
|
||||||
|
|
||||||
kotlinToResolvedCallTransformer.runCallCheckers(resolvedCall, topLevelCallCheckerContext)
|
kotlinToResolvedCallTransformer.runCallCheckers(resolvedCall, topLevelCallCheckerContext)
|
||||||
resolvedAtom.completed = true
|
|
||||||
|
return resultTypeInfo.resultType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ReceiverValue.updateReceiverValue(substitutor: TypeSubstitutor): ReceiverValue {
|
private fun ReceiverValue.updateReceiverValue(substitutor: NewTypeSubstitutor): ReceiverValue {
|
||||||
val newType = substitutor.safeSubstitute(type, Variance.INVARIANT).let {
|
val newType = substitutor.safeSubstitute(type.unwrap()).let {
|
||||||
typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference) ?: it
|
typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference) ?: it
|
||||||
}
|
}
|
||||||
return if (type != newType) replaceType(newType as KotlinType) else this
|
return if (type != newType) replaceType(newType as KotlinType) else this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recordArgumentAdaptationForCallableReference(
|
private fun recordArgumentAdaptationForCallableReference(
|
||||||
resolvedCall: ResolvedCallImpl<CallableDescriptor>,
|
resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
callableReferenceAdaptation: CallableReferenceAdaptation?
|
callableReferenceAdaptation: CallableReferenceAdaptation?
|
||||||
) {
|
) {
|
||||||
if (callableReferenceAdaptation == null) return
|
if (callableReferenceAdaptation == null) return
|
||||||
@@ -560,14 +601,12 @@ class ResolvedAtomCompleter(
|
|||||||
mappedArguments.add(valueParameter to resolvedValueArgument)
|
mappedArguments.add(valueParameter to resolvedValueArgument)
|
||||||
}
|
}
|
||||||
if (hasNonTrivialMapping || isCallableReferenceWithImplicitConversion(resolvedCall, callableReferenceAdaptation)) {
|
if (hasNonTrivialMapping || isCallableReferenceWithImplicitConversion(resolvedCall, callableReferenceAdaptation)) {
|
||||||
for ((valueParameter, resolvedValueArgument) in mappedArguments) {
|
resolvedCall.updateValueArguments(mappedArguments.toMap())
|
||||||
resolvedCall.recordValueArgument(valueParameter, resolvedValueArgument)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCallableReferenceWithImplicitConversion(
|
private fun isCallableReferenceWithImplicitConversion(
|
||||||
resolvedCall: ResolvedCall<CallableDescriptor>,
|
resolvedCall: NewAbstractResolvedCall<*>,
|
||||||
callableReferenceAdaptation: CallableReferenceAdaptation
|
callableReferenceAdaptation: CallableReferenceAdaptation
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.psiKotlinCall
|
||||||
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.typeUtil.asTypeProjection
|
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||||
@@ -275,9 +276,16 @@ fun Call.isCallableReference(): Boolean {
|
|||||||
return callElement.isCallableReference()
|
return callElement.isCallableReference()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtElement.isCallableReference(): Boolean =
|
fun PsiElement.isCallableReference(): Boolean =
|
||||||
this is KtNameReferenceExpression && (parent as? KtCallableReferenceExpression)?.callableReference == this
|
this is KtNameReferenceExpression && (parent as? KtCallableReferenceExpression)?.callableReference == this
|
||||||
|
|
||||||
|
fun PsiElement.asCallableReferenceExpression(): KtCallableReferenceExpression? =
|
||||||
|
when {
|
||||||
|
isCallableReference() -> parent as KtCallableReferenceExpression
|
||||||
|
this is KtCallableReferenceExpression -> this
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
fun Call.createLookupLocation(): KotlinLookupLocation {
|
fun Call.createLookupLocation(): KotlinLookupLocation {
|
||||||
val calleeExpression = calleeExpression
|
val calleeExpression = calleeExpression
|
||||||
val element =
|
val element =
|
||||||
@@ -339,3 +347,8 @@ fun <D : CallableDescriptor> ResolvedCallImpl<D>.shouldBeSubstituteWithStubTypes
|
|||||||
|| dispatchReceiver?.type?.contains { it is StubTypeForBuilderInference } == true
|
|| dispatchReceiver?.type?.contains { it is StubTypeForBuilderInference } == true
|
||||||
|| extensionReceiver?.type?.contains { it is StubTypeForBuilderInference } == true
|
|| extensionReceiver?.type?.contains { it is StubTypeForBuilderInference } == true
|
||||||
|| valueArguments.any { argument -> argument.key.type.contains { it is StubTypeForBuilderInference } }
|
|| valueArguments.any { argument -> argument.key.type.contains { it is StubTypeForBuilderInference } }
|
||||||
|
|
||||||
|
fun KotlinCall.extractCallableReferenceExpression(): KtCallableReferenceExpression? =
|
||||||
|
psiKotlinCall.psiCall.extractCallableReferenceExpression()
|
||||||
|
|
||||||
|
fun Call.extractCallableReferenceExpression(): KtCallableReferenceExpression? = callElement.asCallableReferenceExpression()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.util
|
package org.jetbrains.kotlin.resolve.calls.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtCallElement
|
import org.jetbrains.kotlin.psi.KtCallElement
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||||
@@ -17,7 +17,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.NewAbstractResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassValueReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassValueReceiver
|
||||||
@@ -98,7 +99,8 @@ fun KtCallElement.getArgumentByParameterIndex(index: Int, context: BindingContex
|
|||||||
val parameterToProcess = resolvedCall.resultingDescriptor.valueParameters.getOrNull(index) ?: return emptyList()
|
val parameterToProcess = resolvedCall.resultingDescriptor.valueParameters.getOrNull(index) ?: return emptyList()
|
||||||
return resolvedCall.valueArguments[parameterToProcess]?.arguments ?: emptyList()
|
return resolvedCall.valueArguments[parameterToProcess]?.arguments ?: emptyList()
|
||||||
}
|
}
|
||||||
fun CallableMemberDescriptor.isNotSimpleCall(): Boolean =
|
|
||||||
|
fun CallableDescriptor.isNotSimpleCall(): Boolean =
|
||||||
typeParameters.isNotEmpty() ||
|
typeParameters.isNotEmpty() ||
|
||||||
(returnType?.let { type ->
|
(returnType?.let { type ->
|
||||||
type.contains {
|
type.contains {
|
||||||
@@ -109,7 +111,7 @@ fun CallableMemberDescriptor.isNotSimpleCall(): Boolean =
|
|||||||
}
|
}
|
||||||
} ?: false)
|
} ?: false)
|
||||||
|
|
||||||
fun ResolvedCall<*>.isNewNotCompleted(): Boolean = if (this is NewAbstractResolvedCall) !isCompleted else false
|
fun ResolvedCall<*>.isNewNotCompleted(): Boolean = if (this is NewAbstractResolvedCall) !isCompleted() else false
|
||||||
|
|
||||||
fun ResolvedCall<*>.hasInferredReturnType(): Boolean {
|
fun ResolvedCall<*>.hasInferredReturnType(): Boolean {
|
||||||
if (isNewNotCompleted()) return false
|
if (isNewNotCompleted()) return false
|
||||||
|
|||||||
@@ -511,3 +511,15 @@ fun PsiElement?.unwrapParenthesesLabelsAndAnnotations(): PsiElement? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiElement.unwrapParenthesesLabelsAndAnnotationsDeeply(): PsiElement {
|
||||||
|
var current: PsiElement = this
|
||||||
|
var unwrapped: PsiElement?
|
||||||
|
|
||||||
|
do {
|
||||||
|
unwrapped = current.parent?.unwrapParenthesesLabelsAndAnnotations()
|
||||||
|
current = current.parent
|
||||||
|
} while (unwrapped != current)
|
||||||
|
|
||||||
|
return unwrapped
|
||||||
|
}
|
||||||
|
|||||||
+4
@@ -41,6 +41,10 @@ abstract class ArgumentConstraintPosition<out T>(val argument: T) : ConstraintPo
|
|||||||
override fun toString(): String = "Argument $argument"
|
override fun toString(): String = "Argument $argument"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class CallableReferenceConstraintPosition<out T>(val call: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
|
||||||
|
override fun toString(): String = "Callable reference $call"
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ReceiverConstraintPosition<T>(val argument: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
|
abstract class ReceiverConstraintPosition<T>(val argument: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
|
||||||
override fun toString(): String = "Receiver $argument"
|
override fun toString(): String = "Receiver $argument"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ package org.jetbrains.kotlin.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceResolver
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.NewOverloadingConflictResolver
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.SimpleResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.descriptorUtil.OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION_FQ_NAME
|
||||||
@@ -24,24 +24,116 @@ class KotlinCallResolver(
|
|||||||
private val towerResolver: TowerResolver,
|
private val towerResolver: TowerResolver,
|
||||||
private val kotlinCallCompleter: KotlinCallCompleter,
|
private val kotlinCallCompleter: KotlinCallCompleter,
|
||||||
private val overloadingConflictResolver: NewOverloadingConflictResolver,
|
private val overloadingConflictResolver: NewOverloadingConflictResolver,
|
||||||
private val callableReferenceResolver: CallableReferenceResolver,
|
private val callableReferenceArgumentResolver: CallableReferenceArgumentResolver,
|
||||||
private val callComponents: KotlinCallComponents
|
private val callComponents: KotlinCallComponents
|
||||||
) {
|
) {
|
||||||
fun resolveCall(
|
fun resolveAndCompleteCall(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
resolutionCallbacks: KotlinResolutionCallbacks,
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
kotlinCall: KotlinCall,
|
kotlinCall: KotlinCall,
|
||||||
expectedType: UnwrappedType?,
|
expectedType: UnwrappedType?,
|
||||||
collectAllCandidates: Boolean,
|
collectAllCandidates: Boolean,
|
||||||
createFactoryProviderForInvoke: () -> CandidateFactoryProviderForInvoke<ResolutionCandidate>
|
): CallResolutionResult {
|
||||||
|
val candidateFactory = createFactory(scopeTower, kotlinCall, resolutionCallbacks, expectedType)
|
||||||
|
val candidates = resolveCall(scopeTower, resolutionCallbacks, kotlinCall, collectAllCandidates, candidateFactory)
|
||||||
|
|
||||||
|
if (collectAllCandidates) {
|
||||||
|
return kotlinCallCompleter.createAllCandidatesResult(candidates, expectedType, resolutionCallbacks)
|
||||||
|
}
|
||||||
|
|
||||||
|
return kotlinCallCompleter.runCompletion(candidateFactory, candidates, expectedType, resolutionCallbacks)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveAndCompleteGivenCandidates(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
|
kotlinCall: KotlinCall,
|
||||||
|
expectedType: UnwrappedType?,
|
||||||
|
givenCandidates: Collection<GivenCandidate>,
|
||||||
|
collectAllCandidates: Boolean
|
||||||
): CallResolutionResult {
|
): CallResolutionResult {
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
kotlinCall.checkCallInvariants()
|
kotlinCall.checkCallInvariants()
|
||||||
|
|
||||||
val candidateFactory = SimpleCandidateFactory(
|
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall, resolutionCallbacks)
|
||||||
callComponents, scopeTower, kotlinCall, resolutionCallbacks, callableReferenceResolver
|
val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() }
|
||||||
|
|
||||||
|
if (collectAllCandidates) {
|
||||||
|
val allCandidates = towerResolver.runWithEmptyTowerData(
|
||||||
|
KnownResultProcessor(resolutionCandidates),
|
||||||
|
TowerResolver.AllCandidatesCollector(),
|
||||||
|
useOrder = false
|
||||||
|
)
|
||||||
|
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val candidates = towerResolver.runWithEmptyTowerData(
|
||||||
|
KnownResultProcessor(resolutionCandidates),
|
||||||
|
TowerResolver.SuccessfulResultCollector(),
|
||||||
|
useOrder = true
|
||||||
)
|
)
|
||||||
|
val mostSpecificCandidates = choseMostSpecific(kotlinCall, resolutionCallbacks, candidates)
|
||||||
|
|
||||||
|
return kotlinCallCompleter.runCompletion(candidateFactory, mostSpecificCandidates, expectedType, resolutionCallbacks)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveCallableReferenceArgument(
|
||||||
|
argument: CallableReferenceKotlinCallArgument,
|
||||||
|
expectedType: UnwrappedType?,
|
||||||
|
baseSystem: ConstraintStorage,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks
|
||||||
|
): Collection<CallableReferenceResolutionCandidate> {
|
||||||
|
val scopeTower = callComponents.statelessCallbacks.getScopeTowerForCallableReferenceArgument(argument)
|
||||||
|
val factory = createCallableReferenceCallFactory(scopeTower, argument.call, resolutionCallbacks, expectedType, argument, baseSystem)
|
||||||
|
|
||||||
|
return resolveCall(scopeTower, resolutionCallbacks, argument.call, collectAllCandidates = false, factory)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createCallableReferenceCallFactory(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
kotlinCall: KotlinCall,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
|
expectedType: UnwrappedType?,
|
||||||
|
argument: CallableReferenceKotlinCallArgument? = null,
|
||||||
|
baseSystem: ConstraintStorage? = null
|
||||||
|
): CandidateFactory<CallableReferenceResolutionCandidate> {
|
||||||
|
val resolutionAtom = argument
|
||||||
|
?: CallableReferenceKotlinCall(kotlinCall, resolutionCallbacks.getLhsResult(kotlinCall), kotlinCall.name)
|
||||||
|
|
||||||
|
return CallableReferencesCandidateFactory(resolutionAtom, callComponents, scopeTower, expectedType, baseSystem, resolutionCallbacks)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSimpleCallFactory(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
kotlinCall: KotlinCall,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
|
): CandidateFactory<ResolutionCandidate> = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall, resolutionCallbacks)
|
||||||
|
|
||||||
|
private fun createFactory(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
kotlinCall: KotlinCall,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
|
expectedType: UnwrappedType?
|
||||||
|
): CandidateFactory<ResolutionCandidate> =
|
||||||
|
when (kotlinCall.callKind) {
|
||||||
|
KotlinCallKind.CALLABLE_REFERENCE -> createCallableReferenceCallFactory(scopeTower, kotlinCall, resolutionCallbacks, expectedType)
|
||||||
|
else -> createSimpleCallFactory(scopeTower, kotlinCall, resolutionCallbacks)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <C : ResolutionCandidate> resolveCall(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
|
kotlinCall: KotlinCall,
|
||||||
|
collectAllCandidates: Boolean,
|
||||||
|
candidateFactory: CandidateFactory<C>,
|
||||||
|
): Collection<C> {
|
||||||
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
|
kotlinCall.checkCallInvariants()
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
val processor = when (kotlinCall.callKind) {
|
val processor = when (kotlinCall.callKind) {
|
||||||
KotlinCallKind.VARIABLE -> {
|
KotlinCallKind.VARIABLE -> {
|
||||||
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
|
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
|
||||||
@@ -51,9 +143,12 @@ class KotlinCallResolver(
|
|||||||
scopeTower,
|
scopeTower,
|
||||||
kotlinCall.name,
|
kotlinCall.name,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
createFactoryProviderForInvoke(),
|
resolutionCallbacks.getCandidateFactoryForInvoke(scopeTower, kotlinCall),
|
||||||
kotlinCall.explicitReceiver?.receiver
|
kotlinCall.explicitReceiver?.receiver
|
||||||
)
|
) as ScopeTowerProcessor<C>
|
||||||
|
}
|
||||||
|
KotlinCallKind.CALLABLE_REFERENCE -> {
|
||||||
|
createCallableReferenceProcessor(candidateFactory as CallableReferencesCandidateFactory) as ScopeTowerProcessor<C>
|
||||||
}
|
}
|
||||||
KotlinCallKind.INVOKE -> {
|
KotlinCallKind.INVOKE -> {
|
||||||
createProcessorWithReceiverValueOrEmpty(kotlinCall.explicitReceiver?.receiver) {
|
createProcessorWithReceiverValueOrEmpty(kotlinCall.explicitReceiver?.receiver) {
|
||||||
@@ -69,8 +164,7 @@ class KotlinCallResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (collectAllCandidates) {
|
if (collectAllCandidates) {
|
||||||
val allCandidates = towerResolver.collectAllCandidates(scopeTower, processor, kotlinCall.name)
|
return towerResolver.collectAllCandidates(scopeTower, processor, kotlinCall.name)
|
||||||
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidates = towerResolver.runResolve(
|
val candidates = towerResolver.runResolve(
|
||||||
@@ -80,73 +174,55 @@ class KotlinCallResolver(
|
|||||||
name = kotlinCall.name
|
name = kotlinCall.name
|
||||||
)
|
)
|
||||||
|
|
||||||
return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates)
|
@Suppress("UNCHECKED_CAST")
|
||||||
}
|
return choseMostSpecific(kotlinCall, resolutionCallbacks, candidates) as Set<C>
|
||||||
|
|
||||||
fun resolveGivenCandidates(
|
|
||||||
scopeTower: ImplicitScopeTower,
|
|
||||||
resolutionCallbacks: KotlinResolutionCallbacks,
|
|
||||||
kotlinCall: KotlinCall,
|
|
||||||
expectedType: UnwrappedType?,
|
|
||||||
givenCandidates: Collection<GivenCandidate>,
|
|
||||||
collectAllCandidates: Boolean
|
|
||||||
): CallResolutionResult {
|
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
|
||||||
|
|
||||||
kotlinCall.checkCallInvariants()
|
|
||||||
val candidateFactory = SimpleCandidateFactory(
|
|
||||||
callComponents, scopeTower, kotlinCall, resolutionCallbacks, callableReferenceResolver
|
|
||||||
)
|
|
||||||
|
|
||||||
val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() }
|
|
||||||
|
|
||||||
if (collectAllCandidates) {
|
|
||||||
val allCandidates = towerResolver.runWithEmptyTowerData(
|
|
||||||
KnownResultProcessor(resolutionCandidates),
|
|
||||||
TowerResolver.AllCandidatesCollector(),
|
|
||||||
useOrder = false
|
|
||||||
)
|
|
||||||
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
|
|
||||||
|
|
||||||
}
|
|
||||||
val candidates = towerResolver.runWithEmptyTowerData(
|
|
||||||
KnownResultProcessor(resolutionCandidates),
|
|
||||||
TowerResolver.SuccessfulResultCollector(),
|
|
||||||
useOrder = true
|
|
||||||
)
|
|
||||||
return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun choseMostSpecific(
|
private fun choseMostSpecific(
|
||||||
candidateFactory: SimpleCandidateFactory,
|
kotlinCall: KotlinCall,
|
||||||
resolutionCallbacks: KotlinResolutionCallbacks,
|
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
expectedType: UnwrappedType?,
|
|
||||||
candidates: Collection<ResolutionCandidate>
|
candidates: Collection<ResolutionCandidate>
|
||||||
): CallResolutionResult {
|
): Set<ResolutionCandidate> {
|
||||||
var refinedCandidates = candidates
|
var refinedCandidates = candidates
|
||||||
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.RefinedSamAdaptersPriority)) {
|
|
||||||
|
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.RefinedSamAdaptersPriority) && kotlinCall.callKind != KotlinCallKind.CALLABLE_REFERENCE) {
|
||||||
val nonSynthesized = candidates.filter { !it.resolvedCall.candidateDescriptor.isSynthesized }
|
val nonSynthesized = candidates.filter { !it.resolvedCall.candidateDescriptor.isSynthesized }
|
||||||
if (!nonSynthesized.isEmpty()) {
|
if (nonSynthesized.isNotEmpty()) {
|
||||||
refinedCandidates = nonSynthesized
|
refinedCandidates = nonSynthesized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates(
|
var maximallySpecificCandidates = if (kotlinCall.callKind == KotlinCallKind.CALLABLE_REFERENCE) {
|
||||||
refinedCandidates,
|
@Suppress("UNCHECKED_CAST")
|
||||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
callableReferenceArgumentResolver.callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates(
|
||||||
discriminateGenerics = true // todo
|
refinedCandidates as Collection<CallableReferenceResolutionCandidate>,
|
||||||
)
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
|
discriminateGenerics = true
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
overloadingConflictResolver.chooseMaximallySpecificCandidates(
|
||||||
|
refinedCandidates,
|
||||||
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
|
discriminateGenerics = true // todo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
maximallySpecificCandidates.size > 1 &&
|
maximallySpecificCandidates.size > 1 &&
|
||||||
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.OverloadResolutionByLambdaReturnType) &&
|
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.OverloadResolutionByLambdaReturnType) &&
|
||||||
candidates.all { resolutionCallbacks.inferenceSession.shouldRunCompletion(it) }
|
candidates.all { resolutionCallbacks.inferenceSession.shouldRunCompletion(it) } &&
|
||||||
|
kotlinCall.callKind != KotlinCallKind.CALLABLE_REFERENCE
|
||||||
) {
|
) {
|
||||||
val candidatesWithAnnotation =
|
val candidatesWithAnnotation = candidates.filter {
|
||||||
candidates.filter { it.resolvedCall.candidateDescriptor.annotations.hasAnnotation(OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION_FQ_NAME) }
|
it.resolvedCall.candidateDescriptor.annotations.hasAnnotation(OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION_FQ_NAME)
|
||||||
|
}.toSet()
|
||||||
val candidatesWithoutAnnotation = candidates - candidatesWithAnnotation
|
val candidatesWithoutAnnotation = candidates - candidatesWithAnnotation
|
||||||
if (candidatesWithAnnotation.isNotEmpty()) {
|
if (candidatesWithAnnotation.isNotEmpty()) {
|
||||||
val newCandidates = kotlinCallCompleter.chooseCandidateRegardingOverloadResolutionByLambdaReturnType(maximallySpecificCandidates, resolutionCallbacks)
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val newCandidates = kotlinCallCompleter.chooseCandidateRegardingOverloadResolutionByLambdaReturnType(
|
||||||
|
maximallySpecificCandidates as Set<SimpleResolutionCandidate>,
|
||||||
|
resolutionCallbacks
|
||||||
|
)
|
||||||
maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates(
|
maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates(
|
||||||
newCandidates,
|
newCandidates,
|
||||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
@@ -160,7 +236,6 @@ class KotlinCallResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks)
|
return maximallySpecificCandidates
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.isInapplicable
|
||||||
|
|
||||||
|
class CallableReferenceArgumentResolver(val callableReferenceOverloadConflictResolver: CallableReferenceOverloadConflictResolver) {
|
||||||
|
fun processCallableReferenceArgument(
|
||||||
|
csBuilder: ConstraintSystemBuilder,
|
||||||
|
resolvedAtom: ResolvedCallableReferenceArgumentAtom,
|
||||||
|
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||||
|
resolutionCallbacks: KotlinResolutionCallbacks
|
||||||
|
) {
|
||||||
|
val argument = resolvedAtom.atom
|
||||||
|
val expectedType = resolvedAtom.expectedType?.let { (csBuilder.buildCurrentSubstitutor() as NewTypeSubstitutor).safeSubstitute(it) }
|
||||||
|
val candidates = resolutionCallbacks.resolveCallableReferenceArgument(resolvedAtom.atom, expectedType, csBuilder.currentStorage())
|
||||||
|
|
||||||
|
if (candidates.size > 1 && resolvedAtom is EagerCallableReferenceAtom) {
|
||||||
|
if (candidates.all { it.resultingApplicability.isInapplicable }) {
|
||||||
|
diagnosticsHolder.addDiagnostic(CallableReferenceCallCandidatesAmbiguity(argument, candidates))
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedAtom.setAnalyzedResults(
|
||||||
|
candidate = null,
|
||||||
|
subResolvedAtoms = listOf(resolvedAtom.transformToPostponed())
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val chosenCandidate = candidates.singleOrNull()
|
||||||
|
if (chosenCandidate != null) {
|
||||||
|
val toFreshSubstitutor = CreateFreshVariablesSubstitutor.createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||||
|
chosenCandidate.candidate,
|
||||||
|
csBuilder
|
||||||
|
)
|
||||||
|
chosenCandidate.addConstraints(csBuilder, toFreshSubstitutor, callableReference = argument)
|
||||||
|
chosenCandidate.diagnostics.forEach {
|
||||||
|
val transformedDiagnostic = when (it) {
|
||||||
|
is CompatibilityWarning -> CompatibilityWarningOnArgument(argument, it.candidate)
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
diagnosticsHolder.addDiagnostic(transformedDiagnostic)
|
||||||
|
}
|
||||||
|
chosenCandidate.freshVariablesSubstitutor = toFreshSubstitutor
|
||||||
|
} else {
|
||||||
|
if (candidates.isEmpty()) {
|
||||||
|
diagnosticsHolder.addDiagnostic(NoneCallableReferenceCallCandidates(argument))
|
||||||
|
} else {
|
||||||
|
diagnosticsHolder.addDiagnostic(CallableReferenceCallCandidatesAmbiguity(argument, candidates))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo -- create this inside CallableReferencesCandidateFactory
|
||||||
|
val subKtArguments = listOfNotNull(buildResolvedKtArgument(argument.lhsResult))
|
||||||
|
|
||||||
|
resolvedAtom.setAnalyzedResults(chosenCandidate, subKtArguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildResolvedKtArgument(lhsResult: LHSResult): ResolvedAtom? {
|
||||||
|
if (lhsResult !is LHSResult.Expression) return null
|
||||||
|
return when (val lshCallArgument = lhsResult.lshCallArgument) {
|
||||||
|
is SubKotlinCallArgument -> lshCallArgument.callResult
|
||||||
|
is ExpressionKotlinCallArgument -> ResolvedExpressionAtom(lshCallArgument)
|
||||||
|
else -> unexpectedArgument(lshCallArgument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||||
|
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||||
|
import org.jetbrains.kotlin.util.CancellationChecker
|
||||||
|
|
||||||
|
class CallableReferenceOverloadConflictResolver(
|
||||||
|
builtIns: KotlinBuiltIns,
|
||||||
|
module: ModuleDescriptor,
|
||||||
|
specificityComparator: TypeSpecificityComparator,
|
||||||
|
platformOverloadsSpecificityComparator: PlatformOverloadsSpecificityComparator,
|
||||||
|
cancellationChecker: CancellationChecker,
|
||||||
|
statelessCallbacks: KotlinResolutionStatelessCallbacks,
|
||||||
|
constraintInjector: ConstraintInjector,
|
||||||
|
kotlinTypeRefiner: KotlinTypeRefiner,
|
||||||
|
) : OverloadingConflictResolver<CallableReferenceResolutionCandidate>(
|
||||||
|
builtIns,
|
||||||
|
module,
|
||||||
|
specificityComparator,
|
||||||
|
platformOverloadsSpecificityComparator,
|
||||||
|
cancellationChecker,
|
||||||
|
{ it.candidate },
|
||||||
|
{ statelessCallbacks.createConstraintSystemForOverloadResolution(constraintInjector, builtIns) },
|
||||||
|
Companion::createFlatSignature,
|
||||||
|
{ null },
|
||||||
|
{ statelessCallbacks.isDescriptorFromSource(it) },
|
||||||
|
null,
|
||||||
|
kotlinTypeRefiner,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
private fun createFlatSignature(candidate: CallableReferenceResolutionCandidate) =
|
||||||
|
FlatSignature.createFromReflectionType(
|
||||||
|
candidate, candidate.candidate, candidate.numDefaults, hasBoundExtensionReceiver = candidate.extensionReceiver != null,
|
||||||
|
candidate.reflectionCandidateType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-44
@@ -6,32 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.*
|
import org.jetbrains.kotlin.builtins.*
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CreateFreshVariablesSubstitutor.createToFreshVariableSubstitutorAndAddInitialConstraints
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPositionImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.DISPATCH_RECEIVER
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.EXTENSION_RECEIVER
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.captureFromExpression
|
import org.jetbrains.kotlin.types.checker.captureFromExpression
|
||||||
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
||||||
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
|
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
|
||||||
|
|
||||||
sealed class CallableReceiver(val receiver: ReceiverValueWithSmartCastInfo) {
|
sealed class CallableReceiver(val receiver: ReceiverValueWithSmartCastInfo) {
|
||||||
class UnboundReference(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
class UnboundReference(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||||
@@ -40,10 +27,6 @@ sealed class CallableReceiver(val receiver: ReceiverValueWithSmartCastInfo) {
|
|||||||
class ExplicitValueReceiver(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
class ExplicitValueReceiver(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo investigate similar code in CheckVisibility
|
|
||||||
private val CallableReceiver.asReceiverValueForVisibilityChecks: ReceiverValue
|
|
||||||
get() = receiver.receiverValue
|
|
||||||
|
|
||||||
class CallableReferenceAdaptation(
|
class CallableReferenceAdaptation(
|
||||||
val argumentTypes: Array<KotlinType>,
|
val argumentTypes: Array<KotlinType>,
|
||||||
val coercionStrategy: CoercionStrategy,
|
val coercionStrategy: CoercionStrategy,
|
||||||
@@ -90,41 +73,31 @@ fun createCallableReferenceProcessor(factory: CallableReferencesCandidateFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConstraintSystemOperation.checkCallableReference(
|
fun CallableReferenceResolutionCandidate.addConstraints(
|
||||||
argument: CallableReferenceKotlinCallArgument,
|
constraintSystem: ConstraintSystemOperation,
|
||||||
dispatchReceiver: CallableReceiver?,
|
substitutor: FreshVariableNewTypeSubstitutor,
|
||||||
extensionReceiver: CallableReceiver?,
|
callableReference: CallableReferenceResolutionAtom
|
||||||
candidateDescriptor: CallableDescriptor,
|
) {
|
||||||
reflectionCandidateType: UnwrappedType,
|
val position = when (callableReference) {
|
||||||
expectedType: UnwrappedType?,
|
is CallableReferenceKotlinCallArgument -> ArgumentConstraintPositionImpl(callableReference)
|
||||||
ownerDescriptor: DeclarationDescriptor
|
is CallableReferenceKotlinCall -> CallableReferenceConstraintPositionImpl(callableReference)
|
||||||
): Pair<FreshVariableNewTypeSubstitutor, KotlinCallDiagnostic?> {
|
|
||||||
val position = ArgumentConstraintPositionImpl(argument)
|
|
||||||
|
|
||||||
val toFreshSubstitutor = createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, this)
|
|
||||||
|
|
||||||
if (!ErrorUtils.isError(candidateDescriptor)) {
|
|
||||||
addReceiverConstraint(toFreshSubstitutor, dispatchReceiver, candidateDescriptor.dispatchReceiverParameter, position)
|
|
||||||
addReceiverConstraint(toFreshSubstitutor, extensionReceiver, candidateDescriptor.extensionReceiverParameter, position)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedType != null && !hasContradiction) {
|
if (!ErrorUtils.isError(candidate)) {
|
||||||
addSubtypeConstraint(toFreshSubstitutor.safeSubstitute(reflectionCandidateType), expectedType, position)
|
constraintSystem.addReceiverConstraint(substitutor, dispatchReceiver, candidate.dispatchReceiverParameter, position)
|
||||||
|
constraintSystem.addReceiverConstraint(substitutor, extensionReceiver, candidate.extensionReceiverParameter, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
val invisibleMember = DescriptorVisibilities.findInvisibleMember(
|
if (expectedType != null && !TypeUtils.noExpectedType(expectedType) && !constraintSystem.hasContradiction) {
|
||||||
dispatchReceiver?.asReceiverValueForVisibilityChecks,
|
constraintSystem.addSubtypeConstraint(substitutor.safeSubstitute(reflectionCandidateType), expectedType, position)
|
||||||
candidateDescriptor, ownerDescriptor
|
}
|
||||||
)
|
|
||||||
return toFreshSubstitutor to invisibleMember?.let(::VisibilityError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun ConstraintSystemOperation.addReceiverConstraint(
|
private fun ConstraintSystemOperation.addReceiverConstraint(
|
||||||
toFreshSubstitutor: FreshVariableNewTypeSubstitutor,
|
toFreshSubstitutor: FreshVariableNewTypeSubstitutor,
|
||||||
receiverArgument: CallableReceiver?,
|
receiverArgument: CallableReceiver?,
|
||||||
receiverParameter: ReceiverParameterDescriptor?,
|
receiverParameter: ReceiverParameterDescriptor?,
|
||||||
position: ArgumentConstraintPositionImpl
|
position: ConstraintPosition
|
||||||
) {
|
) {
|
||||||
if (receiverArgument == null || receiverParameter == null) {
|
if (receiverArgument == null || receiverParameter == null) {
|
||||||
assert(receiverArgument == null) { "Receiver argument should be null if parameter is: $receiverArgument" }
|
assert(receiverArgument == null) { "Receiver argument should be null if parameter is: $receiverArgument" }
|
||||||
|
|||||||
-162
@@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 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.calls.components
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.TowerResolver
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isInapplicable
|
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
|
||||||
import org.jetbrains.kotlin.util.CancellationChecker
|
|
||||||
|
|
||||||
|
|
||||||
class CallableReferenceOverloadConflictResolver(
|
|
||||||
builtIns: KotlinBuiltIns,
|
|
||||||
module: ModuleDescriptor,
|
|
||||||
specificityComparator: TypeSpecificityComparator,
|
|
||||||
platformOverloadsSpecificityComparator: PlatformOverloadsSpecificityComparator,
|
|
||||||
cancellationChecker: CancellationChecker,
|
|
||||||
statelessCallbacks: KotlinResolutionStatelessCallbacks,
|
|
||||||
constraintInjector: ConstraintInjector,
|
|
||||||
kotlinTypeRefiner: KotlinTypeRefiner,
|
|
||||||
) : OverloadingConflictResolver<CallableReferenceCandidate>(
|
|
||||||
builtIns,
|
|
||||||
module,
|
|
||||||
specificityComparator,
|
|
||||||
platformOverloadsSpecificityComparator,
|
|
||||||
cancellationChecker,
|
|
||||||
{ it.candidate },
|
|
||||||
{ statelessCallbacks.createConstraintSystemForOverloadResolution(constraintInjector, builtIns) },
|
|
||||||
Companion::createFlatSignature,
|
|
||||||
{ null },
|
|
||||||
{ statelessCallbacks.isDescriptorFromSource(it) },
|
|
||||||
null,
|
|
||||||
kotlinTypeRefiner,
|
|
||||||
) {
|
|
||||||
companion object {
|
|
||||||
private fun createFlatSignature(candidate: CallableReferenceCandidate) =
|
|
||||||
FlatSignature.createFromReflectionType(
|
|
||||||
candidate, candidate.candidate, candidate.numDefaults, hasBoundExtensionReceiver = candidate.extensionReceiver != null,
|
|
||||||
candidate.reflectionCandidateType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class CallableReferenceResolver(
|
|
||||||
private val towerResolver: TowerResolver,
|
|
||||||
private val callableReferenceOverloadConflictResolver: CallableReferenceOverloadConflictResolver,
|
|
||||||
private val callComponents: KotlinCallComponents
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun processCallableReferenceArgument(
|
|
||||||
csBuilder: ConstraintSystemBuilder,
|
|
||||||
resolvedAtom: ResolvedCallableReferenceAtom,
|
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
|
||||||
resolutionCallbacks: KotlinResolutionCallbacks
|
|
||||||
) {
|
|
||||||
val argument = resolvedAtom.atom
|
|
||||||
val expectedType = resolvedAtom.expectedType?.let { (csBuilder.buildCurrentSubstitutor() as NewTypeSubstitutor).safeSubstitute(it) }
|
|
||||||
|
|
||||||
val scopeTower = callComponents.statelessCallbacks.getScopeTowerForCallableReferenceArgument(argument)
|
|
||||||
val candidates = runRHSResolution(scopeTower, argument, expectedType, csBuilder, resolutionCallbacks) { checkCallableReference ->
|
|
||||||
csBuilder.runTransaction { checkCallableReference(this); false }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (candidates.size > 1 && resolvedAtom is EagerCallableReferenceAtom) {
|
|
||||||
if (candidates.all { it.resultingApplicability.isInapplicable }) {
|
|
||||||
diagnosticsHolder.addDiagnostic(CallableReferenceCandidatesAmbiguity(argument, candidates))
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedAtom.setAnalyzedResults(
|
|
||||||
candidate = null,
|
|
||||||
subResolvedAtoms = listOf(resolvedAtom.transformToPostponed())
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val chosenCandidate = candidates.singleOrNull()
|
|
||||||
if (chosenCandidate != null) {
|
|
||||||
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
|
|
||||||
csBuilder.checkCallableReference(
|
|
||||||
argument, dispatchReceiver, extensionReceiver, candidate,
|
|
||||||
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor
|
|
||||||
)
|
|
||||||
}
|
|
||||||
diagnosticsHolder.addDiagnosticIfNotNull(diagnostic)
|
|
||||||
chosenCandidate.diagnostics.forEach {
|
|
||||||
val transformedDiagnostic = when (it) {
|
|
||||||
is CompatibilityWarning -> CompatibilityWarningOnArgument(argument, it.candidate)
|
|
||||||
else -> it
|
|
||||||
}
|
|
||||||
diagnosticsHolder.addDiagnostic(transformedDiagnostic)
|
|
||||||
}
|
|
||||||
chosenCandidate.freshSubstitutor = toFreshSubstitutor
|
|
||||||
} else {
|
|
||||||
if (candidates.isEmpty()) {
|
|
||||||
diagnosticsHolder.addDiagnostic(NoneCallableReferenceCandidates(argument))
|
|
||||||
} else {
|
|
||||||
diagnosticsHolder.addDiagnostic(CallableReferenceCandidatesAmbiguity(argument, candidates))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo -- create this inside CallableReferencesCandidateFactory
|
|
||||||
val subKtArguments = listOfNotNull(buildResolvedKtArgument(argument.lhsResult))
|
|
||||||
|
|
||||||
resolvedAtom.setAnalyzedResults(chosenCandidate, subKtArguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildResolvedKtArgument(lhsResult: LHSResult): ResolvedAtom? {
|
|
||||||
if (lhsResult !is LHSResult.Expression) return null
|
|
||||||
val lshCallArgument = lhsResult.lshCallArgument
|
|
||||||
return when (lshCallArgument) {
|
|
||||||
is SubKotlinCallArgument -> lshCallArgument.callResult
|
|
||||||
is ExpressionKotlinCallArgument -> ResolvedExpressionAtom(lshCallArgument)
|
|
||||||
else -> unexpectedArgument(lshCallArgument)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runRHSResolution(
|
|
||||||
scopeTower: ImplicitScopeTower,
|
|
||||||
callableReference: CallableReferenceKotlinCallArgument,
|
|
||||||
expectedType: UnwrappedType?, // this type can have not fixed type variable inside
|
|
||||||
csBuilder: ConstraintSystemBuilder,
|
|
||||||
resolutionCallbacks: KotlinResolutionCallbacks,
|
|
||||||
compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit // you can run anything throw this operation and all this operation will be rolled back
|
|
||||||
): Set<CallableReferenceCandidate> {
|
|
||||||
val factory = CallableReferencesCandidateFactory(
|
|
||||||
callableReference, callComponents, scopeTower, compatibilityChecker, expectedType, csBuilder, resolutionCallbacks
|
|
||||||
)
|
|
||||||
val processor = createCallableReferenceProcessor(factory)
|
|
||||||
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = true, name = callableReference.rhsName)
|
|
||||||
return callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates(
|
|
||||||
candidates,
|
|
||||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
|
||||||
discriminateGenerics = false // we can't specify generics explicitly for callable references
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+2
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
|
||||||
@@ -42,7 +43,7 @@ class CompletionModeCalculator {
|
|||||||
if (returnType == null) return ConstraintSystemCompletionMode.PARTIAL
|
if (returnType == null) return ConstraintSystemCompletionMode.PARTIAL
|
||||||
|
|
||||||
// Full if return type for call has no type variables
|
// Full if return type for call has no type variables
|
||||||
if (csBuilder.isProperType(returnType)) return ConstraintSystemCompletionMode.FULL
|
if (getSystem().getBuilder().isProperType(returnType)) return ConstraintSystemCompletionMode.FULL
|
||||||
|
|
||||||
// For nested call with variables in return type check possibility of full completion
|
// For nested call with variables in return type check possibility of full completion
|
||||||
return CalculatorForNestedCall(
|
return CalculatorForNestedCall(
|
||||||
|
|||||||
+17
-1
@@ -11,10 +11,15 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.SimpleResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateFactoryProviderForInvoke
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -37,7 +42,7 @@ interface KotlinResolutionStatelessCallbacks {
|
|||||||
|
|
||||||
fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean
|
fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean
|
||||||
fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower
|
fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower
|
||||||
fun getVariableCandidateIfInvoke(functionCall: KotlinCall): KotlinResolutionCandidate?
|
fun getVariableCandidateIfInvoke(functionCall: KotlinCall): ResolutionCandidate?
|
||||||
fun isBuilderInferenceCall(argument: KotlinCallArgument, parameter: ValueParameterDescriptor): Boolean
|
fun isBuilderInferenceCall(argument: KotlinCallArgument, parameter: ValueParameterDescriptor): Boolean
|
||||||
fun isApplicableCallForBuilderInference(descriptor: CallableDescriptor, languageVersionSettings: LanguageVersionSettings): Boolean
|
fun isApplicableCallForBuilderInference(descriptor: CallableDescriptor, languageVersionSettings: LanguageVersionSettings): Boolean
|
||||||
|
|
||||||
@@ -77,6 +82,17 @@ interface KotlinResolutionCallbacks {
|
|||||||
stubsForPostponedVariables: Map<NewTypeVariable, StubTypeForBuilderInference>,
|
stubsForPostponedVariables: Map<NewTypeVariable, StubTypeForBuilderInference>,
|
||||||
): ReturnArgumentsAnalysisResult
|
): ReturnArgumentsAnalysisResult
|
||||||
|
|
||||||
|
fun getCandidateFactoryForInvoke(
|
||||||
|
scopeTower: ImplicitScopeTower,
|
||||||
|
kotlinCall: KotlinCall,
|
||||||
|
): CandidateFactoryProviderForInvoke<ResolutionCandidate>
|
||||||
|
|
||||||
|
fun resolveCallableReferenceArgument(
|
||||||
|
argument: CallableReferenceKotlinCallArgument,
|
||||||
|
expectedType: UnwrappedType?,
|
||||||
|
baseSystem: ConstraintStorage,
|
||||||
|
): Collection<CallableReferenceResolutionCandidate>
|
||||||
|
|
||||||
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
|
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
|
||||||
|
|
||||||
fun isCompileTimeConstant(resolvedAtom: ResolvedCallAtom, expectedType: UnwrappedType): Boolean
|
fun isCompileTimeConstant(resolvedAtom: ResolvedCallAtom, expectedType: UnwrappedType): Boolean
|
||||||
|
|||||||
+29
-14
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraint
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPositionImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPositionImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateFactory
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
|
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -40,22 +41,27 @@ class KotlinCallCompleter(
|
|||||||
resolutionCallbacks: KotlinResolutionCallbacks
|
resolutionCallbacks: KotlinResolutionCallbacks
|
||||||
): CallResolutionResult {
|
): CallResolutionResult {
|
||||||
val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder()
|
val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder()
|
||||||
|
|
||||||
when {
|
when {
|
||||||
candidates.isEmpty() -> diagnosticHolder.addDiagnostic(NoneCandidatesCallDiagnostic(factory.kotlinCall))
|
candidates.isEmpty() -> diagnosticHolder.addDiagnostic(NoneCandidatesCallDiagnostic())
|
||||||
candidates.size > 1 -> diagnosticHolder.addDiagnostic(ManyCandidatesCallDiagnostic(factory.kotlinCall, candidates))
|
candidates.size > 1 -> diagnosticHolder.addDiagnostic(ManyCandidatesCallDiagnostic(candidates))
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidate = prepareCandidateForCompletion(factory, candidates, resolutionCallbacks)
|
val candidate = prepareCandidateForCompletion(factory, candidates, resolutionCallbacks)
|
||||||
val returnType = candidate.substitutedReturnType()
|
val resultType = when (candidate) {
|
||||||
|
is SimpleResolutionCandidate -> {
|
||||||
|
candidate.checkSamWithVararg(diagnosticHolder)
|
||||||
|
candidate.substitutedReturnType().also {
|
||||||
|
candidate.addExpectedTypeConstraint(it, expectedType)
|
||||||
|
candidate.addExpectedTypeFromCastConstraint(it, resolutionCallbacks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is CallableReferenceResolutionCandidate -> candidate.substitutedReflectionType()
|
||||||
|
}
|
||||||
|
|
||||||
candidate.addExpectedTypeConstraint(returnType, expectedType)
|
val completionMode = CompletionModeCalculator.computeCompletionMode(
|
||||||
candidate.addExpectedTypeFromCastConstraint(returnType, resolutionCallbacks)
|
candidate, expectedType, resultType, trivialConstraintTypeInferenceOracle, resolutionCallbacks.inferenceSession
|
||||||
candidate.checkSamWithVararg(diagnosticHolder)
|
)
|
||||||
|
|
||||||
val completionMode =
|
|
||||||
CompletionModeCalculator.computeCompletionMode(
|
|
||||||
candidate, expectedType, returnType, trivialConstraintTypeInferenceOracle, resolutionCallbacks.inferenceSession
|
|
||||||
)
|
|
||||||
|
|
||||||
return when (completionMode) {
|
return when (completionMode) {
|
||||||
ConstraintSystemCompletionMode.FULL -> {
|
ConstraintSystemCompletionMode.FULL -> {
|
||||||
@@ -151,7 +157,7 @@ class KotlinCallCompleter(
|
|||||||
|
|
||||||
private fun SimpleResolutionCandidate.getInputTypesOfLambdaAtom(atom: ResolvedLambdaAtom): List<UnwrappedType> {
|
private fun SimpleResolutionCandidate.getInputTypesOfLambdaAtom(atom: ResolvedLambdaAtom): List<UnwrappedType> {
|
||||||
val result = mutableListOf<UnwrappedType>()
|
val result = mutableListOf<UnwrappedType>()
|
||||||
val substitutor = csBuilder.buildCurrentSubstitutor()
|
val substitutor = getSystem().getBuilder().buildCurrentSubstitutor()
|
||||||
val ctx = getSystem().asConstraintSystemCompleterContext()
|
val ctx = getSystem().asConstraintSystemCompleterContext()
|
||||||
for (inputType in atom.inputTypes) {
|
for (inputType in atom.inputTypes) {
|
||||||
result += substitutor.safeSubstitute(ctx, inputType) as UnwrappedType
|
result += substitutor.safeSubstitute(ctx, inputType) as UnwrappedType
|
||||||
@@ -198,7 +204,7 @@ class KotlinCallCompleter(
|
|||||||
collectAllCandidatesMode = true
|
collectAllCandidatesMode = true
|
||||||
)
|
)
|
||||||
|
|
||||||
CandidateWithDiagnostics(candidate, diagnosticsHolder.getDiagnostics() + candidate.diagnosticsFromResolutionParts)
|
CandidateWithDiagnostics(candidate, diagnosticsHolder.getDiagnostics() + candidate.diagnostics)
|
||||||
}
|
}
|
||||||
return AllCandidatesResolutionResult(completedCandidates)
|
return AllCandidatesResolutionResult(completedCandidates)
|
||||||
}
|
}
|
||||||
@@ -264,6 +270,10 @@ class KotlinCallCompleter(
|
|||||||
return candidate ?: factory.createErrorCandidate().forceResolution()
|
return candidate ?: factory.createErrorCandidate().forceResolution()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun CallableReferenceResolutionCandidate.substitutedReflectionType(): UnwrappedType {
|
||||||
|
return resolvedCall.freshVariablesSubstitutor.safeSubstitute(this.reflectionCandidateType)
|
||||||
|
}
|
||||||
|
|
||||||
private fun ResolutionCandidate.substitutedReturnType(): UnwrappedType? {
|
private fun ResolutionCandidate.substitutedReturnType(): UnwrappedType? {
|
||||||
val returnType = resolvedCall.candidateDescriptor.returnType?.unwrap() ?: return null
|
val returnType = resolvedCall.candidateDescriptor.returnType?.unwrap() ?: return null
|
||||||
return resolvedCall.freshVariablesSubstitutor.safeSubstitute(returnType)
|
return resolvedCall.freshVariablesSubstitutor.safeSubstitute(returnType)
|
||||||
@@ -276,6 +286,8 @@ class KotlinCallCompleter(
|
|||||||
if (returnType == null) return
|
if (returnType == null) return
|
||||||
if (expectedType == null || (TypeUtils.noExpectedType(expectedType) && expectedType !== TypeUtils.UNIT_EXPECTED_TYPE)) return
|
if (expectedType == null || (TypeUtils.noExpectedType(expectedType) && expectedType !== TypeUtils.UNIT_EXPECTED_TYPE)) return
|
||||||
|
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
|
|
||||||
when {
|
when {
|
||||||
csBuilder.currentStorage().notFixedTypeVariables.isEmpty() -> {
|
csBuilder.currentStorage().notFixedTypeVariables.isEmpty() -> {
|
||||||
// This is needed to avoid multiple mismatch errors as we type check resulting type against expected one later
|
// This is needed to avoid multiple mismatch errors as we type check resulting type against expected one later
|
||||||
@@ -304,7 +316,10 @@ class KotlinCallCompleter(
|
|||||||
) {
|
) {
|
||||||
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ExpectedTypeFromCast)) return
|
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ExpectedTypeFromCast)) return
|
||||||
if (returnType == null) return
|
if (returnType == null) return
|
||||||
|
|
||||||
val expectedType = resolutionCallbacks.getExpectedTypeFromAsExpressionAndRecordItInTrace(resolvedCall) ?: return
|
val expectedType = resolutionCallbacks.getExpectedTypeFromAsExpressionAndRecordItInTrace(resolvedCall) ?: return
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
|
|
||||||
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPositionImpl(resolvedCall.atom))
|
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPositionImpl(resolvedCall.atom))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +329,7 @@ class KotlinCallCompleter(
|
|||||||
forwardToInferenceSession: Boolean = false
|
forwardToInferenceSession: Boolean = false
|
||||||
): CallResolutionResult {
|
): CallResolutionResult {
|
||||||
val systemStorage = getSystem().asReadOnlyStorage()
|
val systemStorage = getSystem().asReadOnlyStorage()
|
||||||
val allDiagnostics = diagnosticsHolder.getDiagnostics() + diagnosticsFromResolutionParts
|
val allDiagnostics = diagnosticsHolder.getDiagnostics() + diagnostics
|
||||||
|
|
||||||
if (isErrorCandidate()) {
|
if (isErrorCandidate()) {
|
||||||
return ErrorCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
|
return ErrorCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
|
||||||
|
|||||||
+5
-3
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
class PostponedArgumentsAnalyzer(
|
class PostponedArgumentsAnalyzer(
|
||||||
private val callableReferenceResolver: CallableReferenceResolver,
|
private val callableReferenceArgumentResolver: CallableReferenceArgumentResolver,
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -49,8 +49,10 @@ class PostponedArgumentsAnalyzer(
|
|||||||
diagnosticsHolder
|
diagnosticsHolder
|
||||||
)
|
)
|
||||||
|
|
||||||
is ResolvedCallableReferenceAtom ->
|
is ResolvedCallableReferenceArgumentAtom ->
|
||||||
callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), argument, diagnosticsHolder, resolutionCallbacks)
|
callableReferenceArgumentResolver.processCallableReferenceArgument(
|
||||||
|
c.getBuilder(), argument, diagnosticsHolder, resolutionCallbacks
|
||||||
|
)
|
||||||
|
|
||||||
is ResolvedCollectionLiteralAtom -> TODO("Not supported")
|
is ResolvedCollectionLiteralAtom -> TODO("Not supported")
|
||||||
|
|
||||||
|
|||||||
+26
-6
@@ -119,6 +119,7 @@ internal object NoArguments : ResolutionPart() {
|
|||||||
|
|
||||||
internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||||
override fun ResolutionCandidate.process(workIndex: Int) {
|
override fun ResolutionCandidate.process(workIndex: Int) {
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
val toFreshVariables =
|
val toFreshVariables =
|
||||||
if (candidateDescriptor.typeParameters.isEmpty())
|
if (candidateDescriptor.typeParameters.isEmpty())
|
||||||
FreshVariableNewTypeSubstitutor.Empty
|
FreshVariableNewTypeSubstitutor.Empty
|
||||||
@@ -126,7 +127,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
|||||||
createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, csBuilder)
|
createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, csBuilder)
|
||||||
|
|
||||||
val knownTypeParametersSubstitutor = knownTypeParametersResultingSubstitutor?.let {
|
val knownTypeParametersSubstitutor = knownTypeParametersResultingSubstitutor?.let {
|
||||||
createKnownParametersFromFreshVariablesSubstitutor(toFreshVariables, knownTypeParametersResultingSubstitutor)
|
createKnownParametersFromFreshVariablesSubstitutor(toFreshVariables, it)
|
||||||
} ?: EmptySubstitutor
|
} ?: EmptySubstitutor
|
||||||
|
|
||||||
resolvedCall.freshVariablesSubstitutor = toFreshVariables
|
resolvedCall.freshVariablesSubstitutor = toFreshVariables
|
||||||
@@ -275,6 +276,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
|||||||
|
|
||||||
internal object PostponedVariablesInitializerResolutionPart : ResolutionPart() {
|
internal object PostponedVariablesInitializerResolutionPart : ResolutionPart() {
|
||||||
override fun ResolutionCandidate.process(workIndex: Int) {
|
override fun ResolutionCandidate.process(workIndex: Int) {
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
for ((argument, parameter) in resolvedCall.argumentToCandidateParameter) {
|
for ((argument, parameter) in resolvedCall.argumentToCandidateParameter) {
|
||||||
if (!callComponents.statelessCallbacks.isBuilderInferenceCall(argument, parameter)) continue
|
if (!callComponents.statelessCallbacks.isBuilderInferenceCall(argument, parameter)) continue
|
||||||
val receiverType = parameter.type.getReceiverTypeFromFunctionType() ?: continue
|
val receiverType = parameter.type.getReceiverTypeFromFunctionType() ?: continue
|
||||||
@@ -302,6 +304,7 @@ internal object PostponedVariablesInitializerResolutionPart : ResolutionPart() {
|
|||||||
|
|
||||||
internal object CompatibilityOfTypeVariableAsIntersectionTypePart : ResolutionPart() {
|
internal object CompatibilityOfTypeVariableAsIntersectionTypePart : ResolutionPart() {
|
||||||
override fun ResolutionCandidate.process(workIndex: Int) {
|
override fun ResolutionCandidate.process(workIndex: Int) {
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
for ((_, variableWithConstraints) in csBuilder.currentStorage().notFixedTypeVariables) {
|
for ((_, variableWithConstraints) in csBuilder.currentStorage().notFixedTypeVariables) {
|
||||||
val constraints = variableWithConstraints.constraints.filter { csBuilder.isProperType(it.type) }
|
val constraints = variableWithConstraints.constraints.filter { csBuilder.isProperType(it.type) }
|
||||||
|
|
||||||
@@ -487,13 +490,14 @@ internal object CollectionTypeVariableUsagesInfo : ResolutionPart() {
|
|||||||
|
|
||||||
override fun ResolutionCandidate.process(workIndex: Int) {
|
override fun ResolutionCandidate.process(workIndex: Int) {
|
||||||
for (variable in resolvedCall.freshVariablesSubstitutor.freshVariables) {
|
for (variable in resolvedCall.freshVariablesSubstitutor.freshVariables) {
|
||||||
if (resolvedCall.candidateDescriptor is ClassConstructorDescriptor) {
|
val candidateDescriptor = resolvedCall.candidateDescriptor
|
||||||
val typeParameters = resolvedCall.candidateDescriptor.containingDeclaration.declaredTypeParameters
|
if (candidateDescriptor is ClassConstructorDescriptor) {
|
||||||
|
val typeParameters = candidateDescriptor.containingDeclaration.declaredTypeParameters
|
||||||
|
|
||||||
if (isContainedInInvariantOrContravariantPositionsAmongTypeParameters(variable, typeParameters)) {
|
if (isContainedInInvariantOrContravariantPositionsAmongTypeParameters(variable, typeParameters)) {
|
||||||
variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
||||||
}
|
}
|
||||||
} else if (getSystem().isContainedInInvariantOrContravariantPositionsWithDependencies(variable, candidateDescriptor)) {
|
} else if (getSystem().isContainedInInvariantOrContravariantPositionsWithDependencies(variable, this.candidateDescriptor)) {
|
||||||
variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,6 +509,7 @@ private fun ResolutionCandidate.resolveKotlinArgument(
|
|||||||
candidateParameter: ParameterDescriptor?,
|
candidateParameter: ParameterDescriptor?,
|
||||||
receiverInfo: ReceiverInfo
|
receiverInfo: ReceiverInfo
|
||||||
) {
|
) {
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
val candidateExpectedType = candidateParameter?.let { argument.getExpectedType(it, callComponents.languageVersionSettings) }
|
val candidateExpectedType = candidateParameter?.let { argument.getExpectedType(it, callComponents.languageVersionSettings) }
|
||||||
|
|
||||||
val isReceiver = receiverInfo.isReceiver
|
val isReceiver = receiverInfo.isReceiver
|
||||||
@@ -602,6 +607,7 @@ private fun ResolutionCandidate.resolveKotlinArgument(
|
|||||||
|
|
||||||
private fun ResolutionCandidate.shouldRunConversionForConstants(expectedType: UnwrappedType): Boolean {
|
private fun ResolutionCandidate.shouldRunConversionForConstants(expectedType: UnwrappedType): Boolean {
|
||||||
if (UnsignedTypes.isUnsignedType(expectedType)) return true
|
if (UnsignedTypes.isUnsignedType(expectedType)) return true
|
||||||
|
val csBuilder = getSystem().getBuilder()
|
||||||
if (csBuilder.isTypeVariable(expectedType)) {
|
if (csBuilder.isTypeVariable(expectedType)) {
|
||||||
val variableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[expectedType.constructor] ?: return false
|
val variableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[expectedType.constructor] ?: return false
|
||||||
return variableWithConstraints.constraints.any {
|
return variableWithConstraints.constraints.any {
|
||||||
@@ -650,7 +656,7 @@ internal object CheckReceivers : ResolutionPart() {
|
|||||||
receiverParameter: ReceiverParameterDescriptor?,
|
receiverParameter: ReceiverParameterDescriptor?,
|
||||||
shouldCheckImplicitInvoke: Boolean,
|
shouldCheckImplicitInvoke: Boolean,
|
||||||
) {
|
) {
|
||||||
if ((receiverArgument == null) != (receiverParameter == null)) {
|
if (this !is CallableReferenceResolutionCandidate && (receiverArgument == null) != (receiverParameter == null)) {
|
||||||
error("Inconsistency receiver state for call $kotlinCall and candidate descriptor: $candidateDescriptor")
|
error("Inconsistency receiver state for call $kotlinCall and candidate descriptor: $candidateDescriptor")
|
||||||
}
|
}
|
||||||
if (receiverArgument == null || receiverParameter == null) return
|
if (receiverArgument == null || receiverParameter == null) return
|
||||||
@@ -709,11 +715,25 @@ internal object EagerResolveOfCallableReferences : ResolutionPart() {
|
|||||||
getSubResolvedAtoms()
|
getSubResolvedAtoms()
|
||||||
.filterIsInstance<EagerCallableReferenceAtom>()
|
.filterIsInstance<EagerCallableReferenceAtom>()
|
||||||
.forEach {
|
.forEach {
|
||||||
callableReferenceResolver.processCallableReferenceArgument(csBuilder, it, this, resolutionCallbacks)
|
callComponents.callableReferenceArgumentResolver.processCallableReferenceArgument(
|
||||||
|
getSystem().getBuilder(), it, this, resolutionCallbacks
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal object CheckCallableReference : ResolutionPart() {
|
||||||
|
override fun ResolutionCandidate.process(workIndex: Int) {
|
||||||
|
if (this !is CallableReferenceResolutionCandidate) {
|
||||||
|
error("`CheckCallableReferences` resolution part is applicable only to callable reference calls")
|
||||||
|
}
|
||||||
|
|
||||||
|
val constraintSystem = getSystem().takeIf { !it.hasContradiction } ?: return
|
||||||
|
|
||||||
|
addConstraints(constraintSystem.getBuilder(), resolvedCall.freshVariablesSubstitutor, kotlinCall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal object CheckInfixResolutionPart : ResolutionPart() {
|
internal object CheckInfixResolutionPart : ResolutionPart() {
|
||||||
override fun ResolutionCandidate.process(workIndex: Int) {
|
override fun ResolutionCandidate.process(workIndex: Int) {
|
||||||
val candidateDescriptor = resolvedCall.candidateDescriptor
|
val candidateDescriptor = resolvedCall.candidateDescriptor
|
||||||
|
|||||||
+4
-2
@@ -28,8 +28,10 @@ object UnitTypeConversions : ParameterTypeConversion {
|
|||||||
if (argument !is SimpleKotlinCallArgument) return true
|
if (argument !is SimpleKotlinCallArgument) return true
|
||||||
|
|
||||||
val receiver = argument.receiver
|
val receiver = argument.receiver
|
||||||
if (receiver.receiverValue.type.hasUnitOrSubtypeReturnType(candidate.csBuilder)) return true
|
val csBuilder = candidate.getSystem().getBuilder()
|
||||||
if (receiver.typesFromSmartCasts.any { it.hasUnitOrSubtypeReturnType(candidate.csBuilder) }) return true
|
|
||||||
|
if (receiver.receiverValue.type.hasUnitOrSubtypeReturnType(csBuilder)) return true
|
||||||
|
if (receiver.typesFromSmartCasts.any { it.hasUnitOrSubtypeReturnType(csBuilder) }) return true
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!expectedParameterType.isBuiltinFunctionalType ||
|
!expectedParameterType.isBuiltinFunctionalType ||
|
||||||
|
|||||||
+1
-1
@@ -33,10 +33,10 @@ class CallableReferenceResolutionCandidate(
|
|||||||
val reflectionCandidateType: UnwrappedType,
|
val reflectionCandidateType: UnwrappedType,
|
||||||
val callableReferenceAdaptation: CallableReferenceAdaptation?,
|
val callableReferenceAdaptation: CallableReferenceAdaptation?,
|
||||||
val kotlinCall: CallableReferenceResolutionAtom,
|
val kotlinCall: CallableReferenceResolutionAtom,
|
||||||
|
val expectedType: UnwrappedType?,
|
||||||
override val callComponents: KotlinCallComponents,
|
override val callComponents: KotlinCallComponents,
|
||||||
override val scopeTower: ImplicitScopeTower,
|
override val scopeTower: ImplicitScopeTower,
|
||||||
override val resolutionCallbacks: KotlinResolutionCallbacks,
|
override val resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
val expectedType: UnwrappedType?,
|
|
||||||
override val baseSystem: ConstraintStorage?
|
override val baseSystem: ConstraintStorage?
|
||||||
) : ResolutionCandidate() {
|
) : ResolutionCandidate() {
|
||||||
override val variableCandidateIfInvoke: ResolutionCandidate? = null
|
override val variableCandidateIfInvoke: ResolutionCandidate? = null
|
||||||
|
|||||||
+44
-46
@@ -20,30 +20,61 @@ import java.util.ArrayList
|
|||||||
sealed class ResolutionCandidate : Candidate, KotlinDiagnosticsHolder {
|
sealed class ResolutionCandidate : Candidate, KotlinDiagnosticsHolder {
|
||||||
abstract val resolvedCall: MutableResolvedCallAtom
|
abstract val resolvedCall: MutableResolvedCallAtom
|
||||||
abstract val callComponents: KotlinCallComponents
|
abstract val callComponents: KotlinCallComponents
|
||||||
abstract fun getSubResolvedAtoms(): List<ResolvedAtom>
|
|
||||||
abstract fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom)
|
|
||||||
abstract val variableCandidateIfInvoke: ResolutionCandidate?
|
abstract val variableCandidateIfInvoke: ResolutionCandidate?
|
||||||
abstract val scopeTower: ImplicitScopeTower
|
abstract val scopeTower: ImplicitScopeTower
|
||||||
abstract val knownTypeParametersResultingSubstitutor: TypeSubstitutor?
|
abstract val knownTypeParametersResultingSubstitutor: TypeSubstitutor?
|
||||||
abstract val resolutionCallbacks: KotlinResolutionCallbacks
|
abstract val resolutionCallbacks: KotlinResolutionCallbacks
|
||||||
|
|
||||||
|
override val isSuccessful: Boolean
|
||||||
|
get() {
|
||||||
|
processParts(stopOnFirstError = true)
|
||||||
|
return resultingApplicabilities.minOrNull()!!.isSuccess && !getSystem().hasContradiction
|
||||||
|
}
|
||||||
|
|
||||||
|
override val resultingApplicability: CandidateApplicability
|
||||||
|
get() {
|
||||||
|
processParts(stopOnFirstError = false)
|
||||||
|
return resultingApplicabilities.minOrNull() ?: CandidateApplicability.RESOLVED
|
||||||
|
}
|
||||||
|
|
||||||
|
open val resolutionSequence: List<ResolutionPart> get() = resolvedCall.atom.callKind.resolutionSequence
|
||||||
|
|
||||||
protected abstract val baseSystem: ConstraintStorage?
|
protected abstract val baseSystem: ConstraintStorage?
|
||||||
|
protected val mutableDiagnostics: ArrayList<KotlinCallDiagnostic> = arrayListOf()
|
||||||
|
|
||||||
|
val descriptor: CallableDescriptor get() = resolvedCall.candidateDescriptor
|
||||||
|
val diagnostics: List<KotlinCallDiagnostic> = mutableDiagnostics
|
||||||
|
val resultingApplicabilities: Array<CandidateApplicability>
|
||||||
|
get() = arrayOf(currentApplicability, getResultApplicability(getSystem().errors), variableApplicability)
|
||||||
|
|
||||||
|
private val variableApplicability
|
||||||
|
get() = variableCandidateIfInvoke?.resultingApplicability ?: CandidateApplicability.RESOLVED
|
||||||
|
private val stepCount get() = resolutionSequence.sumOf { it.run { workCount() } }
|
||||||
|
|
||||||
|
private var step = 0
|
||||||
|
private var newSystem: NewConstraintSystemImpl? = null
|
||||||
|
private var currentApplicability: CandidateApplicability = CandidateApplicability.RESOLVED
|
||||||
|
|
||||||
|
abstract fun getSubResolvedAtoms(): List<ResolvedAtom>
|
||||||
|
abstract fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom)
|
||||||
|
|
||||||
override fun addDiagnostic(diagnostic: KotlinCallDiagnostic) {
|
override fun addDiagnostic(diagnostic: KotlinCallDiagnostic) {
|
||||||
mutableDiagnostics.add(diagnostic)
|
mutableDiagnostics.add(diagnostic)
|
||||||
currentApplicability = minOf(diagnostic.candidateApplicability, currentApplicability)
|
currentApplicability = minOf(diagnostic.candidateApplicability, currentApplicability)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val variableApplicability
|
override fun addCompatibilityWarning(other: Candidate) {
|
||||||
get() = variableCandidateIfInvoke?.resultingApplicability ?: CandidateApplicability.RESOLVED
|
if (other is ResolutionCandidate && this !== other && this::class == other::class) {
|
||||||
|
addDiagnostic(CompatibilityWarning(other.descriptor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val descriptor: CallableDescriptor get() = resolvedCall.candidateDescriptor
|
override fun toString(): String {
|
||||||
|
val descriptor = DescriptorRenderer.COMPACT.render(resolvedCall.candidateDescriptor)
|
||||||
protected val mutableDiagnostics: ArrayList<KotlinCallDiagnostic> = arrayListOf()
|
val okOrFail = if (resultingApplicabilities.minOrNull()?.isSuccess != false) "OK" else "FAIL"
|
||||||
|
val step = "$step/$stepCount"
|
||||||
open val resolutionSequence: List<ResolutionPart> get() = resolvedCall.atom.callKind.resolutionSequence
|
return "$okOrFail($step): $descriptor"
|
||||||
private var newSystem: NewConstraintSystemImpl? = null
|
}
|
||||||
|
|
||||||
val diagnostics: List<KotlinCallDiagnostic> = mutableDiagnostics
|
|
||||||
|
|
||||||
fun getSystem(): NewConstraintSystem {
|
fun getSystem(): NewConstraintSystem {
|
||||||
if (newSystem == null) {
|
if (newSystem == null) {
|
||||||
@@ -57,9 +88,6 @@ sealed class ResolutionCandidate : Candidate, KotlinDiagnosticsHolder {
|
|||||||
return newSystem!!
|
return newSystem!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private val stepCount get() = resolutionSequence.sumOf { it.run { workCount() } }
|
|
||||||
private var step = 0
|
|
||||||
|
|
||||||
private fun processParts(stopOnFirstError: Boolean) {
|
private fun processParts(stopOnFirstError: Boolean) {
|
||||||
if (stopOnFirstError && step > 0) return // error already happened
|
if (stopOnFirstError && step > 0) return // error already happened
|
||||||
if (step == stepCount) return
|
if (step == stepCount) return
|
||||||
@@ -99,34 +127,4 @@ sealed class ResolutionCandidate : Candidate, KotlinDiagnosticsHolder {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
protected var currentApplicability: CandidateApplicability = CandidateApplicability.RESOLVED
|
|
||||||
|
|
||||||
override val isSuccessful: Boolean
|
|
||||||
get() {
|
|
||||||
processParts(stopOnFirstError = true)
|
|
||||||
return resultingApplicabilities.minOrNull()!!.isSuccess && !getSystem().hasContradiction
|
|
||||||
}
|
|
||||||
|
|
||||||
val resultingApplicabilities: Array<CandidateApplicability>
|
|
||||||
get() = arrayOf(currentApplicability, getResultApplicability(getSystem().errors), variableApplicability)
|
|
||||||
|
|
||||||
override val resultingApplicability: CandidateApplicability
|
|
||||||
get() {
|
|
||||||
processParts(stopOnFirstError = false)
|
|
||||||
return resultingApplicabilities.minOrNull()!!
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun addCompatibilityWarning(other: Candidate) {
|
|
||||||
if (other is ResolutionCandidate && this !== other && this::class == other::class) {
|
|
||||||
addDiagnostic(CompatibilityWarning(other.descriptor))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
val descriptor = DescriptorRenderer.COMPACT.render(resolvedCall.candidateDescriptor)
|
|
||||||
val okOrFail = if (resultingApplicabilities.minOrNull()!!.isSuccess) "OK" else "FAIL"
|
|
||||||
val step = "$step/$stepCount"
|
|
||||||
return "$okOrFail($step): $descriptor"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -25,8 +25,6 @@ open class SimpleResolutionCandidate(
|
|||||||
override val resolvedCall: MutableResolvedCallAtom,
|
override val resolvedCall: MutableResolvedCallAtom,
|
||||||
override val knownTypeParametersResultingSubstitutor: TypeSubstitutor? = null,
|
override val knownTypeParametersResultingSubstitutor: TypeSubstitutor? = null,
|
||||||
) : ResolutionCandidate() {
|
) : ResolutionCandidate() {
|
||||||
private var subResolvedAtoms: MutableList<ResolvedAtom> = arrayListOf()
|
|
||||||
|
|
||||||
override val variableCandidateIfInvoke: ResolutionCandidate?
|
override val variableCandidateIfInvoke: ResolutionCandidate?
|
||||||
get() = callComponents.statelessCallbacks.getVariableCandidateIfInvoke(resolvedCall.atom)
|
get() = callComponents.statelessCallbacks.getVariableCandidateIfInvoke(resolvedCall.atom)
|
||||||
|
|
||||||
@@ -35,4 +33,6 @@ open class SimpleResolutionCandidate(
|
|||||||
override fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom) {
|
override fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom) {
|
||||||
subResolvedAtoms.add(resolvedAtom)
|
subResolvedAtoms.add(resolvedAtom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var subResolvedAtoms: MutableList<ResolvedAtom> = arrayListOf()
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -35,6 +35,8 @@ val CallableDescriptor.returnTypeOrNothing: UnwrappedType
|
|||||||
fun TypeSubstitutor.substitute(type: UnwrappedType): UnwrappedType = safeSubstitute(type, Variance.INVARIANT).unwrap()
|
fun TypeSubstitutor.substitute(type: UnwrappedType): UnwrappedType = safeSubstitute(type, Variance.INVARIANT).unwrap()
|
||||||
|
|
||||||
fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDescriptor {
|
fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDescriptor {
|
||||||
|
if (substitutor.isEmpty) return this
|
||||||
|
|
||||||
val wrappedSubstitution = object : TypeSubstitution() {
|
val wrappedSubstitution = object : TypeSubstitution() {
|
||||||
override fun get(key: KotlinType): TypeProjection? = null
|
override fun get(key: KotlinType): TypeProjection? = null
|
||||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = substitutor.safeSubstitute(topLevelType.unwrap())
|
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = substitutor.safeSubstitute(topLevelType.unwrap())
|
||||||
@@ -44,16 +46,20 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
|
|||||||
|
|
||||||
fun CallableDescriptor.substituteAndApproximateTypes(
|
fun CallableDescriptor.substituteAndApproximateTypes(
|
||||||
substitutor: NewTypeSubstitutor,
|
substitutor: NewTypeSubstitutor,
|
||||||
typeApproximator: TypeApproximator?
|
typeApproximator: TypeApproximator?,
|
||||||
|
positionDependentApproximation: Boolean = false
|
||||||
): CallableDescriptor {
|
): CallableDescriptor {
|
||||||
|
if (substitutor.isEmpty) return this
|
||||||
|
|
||||||
val wrappedSubstitution = object : TypeSubstitution() {
|
val wrappedSubstitution = object : TypeSubstitution() {
|
||||||
override fun get(key: KotlinType): TypeProjection? = null
|
override fun get(key: KotlinType): TypeProjection? = null
|
||||||
|
|
||||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||||
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
||||||
typeApproximator?.approximateToSuperType(
|
typeApproximator?.approximateTo(
|
||||||
substitutedType,
|
substitutedType,
|
||||||
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
|
||||||
|
position != Variance.IN_VARIANCE || !positionDependentApproximation
|
||||||
) ?: substitutedType
|
) ?: substitutedType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.SimpleResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.transformToResolvedLambda
|
import org.jetbrains.kotlin.resolve.calls.components.transformToResolvedLambda
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
@@ -286,7 +287,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||||
): ResolvedLambdaAtom {
|
): ResolvedLambdaAtom {
|
||||||
val returnVariable = TypeVariableForLambdaReturnType(candidate.callComponents.builtIns, "_R")
|
val returnVariable = TypeVariableForLambdaReturnType(candidate.callComponents.builtIns, "_R")
|
||||||
val csBuilder = candidate.csBuilder
|
val csBuilder = candidate.getSystem().getBuilder()
|
||||||
csBuilder.registerVariable(returnVariable)
|
csBuilder.registerVariable(returnVariable)
|
||||||
val functionalType: KotlinType = csBuilder.buildCurrentSubstitutor().safeSubstitute(candidate.getSystem().asConstraintSystemCompleterContext(), atom.expectedType!!) as KotlinType
|
val functionalType: KotlinType = csBuilder.buildCurrentSubstitutor().safeSubstitute(candidate.getSystem().asConstraintSystemCompleterContext(), atom.expectedType!!) as KotlinType
|
||||||
val expectedType = KotlinTypeFactory.simpleType(
|
val expectedType = KotlinTypeFactory.simpleType(
|
||||||
|
|||||||
+3
@@ -34,6 +34,9 @@ class DeclaredUpperBoundConstraintPositionImpl(
|
|||||||
|
|
||||||
class ArgumentConstraintPositionImpl(argument: KotlinCallArgument) : ArgumentConstraintPosition<KotlinCallArgument>(argument)
|
class ArgumentConstraintPositionImpl(argument: KotlinCallArgument) : ArgumentConstraintPosition<KotlinCallArgument>(argument)
|
||||||
|
|
||||||
|
class CallableReferenceConstraintPositionImpl(val callableReferenceCall: CallableReferenceKotlinCall) :
|
||||||
|
CallableReferenceConstraintPosition<CallableReferenceResolutionAtom>(callableReferenceCall)
|
||||||
|
|
||||||
class ReceiverConstraintPositionImpl(argument: KotlinCallArgument) : ReceiverConstraintPosition<KotlinCallArgument>(argument)
|
class ReceiverConstraintPositionImpl(argument: KotlinCallArgument) : ReceiverConstraintPosition<KotlinCallArgument>(argument)
|
||||||
|
|
||||||
class FixVariableConstraintPositionImpl(
|
class FixVariableConstraintPositionImpl(
|
||||||
|
|||||||
+62
-63
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.model
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||||
@@ -13,35 +13,53 @@ import org.jetbrains.kotlin.config.ApiVersion
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
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.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
|
||||||
|
|
||||||
class CallableReferencesCandidateFactory(
|
class CallableReferencesCandidateFactory(
|
||||||
val argument: CallableReferenceKotlinCallArgument,
|
val kotlinCall: CallableReferenceResolutionAtom,
|
||||||
val callComponents: KotlinCallComponents,
|
val callComponents: KotlinCallComponents,
|
||||||
val scopeTower: ImplicitScopeTower,
|
val scopeTower: ImplicitScopeTower,
|
||||||
val compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit,
|
|
||||||
val expectedType: UnwrappedType?,
|
val expectedType: UnwrappedType?,
|
||||||
private val csBuilder: ConstraintSystemOperation,
|
private val baseSystem: ConstraintStorage?,
|
||||||
private val resolutionCallbacks: KotlinResolutionCallbacks
|
private val resolutionCallbacks: KotlinResolutionCallbacks
|
||||||
) : CandidateFactory<CallableReferenceResolutionCandidate> {
|
) : CandidateFactory<CallableReferenceResolutionCandidate> {
|
||||||
|
// todo investigate similar code in CheckVisibility
|
||||||
|
private val CallableReceiver.asReceiverValueForVisibilityChecks: ReceiverValue
|
||||||
|
get() = receiver.receiverValue
|
||||||
|
|
||||||
fun createCallableProcessor(explicitReceiver: DetailedReceiver?) =
|
override fun createErrorCandidate(): CallableReferenceResolutionCandidate {
|
||||||
createCallableReferenceProcessor(scopeTower, argument.rhsName, this, explicitReceiver)
|
val errorScope = ErrorUtils.createErrorScope("Error resolution candidate for call $kotlinCall")
|
||||||
|
val errorDescriptor = errorScope.getContributedFunctions(kotlinCall.rhsName, scopeTower.location).first()
|
||||||
|
|
||||||
|
val (reflectionCandidateType, callableReferenceAdaptation) = buildReflectionType(
|
||||||
|
errorDescriptor,
|
||||||
|
dispatchReceiver = null,
|
||||||
|
extensionReceiver = null,
|
||||||
|
expectedType,
|
||||||
|
callComponents.builtIns,
|
||||||
|
buildTypeWithConversions = kotlinCall is CallableReferenceKotlinCallArgument
|
||||||
|
)
|
||||||
|
|
||||||
|
return CallableReferenceResolutionCandidate(
|
||||||
|
errorDescriptor, dispatchReceiver = null, extensionReceiver = null,
|
||||||
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, reflectionCandidateType, callableReferenceAdaptation,
|
||||||
|
kotlinCall, expectedType, callComponents, scopeTower, resolutionCallbacks, baseSystem
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun createCandidate(
|
override fun createCandidate(
|
||||||
towerCandidate: CandidateWithBoundDispatchReceiver,
|
towerCandidate: CandidateWithBoundDispatchReceiver,
|
||||||
@@ -59,18 +77,20 @@ class CallableReferencesCandidateFactory(
|
|||||||
dispatchCallableReceiver,
|
dispatchCallableReceiver,
|
||||||
extensionCallableReceiver,
|
extensionCallableReceiver,
|
||||||
expectedType,
|
expectedType,
|
||||||
callComponents.builtIns
|
callComponents.builtIns,
|
||||||
|
// conversions aren't needed for top-level callable references
|
||||||
|
buildTypeWithConversions = kotlinCall is CallableReferenceKotlinCallArgument
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createReferenceCandidate(): CallableReferenceResolutionCandidate =
|
fun createCallableReferenceCallCandidate(diagnostics: List<KotlinCallDiagnostic>) = CallableReferenceResolutionCandidate(
|
||||||
CallableReferenceResolutionCandidate(
|
candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
||||||
candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
explicitReceiverKind, reflectionCandidateType, callableReferenceAdaptation,
|
||||||
explicitReceiverKind, reflectionCandidateType, callableReferenceAdaptation, diagnostics
|
kotlinCall, expectedType, callComponents, scopeTower, resolutionCallbacks, baseSystem
|
||||||
)
|
).also { diagnostics.forEach(it::addDiagnostic) }
|
||||||
|
|
||||||
if (callComponents.statelessCallbacks.isHiddenInResolution(candidateDescriptor, argument, resolutionCallbacks)) {
|
if (callComponents.statelessCallbacks.isHiddenInResolution(candidateDescriptor, kotlinCall.call, resolutionCallbacks)) {
|
||||||
diagnostics.add(HiddenDescriptor)
|
diagnostics.add(HiddenDescriptor)
|
||||||
return createReferenceCandidate()
|
return createCallableReferenceCallCandidate(diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needCompatibilityResolveForCallableReference(callableReferenceAdaptation, candidateDescriptor)) {
|
if (needCompatibilityResolveForCallableReference(callableReferenceAdaptation, candidateDescriptor)) {
|
||||||
@@ -79,7 +99,7 @@ class CallableReferencesCandidateFactory(
|
|||||||
|
|
||||||
if (callableReferenceAdaptation != null && expectedType != null && hasNonTrivialAdaptation(callableReferenceAdaptation)) {
|
if (callableReferenceAdaptation != null && expectedType != null && hasNonTrivialAdaptation(callableReferenceAdaptation)) {
|
||||||
if (!expectedType.isFunctionType && !expectedType.isSuspendFunctionType) { // expectedType has some reflection type
|
if (!expectedType.isFunctionType && !expectedType.isSuspendFunctionType) { // expectedType has some reflection type
|
||||||
diagnostics.add(AdaptedCallableReferenceIsUsedWithReflection(argument))
|
diagnostics.add(AdaptedCallableReferenceIsUsedWithReflection(kotlinCall))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,49 +107,28 @@ class CallableReferencesCandidateFactory(
|
|||||||
callableReferenceAdaptation.defaults != 0 &&
|
callableReferenceAdaptation.defaults != 0 &&
|
||||||
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType)
|
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType)
|
||||||
) {
|
) {
|
||||||
diagnostics.add(CallableReferencesDefaultArgumentUsed(argument, candidateDescriptor, callableReferenceAdaptation.defaults))
|
diagnostics.add(CallableReferencesDefaultArgumentUsed(kotlinCall, candidateDescriptor, callableReferenceAdaptation.defaults))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidateDescriptor !is CallableMemberDescriptor) {
|
if (candidateDescriptor !is CallableMemberDescriptor) {
|
||||||
return CallableReferenceResolutionCandidate(
|
return createCallableReferenceCallCandidate(listOf(NotCallableMemberReference(kotlinCall, candidateDescriptor)))
|
||||||
candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
|
||||||
explicitReceiverKind, reflectionCandidateType, callableReferenceAdaptation,
|
|
||||||
listOf(NotCallableMemberReference(argument, candidateDescriptor))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostics.addAll(towerCandidate.diagnostics)
|
diagnostics.addAll(towerCandidate.diagnostics)
|
||||||
// todo smartcast on receiver diagnostic and CheckInstantiationOfAbstractClass
|
// todo smartcast on receiver diagnostic and CheckInstantiationOfAbstractClass
|
||||||
|
|
||||||
compatibilityChecker {
|
return createCallableReferenceCallCandidate(diagnostics)
|
||||||
if (it.hasContradiction) return@compatibilityChecker
|
|
||||||
|
|
||||||
val (_, visibilityError) = it.checkCallableReference(
|
|
||||||
argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor,
|
|
||||||
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor
|
|
||||||
)
|
|
||||||
|
|
||||||
diagnostics.addIfNotNull(visibilityError)
|
|
||||||
|
|
||||||
if (it.hasContradiction) diagnostics.add(
|
|
||||||
CallableReferenceNotCompatible(
|
|
||||||
argument,
|
|
||||||
candidateDescriptor,
|
|
||||||
expectedType,
|
|
||||||
reflectionCandidateType
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return createReferenceCandidate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createCallableProcessor(explicitReceiver: DetailedReceiver?) =
|
||||||
|
createCallableReferenceProcessor(scopeTower, kotlinCall.rhsName, this, explicitReceiver)
|
||||||
|
|
||||||
private fun needCompatibilityResolveForCallableReference(
|
private fun needCompatibilityResolveForCallableReference(
|
||||||
callableReferenceAdaptation: CallableReferenceAdaptation?,
|
callableReferenceAdaptation: CallableReferenceAdaptation?,
|
||||||
candidate: CallableDescriptor
|
candidate: CallableDescriptor
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// KT-13934: reference to companion object member via class name
|
// KT-13934: reference to companion object member via class name
|
||||||
if (candidate.containingDeclaration.isCompanionObject() && argument.lhsResult is LHSResult.Type) return true
|
if (candidate.containingDeclaration.isCompanionObject() && kotlinCall.lhsResult is LHSResult.Type) return true
|
||||||
|
|
||||||
if (callableReferenceAdaptation == null) return false
|
if (callableReferenceAdaptation == null) return false
|
||||||
|
|
||||||
@@ -142,19 +141,13 @@ class CallableReferencesCandidateFactory(
|
|||||||
callableReferenceAdaptation.coercionStrategy != CoercionStrategy.NO_COERCION ||
|
callableReferenceAdaptation.coercionStrategy != CoercionStrategy.NO_COERCION ||
|
||||||
callableReferenceAdaptation.mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
callableReferenceAdaptation.mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
||||||
|
|
||||||
private enum class VarargMappingState {
|
|
||||||
UNMAPPED, MAPPED_WITH_PLAIN_ARGS, MAPPED_WITH_ARRAY
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCallableReferenceAdaptation(
|
private fun getCallableReferenceAdaptation(
|
||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
expectedType: UnwrappedType?,
|
expectedType: UnwrappedType?,
|
||||||
unboundReceiverCount: Int,
|
unboundReceiverCount: Int,
|
||||||
builtins: KotlinBuiltIns
|
builtins: KotlinBuiltIns
|
||||||
): CallableReferenceAdaptation? {
|
): CallableReferenceAdaptation? {
|
||||||
if (callComponents.languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_4) return null
|
if (expectedType == null || TypeUtils.noExpectedType(expectedType)) return null
|
||||||
|
|
||||||
if (expectedType == null) return null
|
|
||||||
|
|
||||||
// Do not adapt references against KCallable type as it's impossible to map defaults/vararg to absent parameters of KCallable
|
// Do not adapt references against KCallable type as it's impossible to map defaults/vararg to absent parameters of KCallable
|
||||||
if (ReflectionTypes.hasKCallableTypeFqName(expectedType)) return null
|
if (ReflectionTypes.hasKCallableTypeFqName(expectedType)) return null
|
||||||
@@ -302,7 +295,7 @@ class CallableReferencesCandidateFactory(
|
|||||||
return when (varargMappingState) {
|
return when (varargMappingState) {
|
||||||
VarargMappingState.UNMAPPED -> {
|
VarargMappingState.UNMAPPED -> {
|
||||||
if (KotlinBuiltIns.isArrayOrPrimitiveArray(expectedParameterType) ||
|
if (KotlinBuiltIns.isArrayOrPrimitiveArray(expectedParameterType) ||
|
||||||
csBuilder.isTypeVariable(expectedParameterType)
|
expectedParameterType.constructor is TypeVariableTypeConstructor
|
||||||
) {
|
) {
|
||||||
val arrayType = builtins.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(elementType)
|
val arrayType = builtins.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(elementType)
|
||||||
?: builtins.getArrayType(Variance.OUT_VARIANCE, elementType)
|
?: builtins.getArrayType(Variance.OUT_VARIANCE, elementType)
|
||||||
@@ -327,7 +320,8 @@ class CallableReferencesCandidateFactory(
|
|||||||
dispatchReceiver: CallableReceiver?,
|
dispatchReceiver: CallableReceiver?,
|
||||||
extensionReceiver: CallableReceiver?,
|
extensionReceiver: CallableReceiver?,
|
||||||
expectedType: UnwrappedType?,
|
expectedType: UnwrappedType?,
|
||||||
builtins: KotlinBuiltIns
|
builtins: KotlinBuiltIns,
|
||||||
|
buildTypeWithConversions: Boolean = true
|
||||||
): Pair<UnwrappedType, CallableReferenceAdaptation?> {
|
): Pair<UnwrappedType, CallableReferenceAdaptation?> {
|
||||||
val argumentsAndReceivers = ArrayList<KotlinType>(descriptor.valueParameters.size + 2)
|
val argumentsAndReceivers = ArrayList<KotlinType>(descriptor.valueParameters.size + 2)
|
||||||
|
|
||||||
@@ -365,7 +359,7 @@ class CallableReferencesCandidateFactory(
|
|||||||
builtins = builtins
|
builtins = builtins
|
||||||
)
|
)
|
||||||
|
|
||||||
val returnType = if (callableReferenceAdaptation == null) {
|
val returnType = if (callableReferenceAdaptation == null || !buildTypeWithConversions) {
|
||||||
descriptor.valueParameters.mapTo(argumentsAndReceivers) { it.type }
|
descriptor.valueParameters.mapTo(argumentsAndReceivers) { it.type }
|
||||||
descriptorReturnType
|
descriptorReturnType
|
||||||
} else {
|
} else {
|
||||||
@@ -380,7 +374,8 @@ class CallableReferencesCandidateFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val suspendConversionStrategy = callableReferenceAdaptation?.suspendConversionStrategy
|
val suspendConversionStrategy = callableReferenceAdaptation?.suspendConversionStrategy
|
||||||
val isSuspend = descriptor.isSuspend || suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
|
val isSuspend = descriptor.isSuspend ||
|
||||||
|
(suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION && buildTypeWithConversions)
|
||||||
|
|
||||||
callComponents.reflectionTypes.getKFunctionType(
|
callComponents.reflectionTypes.getKFunctionType(
|
||||||
Annotations.EMPTY, null, argumentsAndReceivers, null,
|
Annotations.EMPTY, null, argumentsAndReceivers, null,
|
||||||
@@ -397,7 +392,7 @@ class CallableReferencesCandidateFactory(
|
|||||||
private fun toCallableReceiver(receiver: ReceiverValueWithSmartCastInfo, isExplicit: Boolean): CallableReceiver {
|
private fun toCallableReceiver(receiver: ReceiverValueWithSmartCastInfo, isExplicit: Boolean): CallableReceiver {
|
||||||
if (!isExplicit) return CallableReceiver.ScopeReceiver(receiver)
|
if (!isExplicit) return CallableReceiver.ScopeReceiver(receiver)
|
||||||
|
|
||||||
return when (val lhsResult = argument.lhsResult) {
|
return when (val lhsResult = kotlinCall.lhsResult) {
|
||||||
is LHSResult.Expression -> CallableReceiver.ExplicitValueReceiver(receiver)
|
is LHSResult.Expression -> CallableReceiver.ExplicitValueReceiver(receiver)
|
||||||
is LHSResult.Type -> {
|
is LHSResult.Type -> {
|
||||||
if (lhsResult.qualifier?.classValueReceiver?.type == receiver.receiverValue.type) {
|
if (lhsResult.qualifier?.classValueReceiver?.type == receiver.receiverValue.type) {
|
||||||
@@ -410,4 +405,8 @@ class CallableReferencesCandidateFactory(
|
|||||||
else -> throw IllegalStateException("Unsupported kind of lhsResult: $lhsResult")
|
else -> throw IllegalStateException("Unsupported kind of lhsResult: $lhsResult")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private enum class VarargMappingState {
|
||||||
|
UNMAPPED, MAPPED_WITH_PLAIN_ARGS, MAPPED_WITH_ARRAY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,18 @@ fun KotlinCall.checkCallInvariants() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KotlinCallKind.CALLABLE_REFERENCE -> {
|
||||||
|
assert(argumentsInParenthesis.isEmpty()) {
|
||||||
|
"Callable references can't have value arguments"
|
||||||
|
}
|
||||||
|
assert(typeArguments.isEmpty()) {
|
||||||
|
"Callable references can't have explicit type arguments"
|
||||||
|
}
|
||||||
|
assert(externalArgument == null) {
|
||||||
|
"External argument is not allowed not for function call: $externalArgument."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KotlinCallKind.UNSUPPORTED -> error("Call with UNSUPPORTED kind")
|
KotlinCallKind.UNSUPPORTED -> error("Call with UNSUPPORTED kind")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-24
@@ -34,6 +34,18 @@ abstract class InapplicableArgumentDiagnostic : KotlinCallDiagnostic(INAPPLICABL
|
|||||||
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class CallableReferenceInapplicableDiagnostic(
|
||||||
|
private val argument: CallableReferenceResolutionAtom,
|
||||||
|
applicability: CandidateApplicability = INAPPLICABLE
|
||||||
|
) : KotlinCallDiagnostic(applicability) {
|
||||||
|
override fun report(reporter: DiagnosticReporter) {
|
||||||
|
when (argument) {
|
||||||
|
is CallableReferenceKotlinCall -> reporter.onCall(this)
|
||||||
|
is CallableReferenceKotlinCallArgument -> reporter.onCallArgument(argument, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ArgumentsToParameterMapper
|
// ArgumentsToParameterMapper
|
||||||
class TooManyArguments(val argument: KotlinCallArgument, val descriptor: CallableDescriptor) :
|
class TooManyArguments(val argument: KotlinCallArgument, val descriptor: CallableDescriptor) :
|
||||||
KotlinCallDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) {
|
KotlinCallDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) {
|
||||||
@@ -99,38 +111,40 @@ class WrongCountOfTypeArguments(
|
|||||||
|
|
||||||
// Callable reference resolution
|
// Callable reference resolution
|
||||||
class CallableReferenceNotCompatible(
|
class CallableReferenceNotCompatible(
|
||||||
override val argument: CallableReferenceKotlinCallArgument,
|
argument: CallableReferenceResolutionAtom,
|
||||||
val candidate: CallableMemberDescriptor,
|
val candidate: CallableMemberDescriptor,
|
||||||
val expectedType: UnwrappedType?,
|
val expectedType: UnwrappedType?,
|
||||||
val callableReverenceType: UnwrappedType
|
val callableReverenceType: UnwrappedType
|
||||||
) : InapplicableArgumentDiagnostic()
|
) : CallableReferenceInapplicableDiagnostic(argument)
|
||||||
|
|
||||||
// supported by FE but not supported by BE now
|
// supported by FE but not supported by BE now
|
||||||
class CallableReferencesDefaultArgumentUsed(
|
class CallableReferencesDefaultArgumentUsed(
|
||||||
val argument: CallableReferenceKotlinCallArgument,
|
val argument: CallableReferenceResolutionAtom,
|
||||||
val candidate: CallableDescriptor,
|
val candidate: CallableDescriptor,
|
||||||
val defaultsCount: Int
|
val defaultsCount: Int
|
||||||
) : KotlinCallDiagnostic(IMPOSSIBLE_TO_GENERATE) {
|
) : CallableReferenceInapplicableDiagnostic(argument)
|
||||||
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class NotCallableMemberReference(
|
class NotCallableMemberReference(
|
||||||
override val argument: CallableReferenceKotlinCallArgument,
|
val argument: CallableReferenceResolutionAtom,
|
||||||
val candidate: CallableDescriptor
|
val candidate: CallableDescriptor
|
||||||
) : InapplicableArgumentDiagnostic()
|
) : CallableReferenceInapplicableDiagnostic(argument)
|
||||||
|
|
||||||
class NoneCallableReferenceCandidates(override val argument: CallableReferenceKotlinCallArgument) : InapplicableArgumentDiagnostic()
|
class NoneCallableReferenceCallCandidates(val argument: CallableReferenceKotlinCallArgument) :
|
||||||
|
CallableReferenceInapplicableDiagnostic(argument)
|
||||||
|
|
||||||
class CallableReferenceCandidatesAmbiguity(
|
class CallableReferenceCallCandidatesAmbiguity(
|
||||||
override val argument: CallableReferenceKotlinCallArgument,
|
val argument: CallableReferenceKotlinCallArgument,
|
||||||
val candidates: Collection<CallableReferenceCandidate>
|
val candidates: Collection<CallableReferenceResolutionCandidate>
|
||||||
) : InapplicableArgumentDiagnostic()
|
) : CallableReferenceInapplicableDiagnostic(argument)
|
||||||
|
|
||||||
class NotCallableExpectedType(
|
class NotCallableExpectedType(
|
||||||
override val argument: CallableReferenceKotlinCallArgument,
|
val argument: CallableReferenceKotlinCallArgument,
|
||||||
val expectedType: UnwrappedType,
|
val expectedType: UnwrappedType,
|
||||||
val notCallableTypeConstructor: TypeConstructor
|
val notCallableTypeConstructor: TypeConstructor
|
||||||
) : InapplicableArgumentDiagnostic()
|
) : CallableReferenceInapplicableDiagnostic(argument)
|
||||||
|
|
||||||
|
class AdaptedCallableReferenceIsUsedWithReflection(val argument: CallableReferenceResolutionAtom) :
|
||||||
|
CallableReferenceInapplicableDiagnostic(argument, RESOLVED_WITH_ERROR)
|
||||||
|
|
||||||
// SmartCasts
|
// SmartCasts
|
||||||
class SmartCastDiagnostic(
|
class SmartCastDiagnostic(
|
||||||
@@ -258,15 +272,6 @@ class CompatibilityWarningOnArgument(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AdaptedCallableReferenceIsUsedWithReflection(
|
|
||||||
val argument: CallableReferenceKotlinCallArgument,
|
|
||||||
) : KotlinCallDiagnostic(RESOLVED_WITH_ERROR) {
|
|
||||||
override fun report(reporter: DiagnosticReporter) {
|
|
||||||
reporter.onCallArgument(argument, this)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class KotlinConstraintSystemDiagnostic(
|
class KotlinConstraintSystemDiagnostic(
|
||||||
val error: ConstraintSystemError
|
val error: ConstraintSystemError
|
||||||
) : KotlinCallDiagnostic(error.applicability) {
|
) : KotlinCallDiagnostic(error.applicability) {
|
||||||
|
|||||||
@@ -58,6 +58,16 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
|
|||||||
PostponedVariablesInitializerResolutionPart
|
PostponedVariablesInitializerResolutionPart
|
||||||
),
|
),
|
||||||
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
|
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
|
||||||
|
CALLABLE_REFERENCE(
|
||||||
|
CheckVisibility,
|
||||||
|
NoTypeArguments,
|
||||||
|
NoArguments,
|
||||||
|
CreateFreshVariablesSubstitutor,
|
||||||
|
CollectionTypeVariableUsagesInfo,
|
||||||
|
CheckReceivers,
|
||||||
|
CheckCallableReference,
|
||||||
|
CompatibilityOfTypeVariableAsIntersectionTypePart
|
||||||
|
),
|
||||||
UNSUPPORTED();
|
UNSUPPORTED();
|
||||||
|
|
||||||
val resolutionSequence = resolutionPart.asList()
|
val resolutionSequence = resolutionPart.asList()
|
||||||
|
|||||||
+3
-1
@@ -81,7 +81,9 @@ open class MutableResolvedCallAtom(
|
|||||||
override val candidateDescriptor: CallableDescriptor, // original candidate descriptor
|
override val candidateDescriptor: CallableDescriptor, // original candidate descriptor
|
||||||
override val explicitReceiverKind: ExplicitReceiverKind,
|
override val explicitReceiverKind: ExplicitReceiverKind,
|
||||||
override val dispatchReceiverArgument: SimpleKotlinCallArgument?,
|
override val dispatchReceiverArgument: SimpleKotlinCallArgument?,
|
||||||
override val extensionReceiverArgument: SimpleKotlinCallArgument?
|
override val extensionReceiverArgument: SimpleKotlinCallArgument?,
|
||||||
|
open val reflectionCandidateType: UnwrappedType? = null,
|
||||||
|
open val candidate: CallableReferenceResolutionCandidate? = null
|
||||||
) : ResolvedCallAtom() {
|
) : ResolvedCallAtom() {
|
||||||
override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
||||||
override lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
override lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||||
|
|||||||
@@ -45,4 +45,7 @@ class TypeApproximator(
|
|||||||
// resultType <: type
|
// resultType <: type
|
||||||
fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? =
|
fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? =
|
||||||
super.approximateToSubType(type, conf) as UnwrappedType?
|
super.approximateToSubType(type, conf) as UnwrappedType?
|
||||||
|
|
||||||
|
fun approximateTo(type: UnwrappedType, conf: TypeApproximatorConfiguration, toSuperType: Boolean): UnwrappedType? =
|
||||||
|
if (toSuperType) approximateToSuperType(type, conf) else approximateToSubType(type, conf)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -19,8 +19,21 @@ val j1: J<String> = Impl("O")
|
|||||||
// would produce an error.
|
// would produce an error.
|
||||||
val x by j1::value
|
val x by j1::value
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.EXPRESSION, AnnotationTarget.FILE)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val j2: J<String> = Impl("K")
|
val j2: J<String> = Impl("K")
|
||||||
val y by j2::value
|
val y by j2::value
|
||||||
|
val y1 by @Anno j2::value
|
||||||
|
val y2 by (j2::value)
|
||||||
|
val y3 by (j2)::value
|
||||||
|
val y4 by ((j2)::value)
|
||||||
|
val y5 by (((j2)::value))
|
||||||
|
val y6 by @Anno() (((j2)::value))
|
||||||
|
val y7 by (@Anno() ((j2)::value))
|
||||||
|
val y8 by ((@Anno() (j2)::value))
|
||||||
|
val y9 by @Anno() ((@Anno() (j2)::value))
|
||||||
return x + y
|
return x + y
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val z = "K"
|
val z = "K"
|
||||||
open class A(val x: String) {
|
open class A(val x: String) {
|
||||||
|
|||||||
+1
-1
@@ -37,5 +37,5 @@ fun test() {
|
|||||||
val r7 = c::foo
|
val r7 = c::foo
|
||||||
checkSubtype<() -> String>(r7)
|
checkSubtype<() -> String>(r7)
|
||||||
|
|
||||||
C::<!UNRESOLVED_REFERENCE!>bar<!>
|
C::bar
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -6,10 +6,10 @@ public interface J {
|
|||||||
|
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|
||||||
fun f1(x: Int?): Any = x::<!UNSAFE_CALL!>hashCode<!>
|
fun f1(x: Int?): Any = x::<!TYPE_MISMATCH, UNSAFE_CALL!>hashCode<!>
|
||||||
fun <T> f2(t: T): Any = t::<!UNSAFE_CALL!>hashCode<!>
|
fun <T> f2(t: T): Any = t::<!TYPE_MISMATCH, UNSAFE_CALL!>hashCode<!>
|
||||||
fun <S : String?> f3(s: S): Any = s::<!UNSAFE_CALL!>hashCode<!>
|
fun <S : String?> f3(s: S): Any = s::<!TYPE_MISMATCH, UNSAFE_CALL!>hashCode<!>
|
||||||
fun <U : Any> f4(u: U?): Any = u::<!UNSAFE_CALL!>hashCode<!>
|
fun <U : Any> f4(u: U?): Any = u::<!TYPE_MISMATCH, UNSAFE_CALL!>hashCode<!>
|
||||||
fun f5(c: List<*>): Any = c[0]::<!UNSAFE_CALL!>hashCode<!>
|
fun f5(c: List<*>): Any = c[0]::<!TYPE_MISMATCH, UNSAFE_CALL!>hashCode<!>
|
||||||
|
|
||||||
fun f6(j: J): Any = j.platformString()::hashCode
|
fun f6(j: J): Any = j.platformString()::hashCode
|
||||||
|
|||||||
+3
-3
@@ -18,9 +18,9 @@ class Test {
|
|||||||
val <T> List<T>.b: Int? get() = size
|
val <T> List<T>.b: Int? get() = size
|
||||||
|
|
||||||
fun <T> List<T>.testCallable1(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::foo
|
fun <T> List<T>.testCallable1(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::foo
|
||||||
fun <T> List<T>.testCallable2(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<!>?::<!UNSAFE_CALL!>foo<!>
|
fun <T> List<T>.testCallable2(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<!>?::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
|
||||||
fun <T> List<T>.testCallable3(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T, Any><!>::<!UNSAFE_CALL!>foo<!>
|
fun <T> List<T>.testCallable3(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T, Any><!>::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
|
||||||
fun <T> List<T>.testCallable4(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T><!>?::<!UNSAFE_CALL!>foo<!>
|
fun <T> List<T>.testCallable4(): () -> Unit = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<T><!>?::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
|
||||||
|
|
||||||
fun <T> List<T>.testClassLiteral1() = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::class
|
fun <T> List<T>.testClassLiteral1() = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>a<T><!>::class
|
||||||
fun <T> List<T>.testClassLiteral2() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<!>?::class
|
fun <T> List<T>.testClassLiteral2() = <!EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>b<!>?::class
|
||||||
|
|||||||
+1
-1
@@ -4,4 +4,4 @@ package test
|
|||||||
fun nullableFun(): Int? = null
|
fun nullableFun(): Int? = null
|
||||||
fun Int.foo() {}
|
fun Int.foo() {}
|
||||||
|
|
||||||
val test1 = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>nullableFun()<!>?::<!UNSAFE_CALL!>foo<!>
|
val test1 = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!>nullableFun()<!>?::<!TYPE_MISMATCH, UNSAFE_CALL!>foo<!>
|
||||||
|
|||||||
+3
@@ -1,8 +1,11 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
fun <K> id(x: K) = x
|
||||||
|
|
||||||
class A1 {
|
class A1 {
|
||||||
fun <T> a1(t: T): Unit {}
|
fun <T> a1(t: T): Unit {}
|
||||||
fun test1(): (String) -> Unit = A1()::a1
|
fun test1(): (String) -> Unit = A1()::a1
|
||||||
|
fun test2(): (String) -> Unit = id(A1()::a1)
|
||||||
}
|
}
|
||||||
|
|
||||||
class A2 {
|
class A2 {
|
||||||
|
|||||||
+4
-1
@@ -1,8 +1,11 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
fun <K> id(x: K) = x
|
||||||
|
|
||||||
class A1 {
|
class A1 {
|
||||||
fun <T> a1(t: T): Unit {}
|
fun <T> a1(t: T): Unit {}
|
||||||
fun test1(): (String) -> Unit = A1()::a1
|
fun test1(): (String) -> Unit = A1()::a1
|
||||||
|
fun test2(): (String) -> Unit = id(A1()::a1)
|
||||||
}
|
}
|
||||||
|
|
||||||
class A2 {
|
class A2 {
|
||||||
@@ -19,6 +22,6 @@ class A3<T> {
|
|||||||
fun test2(): (T) -> Unit = A3<T>()::a3
|
fun test2(): (T) -> Unit = A3<T>()::a3
|
||||||
fun test3(): (Int) -> String = A3<Int>()::a3
|
fun test3(): (Int) -> String = A3<Int>()::a3
|
||||||
|
|
||||||
fun <R> test4(): (R) -> Unit = <!TYPE_MISMATCH!>this::<!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>a3<!><!>
|
fun <R> test4(): (R) -> Unit = this::<!TYPE_MISMATCH!>a3<!>
|
||||||
fun <R> test5(): (T) -> R = this::a3
|
fun <R> test5(): (T) -> R = this::a3
|
||||||
}
|
}
|
||||||
+3
@@ -1,11 +1,14 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ K> id(/*0*/ x: K): K
|
||||||
|
|
||||||
public final class A1 {
|
public final class A1 {
|
||||||
public constructor A1()
|
public constructor A1()
|
||||||
public final fun </*0*/ T> a1(/*0*/ t: T): kotlin.Unit
|
public final fun </*0*/ T> a1(/*0*/ t: T): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 hashCode(): kotlin.Int
|
||||||
public final fun test1(): (kotlin.String) -> kotlin.Unit
|
public final fun test1(): (kotlin.String) -> kotlin.Unit
|
||||||
|
public final fun test2(): (kotlin.String) -> kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,5 +5,5 @@ class Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
Foo::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!> <!SYNTAX!>< <!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!> ><!> <!SYNTAX!>(2 <!DEBUG_INFO_MISSING_UNRESOLVED!>+<!> 2)<!>
|
Foo::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!> <!SYNTAX!>< <!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!> ><!> <!SYNTAX!>(2 <!DEBUG_INFO_MISSING_UNRESOLVED!>+<!> 2)<!>
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/callableReference/referenceAdaptationHasDependencyOnApi14.fir.kt
Vendored
-18
@@ -1,18 +0,0 @@
|
|||||||
// !API_VERSION: 1.3
|
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
class A {
|
|
||||||
fun foo(s: String = "", vararg xs: Long): String = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun coercionToUnit(f: (A, String, LongArray) -> Unit): Any = f
|
|
||||||
fun varargToElement(f: (A, String, Long, Long) -> String): Any = f
|
|
||||||
fun defaultAndVararg(f: (A) -> String): Any = f
|
|
||||||
fun allOfTheAbove(f: (A) -> Unit): Any = f
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
coercionToUnit(A::foo)
|
|
||||||
varargToElement(A::foo)
|
|
||||||
defaultAndVararg(A::foo)
|
|
||||||
allOfTheAbove(A::foo)
|
|
||||||
}
|
|
||||||
Vendored
-18
@@ -1,18 +0,0 @@
|
|||||||
// !API_VERSION: 1.3
|
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
class A {
|
|
||||||
fun foo(s: String = "", vararg xs: Long): String = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun coercionToUnit(f: (A, String, LongArray) -> Unit): Any = f
|
|
||||||
fun varargToElement(f: (A, String, Long, Long) -> String): Any = f
|
|
||||||
fun defaultAndVararg(f: (A) -> String): Any = f
|
|
||||||
fun allOfTheAbove(f: (A) -> Unit): Any = f
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
coercionToUnit(<!TYPE_MISMATCH!>A::foo<!>)
|
|
||||||
varargToElement(<!TYPE_MISMATCH!>A::foo<!>)
|
|
||||||
defaultAndVararg(<!TYPE_MISMATCH!>A::foo<!>)
|
|
||||||
allOfTheAbove(<!TYPE_MISMATCH!>A::foo<!>)
|
|
||||||
}
|
|
||||||
Vendored
-15
@@ -1,15 +0,0 @@
|
|||||||
package
|
|
||||||
|
|
||||||
public fun allOfTheAbove(/*0*/ f: (A) -> kotlin.Unit): kotlin.Any
|
|
||||||
public fun coercionToUnit(/*0*/ f: (A, kotlin.String, kotlin.LongArray) -> kotlin.Unit): kotlin.Any
|
|
||||||
public fun defaultAndVararg(/*0*/ f: (A) -> kotlin.String): kotlin.Any
|
|
||||||
public fun test(): kotlin.Unit
|
|
||||||
public fun varargToElement(/*0*/ f: (A, kotlin.String, kotlin.Long, kotlin.Long) -> kotlin.String): kotlin.Any
|
|
||||||
|
|
||||||
public final class A {
|
|
||||||
public constructor A()
|
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
public final fun foo(/*0*/ s: kotlin.String = ..., /*1*/ vararg xs: kotlin.Long /*kotlin.LongArray*/): kotlin.String
|
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,6 @@ fun main() {
|
|||||||
// It must be OK
|
// It must be OK
|
||||||
val x18 = String?::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
val x18 = String?::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
||||||
val x19 = String::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
val x19 = String::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
||||||
val x20 = String?::<!UNSAFE_CALL!>hashCode<!>::hashCode
|
val x20 = String?::hashCode::hashCode
|
||||||
val x21 = kotlin.String?::<!UNSAFE_CALL!>hashCode<!>::hashCode
|
val x21 = kotlin.String?::hashCode::hashCode
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferences.kt
Vendored
+1
-1
@@ -381,7 +381,7 @@ fun poll65(): Flow<String> {
|
|||||||
|
|
||||||
fun poll66(): Flow<String> {
|
fun poll66(): Flow<String> {
|
||||||
return flow {
|
return flow {
|
||||||
val inv = ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!>
|
val inv = ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!>
|
||||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -383,7 +383,7 @@ fun poll65(): Flow<String> {
|
|||||||
|
|
||||||
fun poll66(): Flow<String> {
|
fun poll66(): Flow<String> {
|
||||||
return flow {
|
return flow {
|
||||||
val inv = ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!>
|
val inv = ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!>
|
||||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -23,38 +23,57 @@ fun <T> Foo2<T>.setX(y: T): T {
|
|||||||
|
|
||||||
fun Float.bar() {}
|
fun Float.bar() {}
|
||||||
|
|
||||||
|
fun <K> id(x: K) = x
|
||||||
|
|
||||||
fun test1() {
|
fun test1() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX<!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX<!>
|
||||||
|
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo<Float>(1f)
|
val foo = Foo<Float>(1f)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||||
|
|
||||||
foo.x.bar()
|
foo.x.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test2() {
|
fun test2() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX1<!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX1<!>
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX1<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo<Float>(1f)
|
val foo = Foo<Float>(1f)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||||
|
|
||||||
foo.x.bar()
|
foo.x.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test3() {
|
fun test3() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX<!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX<!>
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo2<Int>(1)
|
val foo = Foo2<Int>(1)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
|
|
||||||
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test4() {
|
fun test4() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX1<!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX1<!>
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX1<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo2<Int>(1)
|
val foo = Foo2<Int>(1)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
fooSetRef.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
|
|
||||||
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/inference/capturedTypes/approximateContravariantCapturedTypes.kt
Vendored
+21
-2
@@ -23,38 +23,57 @@ fun <T> Foo2<T>.setX(y: T): T {
|
|||||||
|
|
||||||
fun Float.bar() {}
|
fun Float.bar() {}
|
||||||
|
|
||||||
|
fun <K> id(x: K) = x
|
||||||
|
|
||||||
fun test1() {
|
fun test1() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>Foo<*>::<!TYPE_MISMATCH("Nothing; Foo<*>")!>setX<!><!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>Foo<*>::<!TYPE_MISMATCH, TYPE_MISMATCH!>setX<!><!>
|
||||||
|
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, CapturedType(*), CapturedType(*)>")!>Foo<*>::setX<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo<Float>(1f)
|
val foo = Foo<Float>(1f)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
fooSetRef.invoke(foo, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||||
|
|
||||||
foo.x.bar()
|
foo.x.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test2() {
|
fun test2() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>Foo<*>::setX1<!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>Foo<*>::setX1<!>
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo<*>, kotlin.Nothing, kotlin.Number>")!>Foo<*>::setX1<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo<Float>(1f)
|
val foo = Foo<Float>(1f)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
fooSetRef.invoke(foo, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||||
|
|
||||||
foo.x.bar()
|
foo.x.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test3() {
|
fun test3() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>Foo2<*>::<!TYPE_MISMATCH("Nothing; Foo2<*>")!>setX<!><!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>Foo2<*>::<!TYPE_MISMATCH, TYPE_MISMATCH!>setX<!><!>
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, CapturedType(*), CapturedType(*)>")!>Foo2<*>::setX<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo2<Int>(1)
|
val foo = Foo2<Int>(1)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!TYPE_MISMATCH!>""<!>)
|
fooSetRef.invoke(foo, <!TYPE_MISMATCH!>""<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!TYPE_MISMATCH!>""<!>)
|
||||||
|
|
||||||
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test4() {
|
fun test4() {
|
||||||
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>Foo2<*>::setX1<!>
|
val fooSetRef = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>Foo2<*>::setX1<!>
|
||||||
|
val fooSetRef2 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>id(
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<Foo2<*>, kotlin.Nothing, kotlin.Any?>")!>Foo2<*>::setX1<!>
|
||||||
|
)<!>
|
||||||
val foo = Foo2<Int>(1)
|
val foo = Foo2<Int>(1)
|
||||||
|
|
||||||
fooSetRef.invoke(foo, <!TYPE_MISMATCH!>""<!>)
|
fooSetRef.invoke(foo, <!TYPE_MISMATCH!>""<!>)
|
||||||
|
fooSetRef2.invoke(foo, <!TYPE_MISMATCH!>""<!>)
|
||||||
|
|
||||||
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
foo.x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>bar<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ K> id(/*0*/ x: K): K
|
||||||
public fun test1(): kotlin.Unit
|
public fun test1(): kotlin.Unit
|
||||||
public fun test2(): kotlin.Unit
|
public fun test2(): kotlin.Unit
|
||||||
public fun test3(): kotlin.Unit
|
public fun test3(): kotlin.Unit
|
||||||
|
|||||||
@@ -114,14 +114,14 @@ fun <T : Foo, R: Number, D: Int> main() {
|
|||||||
bar7(Foo::resolve) // OK
|
bar7(Foo::resolve) // OK
|
||||||
|
|
||||||
// with LHS and sentension function expected type
|
// with LHS and sentension function expected type
|
||||||
bar10<D>(<!TYPE_MISMATCH!>Int::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!><!>) // ERROR before the fix in NI
|
bar10<D>(<!TYPE_MISMATCH!>Int::x1<!>) // ERROR before the fix in NI
|
||||||
bar10<Int>(Int::x1) // OK
|
bar10<Int>(Int::x1) // OK
|
||||||
bar10(Int::x1) // OK
|
bar10(Int::x1) // OK
|
||||||
|
|
||||||
fun Int.ext() {
|
fun Int.ext() {
|
||||||
// with LHS and sentension function expected type
|
// with LHS and sentension function expected type
|
||||||
bar10<D>(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!>) // ERROR before the fix in NI
|
bar10<D>(<!TYPE_MISMATCH("KProperty1<TypeVariable(K), String>; KProperty0<String>")!>::x1<!>) // ERROR before the fix in NI
|
||||||
bar10<Int>(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!>) // OK
|
bar10<Int>(<!TYPE_MISMATCH("KProperty1<TypeVariable(K), String>; KProperty0<String>")!>::x1<!>) // OK
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar10<!>(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>x1<!>) // OK
|
bar10(<!TYPE_MISMATCH("KProperty1<TypeVariable(K), String>; KProperty0<String>")!>::x1<!>) // OK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -9,8 +9,8 @@ class Foo7<T>
|
|||||||
fun foo7() = null as Foo7<Int>
|
fun foo7() = null as Foo7<Int>
|
||||||
|
|
||||||
fun poll17(flag: Boolean): Any? {
|
fun poll17(flag: Boolean): Any? {
|
||||||
val inv = if (flag) { foo7() } else { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::Foo7<!> }
|
val inv = if (flag) { <!IMPLICIT_CAST_TO_ANY!>foo7()<!> } else { <!IMPLICIT_CAST_TO_ANY!>::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!><!> }
|
||||||
return <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
return inv
|
||||||
}
|
}
|
||||||
|
|
||||||
fun poll26(flag: Boolean): Any? {
|
fun poll26(flag: Boolean): Any? {
|
||||||
@@ -24,6 +24,6 @@ fun poll36(flag: Boolean): Any? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll56(): Any? {
|
fun poll56(): Any? {
|
||||||
val inv = try { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::Foo7<!> } catch (e: Exception) { foo7() } finally { foo7() }
|
val inv = try { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!> } catch (e: Exception) { foo7() } finally { foo7() }
|
||||||
return <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
return inv
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -18,6 +18,11 @@ class Foo6
|
|||||||
class Foo7<T>
|
class Foo7<T>
|
||||||
fun foo7() = null as Foo7<Int>
|
fun foo7() = null as Foo7<Int>
|
||||||
|
|
||||||
|
fun poll0(flag: Boolean) {
|
||||||
|
val inv = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction0<kotlin.Int>")!>if (flag) { ::bar2 } else { ::foo4 }<!>
|
||||||
|
inv()
|
||||||
|
}
|
||||||
|
|
||||||
fun poll1(flag: Boolean) {
|
fun poll1(flag: Boolean) {
|
||||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||||
inv()
|
inv()
|
||||||
|
|||||||
+15
-10
@@ -18,6 +18,11 @@ class Foo6
|
|||||||
class Foo7<T>
|
class Foo7<T>
|
||||||
fun foo7() = null as Foo7<Int>
|
fun foo7() = null as Foo7<Int>
|
||||||
|
|
||||||
|
fun poll0(flag: Boolean) {
|
||||||
|
val inv = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction0<kotlin.Int>")!>if (flag) { ::bar2 } else { ::foo4 }<!>
|
||||||
|
inv()
|
||||||
|
}
|
||||||
|
|
||||||
fun poll1(flag: Boolean) {
|
fun poll1(flag: Boolean) {
|
||||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||||
inv()
|
inv()
|
||||||
@@ -39,7 +44,7 @@ fun poll13(flag: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll14(flag: Boolean) {
|
fun poll14(flag: Boolean) {
|
||||||
val inv = if (flag) { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::bar4<!> } else { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::foo4<!> }
|
val inv = if (flag) { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar4<!> } else { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo4<!> }
|
||||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv<!>()
|
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +59,8 @@ fun poll16(flag: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll17(flag: Boolean) {
|
fun poll17(flag: Boolean) {
|
||||||
val inv = if (flag) { foo7() } else { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::Foo7<!> }
|
val inv = if (flag) { <!IMPLICIT_CAST_TO_ANY!>foo7()<!> } else { <!IMPLICIT_CAST_TO_ANY!>::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!><!> }
|
||||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
inv
|
||||||
}
|
}
|
||||||
|
|
||||||
fun poll2(flag: Boolean) {
|
fun poll2(flag: Boolean) {
|
||||||
@@ -144,7 +149,7 @@ fun poll42() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll43() {
|
fun poll43() {
|
||||||
val inv = try { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::bar4<!> } finally { ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo4<!> }
|
val inv = try { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar4<!> } finally { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo4<!> }
|
||||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv<!>()
|
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +164,7 @@ fun poll45() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll46() {
|
fun poll46() {
|
||||||
val inv = try { foo7() } finally { ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!> }
|
val inv = try { foo7() } finally { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!> }
|
||||||
inv
|
inv
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +184,7 @@ fun poll52() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll53() {
|
fun poll53() {
|
||||||
val inv = try { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::bar4<!> } catch (e: Exception) { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::foo4<!> } finally { ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo4<!> }
|
val inv = try { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar4<!> } catch (e: Exception) { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo4<!> } finally { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo4<!> }
|
||||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv<!>()
|
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,8 +199,8 @@ fun poll55() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll56() {
|
fun poll56() {
|
||||||
val inv = try { <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::Foo7<!> } catch (e: Exception) { foo7() } finally { foo7() }
|
val inv = try { ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!> } catch (e: Exception) { foo7() } finally { foo7() }
|
||||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
inv
|
||||||
}
|
}
|
||||||
|
|
||||||
fun poll6() {
|
fun poll6() {
|
||||||
@@ -214,7 +219,7 @@ fun poll62() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll63() {
|
fun poll63() {
|
||||||
val inv = ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar4<!>
|
val inv = ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar4<!>
|
||||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +234,7 @@ fun poll65() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun poll66() {
|
fun poll66() {
|
||||||
val inv = ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!>
|
val inv = ::<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!>
|
||||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>inv<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-74
@@ -1,74 +0,0 @@
|
|||||||
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
|
||||||
|
|
||||||
import A.Base.Companion.FromABaseCompanion
|
|
||||||
import B.Base.Companion.FromBBaseCompanion
|
|
||||||
import C.Base.Companion.FromCBaseCompanion
|
|
||||||
import D.Base.Companion.FromDBaseCompanion
|
|
||||||
|
|
||||||
// ===== Case 1: LHS is a class
|
|
||||||
//
|
|
||||||
object A {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
class FromABaseCompanion {
|
|
||||||
fun foo() = 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = FromABaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== Case 2: LHS is a class with companion object, function comes from class
|
|
||||||
|
|
||||||
object B {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
class FromBBaseCompanion {
|
|
||||||
fun foo() = 42
|
|
||||||
|
|
||||||
companion object {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = FromBBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== Case 3: LHS is a class with companion object, function comes from companion
|
|
||||||
|
|
||||||
object C {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
class FromCBaseCompanion {
|
|
||||||
companion object {
|
|
||||||
fun foo() = 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = FromCBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== Case 4: LHS is an object
|
|
||||||
|
|
||||||
object D {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
object FromDBaseCompanion {
|
|
||||||
fun foo() = 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = FromDBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
||||||
|
|
||||||
import A.Base.Companion.FromABaseCompanion
|
import A.Base.Companion.FromABaseCompanion
|
||||||
@@ -53,7 +54,7 @@ object C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
val a = FromCBaseCompanion::<!UNRESOLVED_REFERENCE!>foo<!>
|
val a = FromCBaseCompanion::foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -118,7 +118,7 @@ public object C {
|
|||||||
|
|
||||||
public final class Derived : C.Base {
|
public final class Derived : C.Base {
|
||||||
public constructor Derived()
|
public constructor Derived()
|
||||||
public final val a: [ERROR : Type for FromCBaseCompanion::foo]
|
public final val a: kotlin.reflect.KFunction1<C.Base.Companion.FromCBaseCompanion, kotlin.Int>
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|||||||
-69
@@ -1,69 +0,0 @@
|
|||||||
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
|
||||||
|
|
||||||
// ===== Case 1: LHS is a class
|
|
||||||
//
|
|
||||||
object A {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
class FromBaseCompanion {
|
|
||||||
fun foo() = 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = A.Base.Companion.FromBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== Case 2: LHS is a class with companion object, function comes from class
|
|
||||||
|
|
||||||
object B {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
class FromBaseCompanion {
|
|
||||||
fun foo() = 42
|
|
||||||
|
|
||||||
companion object {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = B.Base.Companion.FromBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== Case 3: LHS is a class with companion object, function comes from companion
|
|
||||||
|
|
||||||
object C {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
class FromBaseCompanion {
|
|
||||||
companion object {
|
|
||||||
fun foo() = 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = C.Base.Companion.FromBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==== Case 4: LHS is an object
|
|
||||||
|
|
||||||
object D {
|
|
||||||
open class Base {
|
|
||||||
companion object {
|
|
||||||
object FromBaseCompanion {
|
|
||||||
fun foo() = 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Derived : Base() {
|
|
||||||
val a = D.Base.Companion.FromBaseCompanion::foo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
||||||
|
|
||||||
// ===== Case 1: LHS is a class
|
// ===== Case 1: LHS is a class
|
||||||
@@ -48,7 +49,7 @@ object C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
val a = C.Base.Companion.FromBaseCompanion::<!UNRESOLVED_REFERENCE!>foo<!>
|
val a = C.Base.Companion.FromBaseCompanion::foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -118,7 +118,7 @@ public object C {
|
|||||||
|
|
||||||
public final class Derived : C.Base {
|
public final class Derived : C.Base {
|
||||||
public constructor Derived()
|
public constructor Derived()
|
||||||
public final val a: [ERROR : Type for C.Base.Companion.FromBaseCompanion::foo]
|
public final val a: kotlin.reflect.KFunction1<C.Base.Companion.FromBaseCompanion, kotlin.Int>
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ object C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
val a = <!DEPRECATED_ACCESS_BY_SHORT_NAME!>FromBaseCompanion<!>::<!UNRESOLVED_REFERENCE!>foo<!>
|
val a = <!DEPRECATED_ACCESS_BY_SHORT_NAME!>FromBaseCompanion<!>::foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -118,7 +118,7 @@ public object C {
|
|||||||
|
|
||||||
public final class Derived : C.Base {
|
public final class Derived : C.Base {
|
||||||
public constructor Derived()
|
public constructor Derived()
|
||||||
public final val a: [ERROR : Type for FromBaseCompanion::foo]
|
public final val a: kotlin.reflect.KFunction1<C.Base.Companion.FromBaseCompanion, kotlin.Int>
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ fun box() {
|
|||||||
|
|
||||||
println(::<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>bar<!>.name)
|
println(::<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>bar<!>.name)
|
||||||
println(::<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>baz<!>.name)
|
println(::<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>baz<!>.name)
|
||||||
println(<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>A<!>::f.name)
|
println(<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>A<!>::<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>f<!>.name)
|
||||||
|
|
||||||
B.<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>Nested<!>()
|
B.<!CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM!>Nested<!>()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ fun box() {
|
|||||||
B.<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>Nested<!>()
|
B.<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>Nested<!>()
|
||||||
|
|
||||||
println(::<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>bar<!>.name)
|
println(::<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>bar<!>.name)
|
||||||
println(<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>A<!>::f.name)
|
println(<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>A<!>::<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>f<!>.name)
|
||||||
|
|
||||||
boo<<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>B?<!>>(null)
|
boo<<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>B?<!>>(null)
|
||||||
<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>boo<!>(null as B?)
|
<!CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM!>boo<!>(null as B?)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
fun f(x: Any): String {
|
fun f(x: Any): String {
|
||||||
when {
|
when {
|
||||||
x is A<*> -> { // BLOCK
|
x is A<*> -> { // BLOCK
|
||||||
return x /*as A<*> */ /*as A<T> */.call(block = local fun <anonymous>(y: Any?): @FlexibleNullability String? {
|
return x /*as A<*> */.call(block = local fun <anonymous>(y: Any?): @FlexibleNullability String? {
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
/*-> @FlexibleNullability I<@FlexibleNullability T?>? */) /*!! String */
|
/*-> @FlexibleNullability I<Nothing>? */) /*!! String */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "Fail"
|
return "Fail"
|
||||||
|
|||||||
@@ -10,10 +10,9 @@ FILE fqName:<root> fileName:/genericSamSmartcast.kt
|
|||||||
RETURN type=kotlin.Nothing from='public final fun f (x: kotlin.Any): kotlin.String declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun f (x: kotlin.Any): kotlin.String declared in <root>'
|
||||||
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||||
CALL 'public open fun call (block: @[FlexibleNullability] <root>.A.I<@[FlexibleNullability] T of <root>.A?>?): @[FlexibleNullability] kotlin.String? declared in <root>.A' type=@[FlexibleNullability] kotlin.String? origin=null
|
CALL 'public open fun call (block: @[FlexibleNullability] <root>.A.I<@[FlexibleNullability] T of <root>.A?>?): @[FlexibleNullability] kotlin.String? declared in <root>.A' type=@[FlexibleNullability] kotlin.String? origin=null
|
||||||
$this: TYPE_OP type=<root>.A<T of <root>.A> origin=IMPLICIT_CAST typeOperand=<root>.A<T of <root>.A>
|
$this: TYPE_OP type=<root>.A<*> origin=IMPLICIT_CAST typeOperand=<root>.A<*>
|
||||||
TYPE_OP type=<root>.A<*> origin=IMPLICIT_CAST typeOperand=<root>.A<*>
|
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
|
||||||
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
|
block: TYPE_OP type=@[FlexibleNullability] <root>.A.I<kotlin.Nothing>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.A.I<kotlin.Nothing>?
|
||||||
block: TYPE_OP type=@[FlexibleNullability] <root>.A.I<@[FlexibleNullability] T of <root>.A?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.A.I<@[FlexibleNullability] T of <root>.A?>?
|
|
||||||
FUN_EXPR type=kotlin.Function1<kotlin.Any?, @[FlexibleNullability] kotlin.String?> origin=LAMBDA
|
FUN_EXPR type=kotlin.Function1<kotlin.Any?, @[FlexibleNullability] kotlin.String?> origin=LAMBDA
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:@[FlexibleNullability] kotlin.String?
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:@[FlexibleNullability] kotlin.String?
|
||||||
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
|
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
|
||||||
|
|||||||
-1
@@ -8,7 +8,6 @@ class A {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B(arg: String) defined in A.B
|
|
||||||
Resulting descriptor: constructor B(arg: String) defined in A.B
|
Resulting descriptor: constructor B(arg: String) defined in A.B
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
-1
@@ -9,7 +9,6 @@ class A {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B(x: String) defined in A.B
|
|
||||||
Resulting descriptor: constructor B(x: String) defined in A.B
|
Resulting descriptor: constructor B(x: String) defined in A.B
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ class A : B, C {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B(x: Int) defined in B
|
|
||||||
Resulting descriptor: constructor B(x: Int) defined in B
|
Resulting descriptor: constructor B(x: Int) defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ class A : B, C {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B() defined in B
|
|
||||||
Resulting descriptor: constructor B() defined in B
|
Resulting descriptor: constructor B() defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ class A : B, C {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B() defined in B
|
|
||||||
Resulting descriptor: constructor B() defined in B
|
Resulting descriptor: constructor B() defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ class A : B, C {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B(x: Int) defined in B
|
|
||||||
Resulting descriptor: constructor B(x: Int) defined in B
|
Resulting descriptor: constructor B(x: Int) defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
-1
@@ -10,7 +10,6 @@ class A : B, C {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B() defined in B
|
|
||||||
Resulting descriptor: constructor B() defined in B
|
Resulting descriptor: constructor B() defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
-1
@@ -11,7 +11,6 @@ class A : B, C {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B(x: String) defined in B
|
|
||||||
Resulting descriptor: constructor B(x: String) defined in B
|
Resulting descriptor: constructor B(x: String) defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ class A(x: Int) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor A(x: Int) defined in A
|
|
||||||
Resulting descriptor: constructor A(x: Int) defined in A
|
Resulting descriptor: constructor A(x: Int) defined in A
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ class A {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor A(x: Int) defined in A
|
|
||||||
Resulting descriptor: constructor A(x: Int) defined in A
|
Resulting descriptor: constructor A(x: Int) defined in A
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ class A(x: Double) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor A(x: String) defined in A
|
|
||||||
Resulting descriptor: constructor A(x: String) defined in A
|
Resulting descriptor: constructor A(x: String) defined in A
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ class A : B {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor B(vararg x: Int) defined in B
|
|
||||||
Resulting descriptor: constructor B(vararg x: Int) defined in B
|
Resulting descriptor: constructor B(vararg x: Int) defined in B
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ fun test() {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: fun foo(f: (Int) -> String): Unit defined in root package
|
|
||||||
Resulting descriptor: fun foo(f: (Int) -> String): Unit defined in root package
|
Resulting descriptor: fun foo(f: (Int) -> String): Unit defined in root package
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ annotation class MyA(val i: Int)
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor MyA(i: Int) defined in MyA
|
|
||||||
Resulting descriptor: constructor MyA(i: Int) defined in MyA
|
Resulting descriptor: constructor MyA(i: Int) defined in MyA
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
-1
@@ -5,7 +5,6 @@ class B: <caret>A() {}
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: constructor A() defined in A
|
|
||||||
Resulting descriptor: constructor A() defined in A
|
Resulting descriptor: constructor A() defined in A
|
||||||
|
|
||||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ fun foo(array: Array<Int>) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun get(index: Int): Int defined in kotlin.Array
|
|
||||||
Resulting descriptor: operator fun get(index: Int): Int defined in kotlin.Array
|
Resulting descriptor: operator fun get(index: Int): Int defined in kotlin.Array
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
-1
@@ -6,7 +6,6 @@ fun bar(f: Int.()->Unit) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
|
||||||
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
||||||
|
|
||||||
Explicit receiver kind = BOTH_RECEIVERS
|
Explicit receiver kind = BOTH_RECEIVERS
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ fun bar(f: ()->Unit) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun invoke(): Unit defined in kotlin.Function0
|
|
||||||
Resulting descriptor: operator fun invoke(): Unit defined in kotlin.Function0
|
Resulting descriptor: operator fun invoke(): Unit defined in kotlin.Function0
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
-1
@@ -10,7 +10,6 @@ interface A {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
|
||||||
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
||||||
|
|
||||||
Explicit receiver kind = BOTH_RECEIVERS
|
Explicit receiver kind = BOTH_RECEIVERS
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ fun test(a: A) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun invoke(Int): Int defined in kotlin.Function1
|
|
||||||
Resulting descriptor: operator fun invoke(Int): Int defined in kotlin.Function1
|
Resulting descriptor: operator fun invoke(Int): Int defined in kotlin.Function1
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ fun bar(f: Int.() -> Unit) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
|
||||||
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
||||||
|
|
||||||
Explicit receiver kind = BOTH_RECEIVERS
|
Explicit receiver kind = BOTH_RECEIVERS
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ fun bar(f: Int.() -> Unit, i: Int) {
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
|
||||||
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
Resulting descriptor: operator fun Int.invoke(): Unit defined in kotlin.Function1
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ fun test() = A<caret>(1)
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: fun invoke(i: Int): Int defined in A.Companion
|
|
||||||
Resulting descriptor: fun invoke(i: Int): Int defined in A.Companion
|
Resulting descriptor: fun invoke(i: Int): Int defined in A.Companion
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ fun test() = A.ONE<caret>(1)
|
|||||||
|
|
||||||
Resolved call:
|
Resolved call:
|
||||||
|
|
||||||
Candidate descriptor: fun invoke(i: Int): Int defined in A
|
|
||||||
Resulting descriptor: fun invoke(i: Int): Int defined in A
|
Resulting descriptor: fun invoke(i: Int): Int defined in A
|
||||||
|
|
||||||
Explicit receiver kind = DISPATCH_RECEIVER
|
Explicit receiver kind = DISPATCH_RECEIVER
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user