diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 7a1ac3ef704..f3d3ed06329 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -21,6 +21,12 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType +import org.jetbrains.kotlin.config.AnalysisFlag +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.contracts.description.ContractProviderKey +import org.jetbrains.kotlin.contracts.description.LazyContractProvider +import org.jetbrains.kotlin.contracts.parsing.ContractParsingServices import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl @@ -33,8 +39,8 @@ import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier +import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultModality import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultVisibility import org.jetbrains.kotlin.resolve.DescriptorUtils.getDispatchReceiverParameterIfNeeded @@ -53,6 +59,7 @@ import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral @@ -65,7 +72,10 @@ class FunctionDescriptorResolver( private val annotationResolver: AnnotationResolver, private val builtIns: KotlinBuiltIns, private val modifiersChecker: ModifiersChecker, - private val overloadChecker: OverloadChecker + private val overloadChecker: OverloadChecker, + private val contractParsingServices: ContractParsingServices, + private val expressionTypingServices: ExpressionTypingServices, + private val languageVersionSettings: LanguageVersionSettings ) { fun resolveFunctionDescriptor( containingDescriptor: DeclarationDescriptor, @@ -107,7 +117,7 @@ class FunctionDescriptorResolver( CallableMemberDescriptor.Kind.DECLARATION, function.toSourceElement() ) - initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, expectedFunctionType) + initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, expectedFunctionType, dataFlowInfo) initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo) BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor) return functionDescriptor @@ -141,7 +151,8 @@ class FunctionDescriptorResolver( function: KtFunction, functionDescriptor: SimpleFunctionDescriptorImpl, trace: BindingTrace, - expectedFunctionType: KotlinType + expectedFunctionType: KotlinType, + dataFlowInfo: DataFlowInfo ) { val headerScope = LexicalWritableScope(scope, functionDescriptor, true, TraceBasedLocalRedeclarationChecker(trace, overloadChecker), LexicalScopeKind.FUNCTION_HEADER) @@ -169,6 +180,8 @@ class FunctionDescriptorResolver( val visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, container)) val modality = resolveMemberModalityFromModifiers(function, getDefaultModality(container, visibility, function.hasBody()), trace.bindingContext, container) + val contractProvider = getContractProvider(functionDescriptor, trace, scope, dataFlowInfo, function) + functionDescriptor.initialize( receiverType, getDispatchReceiverParameterIfNeeded(container), @@ -176,7 +189,8 @@ class FunctionDescriptorResolver( valueParameterDescriptors, returnType, modality, - visibility + visibility, + mapOf(ContractProviderKey to contractProvider) ) functionDescriptor.isOperator = function.hasModifier(KtTokens.OPERATOR_KEYWORD) functionDescriptor.isInfix = function.hasModifier(KtTokens.INFIX_KEYWORD) @@ -194,6 +208,26 @@ class FunctionDescriptorResolver( } } + private fun getContractProvider( + functionDescriptor: SimpleFunctionDescriptorImpl, + trace: BindingTrace, + scope: LexicalScope, + dataFlowInfo: DataFlowInfo, + function: KtFunction + ): LazyContractProvider { + val provideByDeferredForceResolve = LazyContractProvider { + expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor) + } + val emptyContract = LazyContractProvider.createInitialized(null) + + val isContractsEnabled = languageVersionSettings.supportsFeature(LanguageFeature.CallsInPlaceEffect) || + languageVersionSettings.supportsFeature(LanguageFeature.ReturnsEffect) + + if (!isContractsEnabled || !contractParsingServices.fastCheckIfContractPresent(function)) return emptyContract + + return provideByDeferredForceResolve + } + private fun createValueParameterDescriptors( function: KtFunction, functionDescriptor: SimpleFunctionDescriptorImpl, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt index 12b21e66ea2..3936ca7220e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -193,7 +193,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre ) components.functionDescriptorResolver. initializeFunctionDescriptorAndExplicitReturnType(context.scope.ownerDescriptor, context.scope, functionLiteral, - functionDescriptor, context.trace, context.expectedType) + functionDescriptor, context.trace, context.expectedType, context.dataFlowInfo) for (parameterDescriptor in functionDescriptor.valueParameters) { ForceResolveUtil.forceResolveAllContents(parameterDescriptor.annotations) }