[NI] Support signed-unsigned conversions for K/Native
#KT-34545 Fixed
This commit is contained in:
+21
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnderKotlinPackage
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnderKotlinPackage
|
||||||
|
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||||
import org.jetbrains.kotlin.builtins.createFunctionType
|
import org.jetbrains.kotlin.builtins.createFunctionType
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
@@ -33,6 +34,8 @@ 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.util.CallMaker
|
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
@@ -287,4 +290,22 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
val context = topLevelCallContext ?: return
|
val context = topLevelCallContext ?: return
|
||||||
disableContractsInsideContractsBlock(atom.psiCall, resolvedAtom.candidateDescriptor, context.scope, trace)
|
disableContractsInsideContractsBlock(atom.psiCall, resolvedAtom.candidateDescriptor, context.scope, trace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun convertSignedConstantToUnsigned(argument: KotlinCallArgument): IntegerValueTypeConstant? {
|
||||||
|
val argumentExpression = argument.psiExpression ?: return null
|
||||||
|
return convertSignedConstantToUnsigned(argumentExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertSignedConstantToUnsigned(expression: KtExpression): IntegerValueTypeConstant? {
|
||||||
|
val constant = trace[BindingContext.COMPILE_TIME_VALUE, expression]
|
||||||
|
if (constant !is IntegerValueTypeConstant || !constantCanBeConvertedToUnsigned(constant)) return null
|
||||||
|
|
||||||
|
return with(IntegerValueTypeConstant) {
|
||||||
|
constant.convertToUnsignedConstant(moduleDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun constantCanBeConvertedToUnsigned(constant: CompileTimeConstant<*>): Boolean {
|
||||||
|
return !constant.isError && constant.parameters.isPure
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
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.name.Name
|
|
||||||
import org.jetbrains.kotlin.psi.KtSuperExpression
|
import org.jetbrains.kotlin.psi.KtSuperExpression
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
||||||
@@ -40,12 +39,11 @@ import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||||
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class KotlinResolutionStatelessCallbacksImpl(
|
class KotlinResolutionStatelessCallbacksImpl(
|
||||||
private val deprecationResolver: DeprecationResolver,
|
private val deprecationResolver: DeprecationResolver,
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
) : KotlinResolutionStatelessCallbacks {
|
) : KotlinResolutionStatelessCallbacks {
|
||||||
override fun isDescriptorFromSource(descriptor: CallableDescriptor) =
|
override fun isDescriptorFromSource(descriptor: CallableDescriptor) =
|
||||||
DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null
|
DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null
|
||||||
@@ -61,13 +59,13 @@ class KotlinResolutionStatelessCallbacksImpl(
|
|||||||
kotlinCall is PSIKotlinCallImpl && isSuperOrDelegatingConstructorCall(kotlinCall.psiCall)
|
kotlinCall is PSIKotlinCallImpl && isSuperOrDelegatingConstructorCall(kotlinCall.psiCall)
|
||||||
|
|
||||||
override fun isHiddenInResolution(
|
override fun isHiddenInResolution(
|
||||||
descriptor: DeclarationDescriptor, kotlinCall: KotlinCall, resolutionCallbacks: KotlinResolutionCallbacks
|
descriptor: DeclarationDescriptor, kotlinCall: KotlinCall, resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
) =
|
) =
|
||||||
deprecationResolver.isHiddenInResolution(
|
deprecationResolver.isHiddenInResolution(
|
||||||
descriptor,
|
descriptor,
|
||||||
(kotlinCall as? PSIKotlinCall)?.psiCall,
|
(kotlinCall as? PSIKotlinCall)?.psiCall,
|
||||||
(resolutionCallbacks as? KotlinResolutionCallbacksImpl)?.trace?.bindingContext,
|
(resolutionCallbacks as? KotlinResolutionCallbacksImpl)?.trace?.bindingContext,
|
||||||
isSuperOrDelegatingConstructorCall(kotlinCall)
|
isSuperOrDelegatingConstructorCall(kotlinCall),
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
|
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
|
||||||
@@ -84,13 +82,13 @@ class KotlinResolutionStatelessCallbacksImpl(
|
|||||||
|
|
||||||
override fun isApplicableCallForBuilderInference(
|
override fun isApplicableCallForBuilderInference(
|
||||||
descriptor: CallableDescriptor,
|
descriptor: CallableDescriptor,
|
||||||
languageVersionSettings: LanguageVersionSettings
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return org.jetbrains.kotlin.resolve.calls.inference.isApplicableCallForBuilderInference(descriptor, languageVersionSettings)
|
return org.jetbrains.kotlin.resolve.calls.inference.isApplicableCallForBuilderInference(descriptor, languageVersionSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createConstraintSystemForOverloadResolution(
|
override fun createConstraintSystemForOverloadResolution(
|
||||||
constraintInjector: ConstraintInjector, builtIns: KotlinBuiltIns
|
constraintInjector: ConstraintInjector, builtIns: KotlinBuiltIns,
|
||||||
): SimpleConstraintSystem {
|
): SimpleConstraintSystem {
|
||||||
return if (languageVersionSettings.getFlag(AnalysisFlags.constraintSystemForOverloadResolution).forNewInference())
|
return if (languageVersionSettings.getFlag(AnalysisFlags.constraintSystemForOverloadResolution).forNewInference())
|
||||||
SimpleConstraintSystemImpl(constraintInjector, builtIns)
|
SimpleConstraintSystemImpl(constraintInjector, builtIns)
|
||||||
|
|||||||
+73
-37
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.*
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.DiagnosticReporterByTrackingStrategy
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
|
||||||
@@ -42,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
||||||
@@ -77,7 +80,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate,
|
private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate,
|
||||||
private val smartCastManager: SmartCastManager,
|
private val smartCastManager: SmartCastManager,
|
||||||
private val typeApproximator: TypeApproximator,
|
private val typeApproximator: TypeApproximator,
|
||||||
private val missingSupertypesResolver: MissingSupertypesResolver
|
private val missingSupertypesResolver: MissingSupertypesResolver,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
|
private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
|
||||||
@@ -94,13 +97,13 @@ class KotlinToResolvedCallTransformer(
|
|||||||
|
|
||||||
fun <D : CallableDescriptor> onlyTransform(
|
fun <D : CallableDescriptor> onlyTransform(
|
||||||
resolvedCallAtom: ResolvedCallAtom,
|
resolvedCallAtom: ResolvedCallAtom,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
): ResolvedCall<D> = transformToResolvedCall(resolvedCallAtom, null, null, diagnostics)
|
): ResolvedCall<D> = transformToResolvedCall(resolvedCallAtom, null, null, diagnostics)
|
||||||
|
|
||||||
fun <D : CallableDescriptor> transformAndReport(
|
fun <D : CallableDescriptor> transformAndReport(
|
||||||
baseResolvedCall: CallResolutionResult,
|
baseResolvedCall: CallResolutionResult,
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
tracingStrategy: TracingStrategy
|
tracingStrategy: TracingStrategy,
|
||||||
): ResolvedCall<D> {
|
): ResolvedCall<D> {
|
||||||
return when (baseResolvedCall) {
|
return when (baseResolvedCall) {
|
||||||
is PartialCallResolutionResult -> {
|
is PartialCallResolutionResult -> {
|
||||||
@@ -129,7 +132,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
candidate,
|
candidate,
|
||||||
context.trace,
|
context.trace,
|
||||||
baseResolvedCall.diagnostics,
|
baseResolvedCall.diagnostics,
|
||||||
substitutor = resultSubstitutor
|
substitutor = resultSubstitutor,
|
||||||
)
|
)
|
||||||
|
|
||||||
forwardCallToInferenceSession(baseResolvedCall, context, stub, tracingStrategy)
|
forwardCallToInferenceSession(baseResolvedCall, context, stub, tracingStrategy)
|
||||||
@@ -141,7 +144,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
||||||
resultSubstitutor, context, this, expressionTypingServices, argumentTypeResolver,
|
resultSubstitutor, context, this, expressionTypingServices, argumentTypeResolver,
|
||||||
doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory,
|
doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory,
|
||||||
typeApproximator, missingSupertypesResolver
|
typeApproximator, missingSupertypesResolver,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (context.inferenceSession.shouldCompleteResolvedSubAtomsOf(candidate)) {
|
if (context.inferenceSession.shouldCompleteResolvedSubAtomsOf(candidate)) {
|
||||||
@@ -151,7 +154,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val resolvedCall = ktPrimitiveCompleter.completeResolvedCall(
|
val resolvedCall = ktPrimitiveCompleter.completeResolvedCall(
|
||||||
candidate, baseResolvedCall.completedDiagnostic(resultSubstitutor)
|
candidate, baseResolvedCall.completedDiagnostic(resultSubstitutor),
|
||||||
) as ResolvedCall<D>
|
) as ResolvedCall<D>
|
||||||
|
|
||||||
forwardCallToInferenceSession(baseResolvedCall, context, resolvedCall, tracingStrategy)
|
forwardCallToInferenceSession(baseResolvedCall, context, resolvedCall, tracingStrategy)
|
||||||
@@ -168,7 +171,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
baseResolvedCall: CallResolutionResult,
|
baseResolvedCall: CallResolutionResult,
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
tracingStrategy: TracingStrategy
|
tracingStrategy: TracingStrategy,
|
||||||
) {
|
) {
|
||||||
if (baseResolvedCall is CompletedCallResolutionResult) {
|
if (baseResolvedCall is CompletedCallResolutionResult) {
|
||||||
context.inferenceSession.addCompletedCallInfo(PSICompletedCallInfo(baseResolvedCall, context, resolvedCall, tracingStrategy))
|
context.inferenceSession.addCompletedCallInfo(PSICompletedCallInfo(baseResolvedCall, context, resolvedCall, tracingStrategy))
|
||||||
@@ -179,7 +182,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
candidate: ResolvedCallAtom,
|
candidate: ResolvedCallAtom,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>,
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
substitutor: NewTypeSubstitutor?
|
substitutor: NewTypeSubstitutor?,
|
||||||
): ResolvedCall<D> {
|
): ResolvedCall<D> {
|
||||||
val result = transformToResolvedCall<D>(candidate, trace, substitutor, diagnostics)
|
val result = transformToResolvedCall<D>(candidate, trace, substitutor, diagnostics)
|
||||||
val psiKotlinCall = candidate.atom.psiKotlinCall
|
val psiKotlinCall = candidate.atom.psiKotlinCall
|
||||||
@@ -194,14 +197,14 @@ class KotlinToResolvedCallTransformer(
|
|||||||
completedCallAtom: ResolvedCallAtom,
|
completedCallAtom: ResolvedCallAtom,
|
||||||
trace: BindingTrace?,
|
trace: BindingTrace?,
|
||||||
resultSubstitutor: NewTypeSubstitutor? = null, // if substitutor is not null, it means that this call is completed
|
resultSubstitutor: NewTypeSubstitutor? = null, // if substitutor is not null, it means that this call is completed
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
): ResolvedCall<D> {
|
): ResolvedCall<D> {
|
||||||
val psiKotlinCall = completedCallAtom.atom.psiKotlinCall
|
val psiKotlinCall = completedCallAtom.atom.psiKotlinCall
|
||||||
return if (psiKotlinCall is PSIKotlinCallForInvoke) {
|
return if (psiKotlinCall is PSIKotlinCallForInvoke) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
NewVariableAsFunctionResolvedCallImpl(
|
NewVariableAsFunctionResolvedCallImpl(
|
||||||
createOrGet(psiKotlinCall.variableCall.resolvedCall, trace, resultSubstitutor, diagnostics),
|
createOrGet(psiKotlinCall.variableCall.resolvedCall, trace, resultSubstitutor, diagnostics),
|
||||||
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics)
|
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics),
|
||||||
) as ResolvedCall<D>
|
) as ResolvedCall<D>
|
||||||
} else {
|
} else {
|
||||||
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics)
|
createOrGet(completedCallAtom, trace, resultSubstitutor, diagnostics)
|
||||||
@@ -212,7 +215,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
completedSimpleAtom: ResolvedCallAtom,
|
completedSimpleAtom: ResolvedCallAtom,
|
||||||
trace: BindingTrace?,
|
trace: BindingTrace?,
|
||||||
resultSubstitutor: NewTypeSubstitutor?,
|
resultSubstitutor: NewTypeSubstitutor?,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
): NewResolvedCallImpl<D> {
|
): NewResolvedCallImpl<D> {
|
||||||
if (trace != null) {
|
if (trace != null) {
|
||||||
val storedResolvedCall = completedSimpleAtom.atom.psiKotlinCall.getResolvedPsiKotlinCall<D>(trace)
|
val storedResolvedCall = completedSimpleAtom.atom.psiKotlinCall.getResolvedPsiKotlinCall<D>(trace)
|
||||||
@@ -249,14 +252,14 @@ class KotlinToResolvedCallTransformer(
|
|||||||
resolvedCall.resultingDescriptor.extensionReceiverParameter,
|
resolvedCall.resultingDescriptor.extensionReceiverParameter,
|
||||||
resolvedCall.extensionReceiver,
|
resolvedCall.extensionReceiver,
|
||||||
resolvedCall.explicitReceiverKind.isExtensionReceiver,
|
resolvedCall.explicitReceiverKind.isExtensionReceiver,
|
||||||
implicitInvokeCheck = false
|
implicitInvokeCheck = false,
|
||||||
)
|
)
|
||||||
context.checkReceiver(
|
context.checkReceiver(
|
||||||
resolvedCall,
|
resolvedCall,
|
||||||
resolvedCall.resultingDescriptor.dispatchReceiverParameter,
|
resolvedCall.resultingDescriptor.dispatchReceiverParameter,
|
||||||
resolvedCall.dispatchReceiver,
|
resolvedCall.dispatchReceiver,
|
||||||
resolvedCall.explicitReceiverKind.isDispatchReceiver,
|
resolvedCall.explicitReceiverKind.isDispatchReceiver,
|
||||||
implicitInvokeCheck = context.call is CallTransformer.CallForImplicitInvoke
|
implicitInvokeCheck = context.call is CallTransformer.CallForImplicitInvoke,
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -266,7 +269,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
receiverParameter: ReceiverParameterDescriptor?,
|
receiverParameter: ReceiverParameterDescriptor?,
|
||||||
receiverArgument: ReceiverValue?,
|
receiverArgument: ReceiverValue?,
|
||||||
isExplicitReceiver: Boolean,
|
isExplicitReceiver: Boolean,
|
||||||
implicitInvokeCheck: Boolean
|
implicitInvokeCheck: Boolean,
|
||||||
) {
|
) {
|
||||||
if (receiverParameter == null || receiverArgument == null) return
|
if (receiverParameter == null || receiverArgument == null) return
|
||||||
val safeAccess = isExplicitReceiver && !implicitInvokeCheck && resolvedCall.call.isSemanticallyEquivalentToSafeCall
|
val safeAccess = isExplicitReceiver && !implicitInvokeCheck && resolvedCall.call.isSemanticallyEquivalentToSafeCall
|
||||||
@@ -277,7 +280,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
fun runArgumentsChecks(
|
fun runArgumentsChecks(
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
resolvedCall: NewResolvedCallImpl<*>
|
resolvedCall: NewResolvedCallImpl<*>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
for (valueArgument in resolvedCall.call.valueArguments) {
|
for (valueArgument in resolvedCall.call.valueArguments) {
|
||||||
@@ -291,7 +294,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
?: getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context)
|
?: getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context)
|
||||||
Pair(
|
Pair(
|
||||||
expectedType,
|
expectedType,
|
||||||
CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument)
|
CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -303,12 +306,25 @@ class KotlinToResolvedCallTransformer(
|
|||||||
context.replaceDataFlowInfo(resolvedCall.dataFlowInfoForArguments.getInfo(valueArgument))
|
context.replaceDataFlowInfo(resolvedCall.dataFlowInfoForArguments.getInfo(valueArgument))
|
||||||
.replaceExpectedType(expectedType)
|
.replaceExpectedType(expectedType)
|
||||||
.replaceCallPosition(callPosition)
|
.replaceCallPosition(callPosition)
|
||||||
.replaceBindingTrace(trace)
|
|
||||||
|
|
||||||
// todo external argument
|
|
||||||
|
|
||||||
|
val constantConvertedArgument = resolvedCall.getArgumentTypeForConstantConvertedArgument(valueArgument)
|
||||||
val argumentExpression = valueArgument.getArgumentExpression() ?: continue
|
val argumentExpression = valueArgument.getArgumentExpression() ?: continue
|
||||||
updateRecordedType(argumentExpression, parameter, newContext, resolvedCall.isReallySuccess())
|
|
||||||
|
if (constantConvertedArgument != null) {
|
||||||
|
context.trace.record(BindingContext.COMPILE_TIME_VALUE, argumentExpression, constantConvertedArgument)
|
||||||
|
BindingContextUtils.updateRecordedType(
|
||||||
|
constantConvertedArgument.unknownIntegerType, argumentExpression, context.trace, false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRecordedType(
|
||||||
|
argumentExpression,
|
||||||
|
parameter,
|
||||||
|
newContext,
|
||||||
|
constantConvertedArgument?.unknownIntegerType?.unwrap(),
|
||||||
|
resolvedCall.isReallySuccess()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,14 +332,16 @@ class KotlinToResolvedCallTransformer(
|
|||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
parameter: ValueParameterDescriptor?,
|
parameter: ValueParameterDescriptor?,
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
reportErrorForTypeMismatch: Boolean
|
convertedArgumentType: UnwrappedType?,
|
||||||
|
reportErrorForTypeMismatch: Boolean,
|
||||||
): KotlinType? {
|
): KotlinType? {
|
||||||
val deparenthesized = expression.let {
|
val deparenthesized = expression.let {
|
||||||
KtPsiUtil.getLastElementDeparenthesized(it, context.statementFilter)
|
KtPsiUtil.getLastElementDeparenthesized(it, context.statementFilter)
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
val recordedType = context.trace.getType(deparenthesized)
|
val recordedType = context.trace.getType(deparenthesized)
|
||||||
var updatedType = getResolvedCallForArgumentExpression(deparenthesized, context)?.run {
|
|
||||||
|
var updatedType = convertedArgumentType ?: getResolvedCallForArgumentExpression(deparenthesized, context)?.run {
|
||||||
makeNullableTypeIfSafeReceiver(resultingDescriptor.returnType, context)
|
makeNullableTypeIfSafeReceiver(resultingDescriptor.returnType, context)
|
||||||
} ?: recordedType
|
} ?: recordedType
|
||||||
|
|
||||||
@@ -333,7 +351,6 @@ class KotlinToResolvedCallTransformer(
|
|||||||
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, deparenthesized) ?: updatedType
|
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, deparenthesized) ?: updatedType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var reportErrorDuringTypeCheck = reportErrorForTypeMismatch
|
var reportErrorDuringTypeCheck = reportErrorForTypeMismatch
|
||||||
|
|
||||||
if (parameter != null && ImplicitIntegerCoercion.isEnabledForParameter(parameter)) {
|
if (parameter != null && ImplicitIntegerCoercion.isEnabledForParameter(parameter)) {
|
||||||
@@ -342,12 +359,14 @@ class KotlinToResolvedCallTransformer(
|
|||||||
val generalNumberType = createTypeForConvertableConstant(argumentCompileTimeValue)
|
val generalNumberType = createTypeForConvertableConstant(argumentCompileTimeValue)
|
||||||
if (generalNumberType != null) {
|
if (generalNumberType != null) {
|
||||||
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
|
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
|
||||||
context.trace, context.statementFilter, context.expectedType, generalNumberType, expression
|
context.trace, context.statementFilter, context.expectedType, generalNumberType, expression,
|
||||||
)
|
)
|
||||||
reportErrorDuringTypeCheck = true
|
reportErrorDuringTypeCheck = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else if (convertedArgumentType != null) {
|
||||||
|
context.trace.report(Errors.SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED.on(deparenthesized))
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context)
|
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context)
|
||||||
@@ -362,7 +381,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
val typeConstructor = IntegerLiteralTypeConstructor(value, moduleDescriptor, constant.parameters)
|
val typeConstructor = IntegerLiteralTypeConstructor(value, moduleDescriptor, constant.parameters)
|
||||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||||
Annotations.EMPTY, typeConstructor, emptyList(), false,
|
Annotations.EMPTY, typeConstructor, emptyList(), false,
|
||||||
ErrorUtils.createErrorScope("Scope for number value type ($typeConstructor)", true)
|
ErrorUtils.createErrorScope("Scope for number value type ($typeConstructor)", true),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +396,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
updatedType: KotlinType?,
|
updatedType: KotlinType?,
|
||||||
recordedType: KotlinType?,
|
recordedType: KotlinType?,
|
||||||
argumentExpression: KtExpression,
|
argumentExpression: KtExpression,
|
||||||
context: BasicCallResolutionContext
|
context: BasicCallResolutionContext,
|
||||||
): KotlinType? {
|
): KotlinType? {
|
||||||
if ((!ErrorUtils.containsErrorType(recordedType) && recordedType == updatedType) || updatedType == null) return updatedType
|
if ((!ErrorUtils.containsErrorType(recordedType) && recordedType == updatedType) || updatedType == null) return updatedType
|
||||||
|
|
||||||
@@ -433,7 +452,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
) {
|
) {
|
||||||
when (resolvedCall) {
|
when (resolvedCall) {
|
||||||
is NewResolvedCallImpl ->
|
is NewResolvedCallImpl ->
|
||||||
@@ -471,7 +490,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
completedCallAtom: ResolvedCallAtom,
|
completedCallAtom: ResolvedCallAtom,
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
) {
|
) {
|
||||||
val trackingTrace = TrackingBindingTrace(trace)
|
val trackingTrace = TrackingBindingTrace(trace)
|
||||||
val newContext = context.replaceBindingTrace(trackingTrace)
|
val newContext = context.replaceBindingTrace(trackingTrace)
|
||||||
@@ -487,7 +506,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
completedCallAtom.atom.psiKotlinCall,
|
completedCallAtom.atom.psiKotlinCall,
|
||||||
context.dataFlowValueFactory,
|
context.dataFlowValueFactory,
|
||||||
allDiagnostics,
|
allDiagnostics,
|
||||||
smartCastManager
|
smartCastManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
for (diagnostic in allDiagnostics) {
|
for (diagnostic in allDiagnostics) {
|
||||||
@@ -497,7 +516,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
if (diagnostic is ResolvedUsingDeprecatedVisibility) {
|
if (diagnostic is ResolvedUsingDeprecatedVisibility) {
|
||||||
reportResolvedUsingDeprecatedVisibility(
|
reportResolvedUsingDeprecatedVisibility(
|
||||||
completedCallAtom.atom.psiKotlinCall.psiCall, completedCallAtom.candidateDescriptor,
|
completedCallAtom.atom.psiKotlinCall.psiCall, completedCallAtom.candidateDescriptor,
|
||||||
resultingDescriptor, diagnostic, trace
|
resultingDescriptor, diagnostic, trace,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +611,7 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
|||||||
|
|
||||||
protected abstract fun argumentToParameterMap(
|
protected abstract fun argumentToParameterMap(
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
||||||
): Map<ValueArgument, ArgumentMatchImpl>
|
): Map<ValueArgument, ArgumentMatchImpl>
|
||||||
|
|
||||||
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
|
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
|
||||||
@@ -623,7 +642,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
val resolvedCallAtom: ResolvedCallAtom,
|
val resolvedCallAtom: ResolvedCallAtom,
|
||||||
substitutor: NewTypeSubstitutor?,
|
substitutor: NewTypeSubstitutor?,
|
||||||
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
private val typeApproximator: TypeApproximator
|
private val typeApproximator: TypeApproximator,
|
||||||
) : NewAbstractResolvedCall<D>() {
|
) : NewAbstractResolvedCall<D>() {
|
||||||
var isCompleted = false
|
var isCompleted = false
|
||||||
private set
|
private set
|
||||||
@@ -635,6 +654,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue
|
private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue
|
||||||
private var smartCastDispatchReceiverType: KotlinType? = null
|
private var smartCastDispatchReceiverType: KotlinType? = null
|
||||||
private var expedtedTypeForSamConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
|
private var expedtedTypeForSamConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
|
||||||
|
private var argumentTypeForConstantConvertedMap: MutableMap<KtExpression, IntegerValueTypeConstant>? = null
|
||||||
|
|
||||||
|
|
||||||
override val kotlinCall: KotlinCall get() = resolvedCallAtom.atom
|
override val kotlinCall: KotlinCall get() = resolvedCallAtom.atom
|
||||||
@@ -662,7 +682,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
if (extensionReceiver is ImplicitClassReceiver) {
|
if (extensionReceiver is ImplicitClassReceiver) {
|
||||||
extensionReceiver = CastImplicitClassReceiver(
|
extensionReceiver = CastImplicitClassReceiver(
|
||||||
(extensionReceiver as ImplicitClassReceiver).classDescriptor,
|
(extensionReceiver as ImplicitClassReceiver).classDescriptor,
|
||||||
smartCastExtensionReceiverType
|
smartCastExtensionReceiverType,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -715,6 +735,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateExpectedTypeForSamConvertedArgumentMap(substitutor)
|
calculateExpectedTypeForSamConvertedArgumentMap(substitutor)
|
||||||
|
calculateExpectedTypeForConstantConvertedArgumentMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.withNullabilityFromExplicitTypeArgument(typeArgument: SimpleTypeArgument) =
|
private fun KotlinType.withNullabilityFromExplicitTypeArgument(typeArgument: SimpleTypeArgument) =
|
||||||
@@ -722,7 +743,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
|
|
||||||
private fun getSubstitutorWithoutFlexibleTypes(
|
private fun getSubstitutorWithoutFlexibleTypes(
|
||||||
currentSubstitutor: NewTypeSubstitutor?,
|
currentSubstitutor: NewTypeSubstitutor?,
|
||||||
explicitTypeArguments: List<SimpleTypeArgument>
|
explicitTypeArguments: List<SimpleTypeArgument>,
|
||||||
): NewTypeSubstitutor? {
|
): NewTypeSubstitutor? {
|
||||||
if (currentSubstitutor !is NewTypeSubstitutorByConstructorMap || explicitTypeArguments.isEmpty()) return currentSubstitutor
|
if (currentSubstitutor !is NewTypeSubstitutorByConstructorMap || explicitTypeArguments.isEmpty()) return currentSubstitutor
|
||||||
if (!currentSubstitutor.map.any { (_, value) -> value.isFlexible() }) return currentSubstitutor
|
if (!currentSubstitutor.map.any { (_, value) -> value.isFlexible() }) return currentSubstitutor
|
||||||
@@ -747,7 +768,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
val explicitTypeArguments = resolvedCallAtom.atom.typeArguments.filterIsInstance<SimpleTypeArgument>()
|
val explicitTypeArguments = resolvedCallAtom.atom.typeArguments.filterIsInstance<SimpleTypeArgument>()
|
||||||
|
|
||||||
candidateDescriptor.substituteInferredVariablesAndApproximate(
|
candidateDescriptor.substituteInferredVariablesAndApproximate(
|
||||||
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments)
|
getSubstitutorWithoutFlexibleTypes(substitutor, explicitTypeArguments),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FunctionDescriptor -> candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
is FunctionDescriptor -> candidateDescriptor.substituteInferredVariablesAndApproximate(substitutor)
|
||||||
@@ -774,9 +795,24 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
.substituteAndApproximateTypes(compositeSubstitutor, typeApproximator)
|
.substituteAndApproximateTypes(compositeSubstitutor, typeApproximator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getArgumentTypeForConstantConvertedArgument(valueArgument: ValueArgument): IntegerValueTypeConstant? {
|
||||||
|
val expression = valueArgument.getArgumentExpression() ?: return null
|
||||||
|
return argumentTypeForConstantConvertedMap?.get(expression)
|
||||||
|
}
|
||||||
|
|
||||||
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
||||||
expedtedTypeForSamConvertedArgumentMap?.get(valueArgument)
|
expedtedTypeForSamConvertedArgumentMap?.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?) {
|
private fun calculateExpectedTypeForSamConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
|
||||||
if (resolvedCallAtom.argumentsWithConversion.isEmpty()) return
|
if (resolvedCallAtom.argumentsWithConversion.isEmpty()) return
|
||||||
|
|
||||||
@@ -791,7 +827,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
|
|
||||||
override fun argumentToParameterMap(
|
override fun argumentToParameterMap(
|
||||||
resultingDescriptor: CallableDescriptor,
|
resultingDescriptor: CallableDescriptor,
|
||||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>,
|
||||||
): Map<ValueArgument, ArgumentMatchImpl> {
|
): Map<ValueArgument, ArgumentMatchImpl> {
|
||||||
val argumentErrors = collectErrorPositions()
|
val argumentErrors = collectErrorPositions()
|
||||||
|
|
||||||
@@ -846,7 +882,7 @@ fun ResolutionCandidateApplicability.toResolutionStatus(): ResolutionStatus = wh
|
|||||||
|
|
||||||
class NewVariableAsFunctionResolvedCallImpl(
|
class NewVariableAsFunctionResolvedCallImpl(
|
||||||
override val variableCall: NewResolvedCallImpl<VariableDescriptor>,
|
override val variableCall: NewResolvedCallImpl<VariableDescriptor>,
|
||||||
override val functionCall: NewResolvedCallImpl<FunctionDescriptor>
|
override val functionCall: NewResolvedCallImpl<FunctionDescriptor>,
|
||||||
) : VariableAsFunctionResolvedCall, ResolvedCall<FunctionDescriptor> by functionCall {
|
) : VariableAsFunctionResolvedCall, ResolvedCall<FunctionDescriptor> by functionCall {
|
||||||
val baseCall get() = functionCall.resolvedCallAtom.atom.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
val baseCall get() = functionCall.resolvedCallAtom.atom.psiKotlinCall.cast<PSIKotlinCallForInvoke>().baseCall
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -201,7 +201,11 @@ class ResolvedAtomCompleter(
|
|||||||
|
|
||||||
val argumentExpression = resultValueArgument.valueArgument.getArgumentExpression() ?: continue
|
val argumentExpression = resultValueArgument.valueArgument.getArgumentExpression() ?: continue
|
||||||
kotlinToResolvedCallTransformer.updateRecordedType(
|
kotlinToResolvedCallTransformer.updateRecordedType(
|
||||||
argumentExpression, parameter = null, context = newContext, reportErrorForTypeMismatch = true
|
argumentExpression,
|
||||||
|
parameter = null,
|
||||||
|
context = newContext,
|
||||||
|
reportErrorForTypeMismatch = true,
|
||||||
|
convertedArgumentType = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -19,6 +19,7 @@ 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.ImplicitScopeTower
|
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.StubType
|
import org.jetbrains.kotlin.types.StubType
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
@@ -75,4 +76,6 @@ interface KotlinResolutionCallbacks {
|
|||||||
fun getExpectedTypeFromAsExpressionAndRecordItInTrace(resolvedAtom: ResolvedCallAtom): UnwrappedType?
|
fun getExpectedTypeFromAsExpressionAndRecordItInTrace(resolvedAtom: ResolvedCallAtom): UnwrappedType?
|
||||||
|
|
||||||
fun disableContractsIfNecessary(resolvedAtom: ResolvedCallAtom)
|
fun disableContractsIfNecessary(resolvedAtom: ResolvedCallAtom)
|
||||||
|
|
||||||
|
fun convertSignedConstantToUnsigned(argument: KotlinCallArgument): IntegerValueTypeConstant?
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -35,10 +35,11 @@ fun resolveKtPrimitive(
|
|||||||
argument: KotlinCallArgument,
|
argument: KotlinCallArgument,
|
||||||
expectedType: UnwrappedType?,
|
expectedType: UnwrappedType?,
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||||
isReceiver: Boolean
|
isReceiver: Boolean,
|
||||||
|
convertedType: UnwrappedType?
|
||||||
): ResolvedAtom = when (argument) {
|
): ResolvedAtom = when (argument) {
|
||||||
is SimpleKotlinCallArgument ->
|
is SimpleKotlinCallArgument ->
|
||||||
checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver)
|
checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver, convertedType)
|
||||||
|
|
||||||
is LambdaKotlinCallArgument ->
|
is LambdaKotlinCallArgument ->
|
||||||
preprocessLambdaArgument(csBuilder, argument, expectedType, diagnosticsHolder)
|
preprocessLambdaArgument(csBuilder, argument, expectedType, diagnosticsHolder)
|
||||||
|
|||||||
+1
-1
@@ -132,7 +132,7 @@ class PostponedArgumentsAnalyzer(
|
|||||||
|
|
||||||
val subResolvedKtPrimitives = returnArgumentsInfo.nonErrorArguments.map {
|
val subResolvedKtPrimitives = returnArgumentsInfo.nonErrorArguments.map {
|
||||||
resolveKtPrimitive(
|
resolveKtPrimitive(
|
||||||
c.getBuilder(), it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false
|
c.getBuilder(), it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false, convertedType = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||||
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.types.*
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
|
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
|
||||||
@@ -288,7 +290,40 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
|
|||||||
isReceiver: Boolean
|
isReceiver: Boolean
|
||||||
) {
|
) {
|
||||||
val expectedType = candidateParameter?.let { prepareExpectedType(argument, candidateParameter) }
|
val expectedType = candidateParameter?.let { prepareExpectedType(argument, candidateParameter) }
|
||||||
addResolvedKtPrimitive(resolveKtPrimitive(csBuilder, argument, expectedType, this, isReceiver))
|
val convertedArgument = if (expectedType != null && shouldRunConversionForConstants(expectedType)) {
|
||||||
|
val convertedConstant = resolutionCallbacks.convertSignedConstantToUnsigned(argument)
|
||||||
|
if (convertedConstant != null) {
|
||||||
|
resolvedCall.registerArgumentWithConstantConversion(argument, convertedConstant)
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedConstant
|
||||||
|
} else null
|
||||||
|
|
||||||
|
addResolvedKtPrimitive(
|
||||||
|
resolveKtPrimitive(
|
||||||
|
csBuilder,
|
||||||
|
argument,
|
||||||
|
expectedType,
|
||||||
|
this,
|
||||||
|
isReceiver,
|
||||||
|
convertedArgument?.unknownIntegerType?.unwrap()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinResolutionCandidate.shouldRunConversionForConstants(expectedType: UnwrappedType): Boolean {
|
||||||
|
if (UnsignedTypes.isUnsignedType(expectedType)) return true
|
||||||
|
if (csBuilder.isTypeVariable(expectedType)) {
|
||||||
|
val variableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[expectedType.constructor] ?: return false
|
||||||
|
return variableWithConstraints.constraints.any {
|
||||||
|
it.kind == ConstraintKind.EQUALITY &&
|
||||||
|
it.position.from is ExplicitTypeParameterConstraintPosition &&
|
||||||
|
UnsignedTypes.isUnsignedType(it.type as UnwrappedType)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinResolutionCandidate.prepareExpectedType(
|
private fun KotlinResolutionCandidate.prepareExpectedType(
|
||||||
|
|||||||
+6
-4
@@ -37,9 +37,10 @@ fun checkSimpleArgument(
|
|||||||
argument: SimpleKotlinCallArgument,
|
argument: SimpleKotlinCallArgument,
|
||||||
expectedType: UnwrappedType?,
|
expectedType: UnwrappedType?,
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||||
isReceiver: Boolean
|
isReceiver: Boolean,
|
||||||
|
convertedType: UnwrappedType?
|
||||||
): ResolvedAtom = when (argument) {
|
): ResolvedAtom = when (argument) {
|
||||||
is ExpressionKotlinCallArgument -> checkExpressionArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver)
|
is ExpressionKotlinCallArgument -> checkExpressionArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver, convertedType)
|
||||||
is SubKotlinCallArgument -> checkSubCallArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver)
|
is SubKotlinCallArgument -> checkSubCallArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver)
|
||||||
else -> unexpectedArgument(argument)
|
else -> unexpectedArgument(argument)
|
||||||
}
|
}
|
||||||
@@ -49,13 +50,14 @@ private fun checkExpressionArgument(
|
|||||||
expressionArgument: ExpressionKotlinCallArgument,
|
expressionArgument: ExpressionKotlinCallArgument,
|
||||||
expectedType: UnwrappedType?,
|
expectedType: UnwrappedType?,
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||||
isReceiver: Boolean
|
isReceiver: Boolean,
|
||||||
|
convertedType: UnwrappedType?
|
||||||
): ResolvedAtom {
|
): ResolvedAtom {
|
||||||
val resolvedExpression = ResolvedExpressionAtom(expressionArgument)
|
val resolvedExpression = ResolvedExpressionAtom(expressionArgument)
|
||||||
if (expectedType == null) return resolvedExpression
|
if (expectedType == null) return resolvedExpression
|
||||||
|
|
||||||
// todo run this approximation only once for call
|
// todo run this approximation only once for call
|
||||||
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.receiver.stableType, expectedType)
|
val argumentType = convertedType ?: captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.receiver.stableType, expectedType)
|
||||||
|
|
||||||
fun unstableSmartCastOrSubtypeError(
|
fun unstableSmartCastOrSubtypeError(
|
||||||
unstableType: UnwrappedType?, actualExpectedType: UnwrappedType, position: ConstraintPosition
|
unstableType: UnwrappedType?, actualExpectedType: UnwrappedType, position: ConstraintPosition
|
||||||
|
|||||||
+2
-1
@@ -144,6 +144,7 @@ class SimpleCandidateFactory(
|
|||||||
if (ErrorUtils.isError(descriptor)) {
|
if (ErrorUtils.isError(descriptor)) {
|
||||||
return KotlinResolutionCandidate(
|
return KotlinResolutionCandidate(
|
||||||
callComponents,
|
callComponents,
|
||||||
|
resolutionCallbacks,
|
||||||
callableReferenceResolver,
|
callableReferenceResolver,
|
||||||
scopeTower,
|
scopeTower,
|
||||||
baseSystem,
|
baseSystem,
|
||||||
@@ -154,7 +155,7 @@ class SimpleCandidateFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val candidate = KotlinResolutionCandidate(
|
val candidate = KotlinResolutionCandidate(
|
||||||
callComponents, callableReferenceResolver, scopeTower, baseSystem, resolvedKtCall, knownSubstitutor
|
callComponents, resolutionCallbacks, callableReferenceResolver, scopeTower, baseSystem, resolvedKtCall, knownSubstitutor
|
||||||
)
|
)
|
||||||
|
|
||||||
initialDiagnostics.forEach(candidate::addDiagnostic)
|
initialDiagnostics.forEach(candidate::addDiagnostic)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintError
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForCallableReferenceReturnType
|
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForCallableReferenceReturnType
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
|
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
@@ -70,6 +71,7 @@ abstract class ResolvedCallAtom : ResolvedAtom() {
|
|||||||
abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
||||||
abstract val knownParametersSubstitutor: TypeSubstitutor
|
abstract val knownParametersSubstitutor: TypeSubstitutor
|
||||||
abstract val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
abstract val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
||||||
|
abstract val argumentsWithConstantConversion: Map<KotlinCallArgument, IntegerValueTypeConstant>
|
||||||
}
|
}
|
||||||
|
|
||||||
class SamConversionDescription(
|
class SamConversionDescription(
|
||||||
|
|||||||
+15
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceResolver
|
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.components.NewConstraintSystemImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper
|
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||||
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
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.constants.IntegerValueTypeConstant
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|
||||||
|
|
||||||
@@ -65,6 +67,7 @@ fun KotlinDiagnosticsHolder.addDiagnosticIfNotNull(diagnostic: KotlinCallDiagnos
|
|||||||
*/
|
*/
|
||||||
class KotlinResolutionCandidate(
|
class KotlinResolutionCandidate(
|
||||||
val callComponents: KotlinCallComponents,
|
val callComponents: KotlinCallComponents,
|
||||||
|
val resolutionCallbacks: KotlinResolutionCallbacks,
|
||||||
val callableReferenceResolver: CallableReferenceResolver,
|
val callableReferenceResolver: CallableReferenceResolver,
|
||||||
val scopeTower: ImplicitScopeTower,
|
val scopeTower: ImplicitScopeTower,
|
||||||
private val baseSystem: ConstraintStorage,
|
private val baseSystem: ConstraintStorage,
|
||||||
@@ -182,6 +185,7 @@ class MutableResolvedCallAtom(
|
|||||||
override lateinit var knownParametersSubstitutor: TypeSubstitutor
|
override lateinit var knownParametersSubstitutor: TypeSubstitutor
|
||||||
lateinit var argumentToCandidateParameter: Map<KotlinCallArgument, ValueParameterDescriptor>
|
lateinit var argumentToCandidateParameter: Map<KotlinCallArgument, ValueParameterDescriptor>
|
||||||
private var samAdapterMap: HashMap<KotlinCallArgument, SamConversionDescription>? = null
|
private var samAdapterMap: HashMap<KotlinCallArgument, SamConversionDescription>? = null
|
||||||
|
private var signedUnsignedConstantConversions: HashMap<KotlinCallArgument, IntegerValueTypeConstant>? = null
|
||||||
|
|
||||||
val hasSamConversion: Boolean
|
val hasSamConversion: Boolean
|
||||||
get() = samAdapterMap != null
|
get() = samAdapterMap != null
|
||||||
@@ -189,6 +193,9 @@ class MutableResolvedCallAtom(
|
|||||||
override val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
override val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
||||||
get() = samAdapterMap ?: emptyMap()
|
get() = samAdapterMap ?: emptyMap()
|
||||||
|
|
||||||
|
override val argumentsWithConstantConversion: Map<KotlinCallArgument, IntegerValueTypeConstant>
|
||||||
|
get() = signedUnsignedConstantConversions ?: emptyMap()
|
||||||
|
|
||||||
fun registerArgumentWithSamConversion(argument: KotlinCallArgument, samConversionDescription: SamConversionDescription) {
|
fun registerArgumentWithSamConversion(argument: KotlinCallArgument, samConversionDescription: SamConversionDescription) {
|
||||||
if (samAdapterMap == null)
|
if (samAdapterMap == null)
|
||||||
samAdapterMap = hashMapOf()
|
samAdapterMap = hashMapOf()
|
||||||
@@ -196,6 +203,14 @@ class MutableResolvedCallAtom(
|
|||||||
samAdapterMap!![argument] = samConversionDescription
|
samAdapterMap!![argument] = samConversionDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun registerArgumentWithConstantConversion(argument: KotlinCallArgument, convertedConstant: IntegerValueTypeConstant) {
|
||||||
|
if (signedUnsignedConstantConversions == null)
|
||||||
|
signedUnsignedConstantConversions = hashMapOf()
|
||||||
|
|
||||||
|
signedUnsignedConstantConversions!![argument] = convertedConstant
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override public fun setAnalyzedResults(subResolvedAtoms: List<ResolvedAtom>) {
|
override public fun setAnalyzedResults(subResolvedAtoms: List<ResolvedAtom>) {
|
||||||
super.setAnalyzedResults(subResolvedAtoms)
|
super.setAnalyzedResults(subResolvedAtoms)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -1,5 +1,6 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_VARIABLE
|
||||||
// !CHECK_TYPE
|
// !CHECK_TYPE
|
||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
|
||||||
// Here we mostly trying to fix behaviour in order to track changes in inference rules for unsigned types later
|
// Here we mostly trying to fix behaviour in order to track changes in inference rules for unsigned types later
|
||||||
|
|
||||||
@@ -9,9 +10,11 @@ fun <K> select(x: K, y: K): K = TODO()
|
|||||||
fun takeUByte(u: UByte) {}
|
fun takeUByte(u: UByte) {}
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
select(1, 1u) checkType { _<Comparable<*>>() }
|
<!NI;TYPE_MISMATCH!>select<!>(1, 1u) checkType { <!NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Comparable<*>>() }
|
||||||
takeUByte(<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>id(1)<!>)
|
takeUByte(<!NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>id(1)<!>)
|
||||||
|
|
||||||
1 <!NONE_APPLICABLE!>+<!> 1u
|
1 <!NONE_APPLICABLE!>+<!> 1u
|
||||||
(1u + <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>) checkType { _<UInt>() }
|
(1u + <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>) checkType { _<UInt>() }
|
||||||
|
|
||||||
|
id<UInt>(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
|
||||||
fun takeUByte(u: UByte) {}
|
fun takeUByte(u: UByte) {}
|
||||||
fun takeUShort(u: UShort) {}
|
fun takeUShort(u: UShort) {}
|
||||||
@@ -26,7 +27,7 @@ fun test() {
|
|||||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||||
takeULong(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
takeULong(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||||
|
|
||||||
takeULong(<!INT_LITERAL_OUT_OF_RANGE!>18446744073709551615<!>)
|
takeULong(<!INT_LITERAL_OUT_OF_RANGE, NI;TYPE_MISMATCH!>18446744073709551615<!>)
|
||||||
takeULong(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1844674407370955161<!>)
|
takeULong(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1844674407370955161<!>)
|
||||||
takeULong(18446744073709551615u)
|
takeULong(18446744073709551615u)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user