diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/ContractParsingServices.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/ContractParsingServices.kt index ef96c35fe1d..6fba898c4b5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/ContractParsingServices.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/ContractParsingServices.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.contracts.description.ContractDescription import org.jetbrains.kotlin.contracts.description.ContractProviderKey import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace @@ -35,7 +35,7 @@ class ContractParsingServices(val languageVersionSettings: LanguageVersionSettin fun checkContractAndRecordIfPresent(expression: KtExpression, trace: BindingTrace, scope: LexicalScope, isFirstStatement: Boolean) { val ownerDescriptor = scope.ownerDescriptor if (!expression.isContractDescriptionCallPsiCheck() || ownerDescriptor !is FunctionDescriptor) return - val contractProvider = ownerDescriptor.getUserData(ContractProviderKey) ?: return + val contractProvider = ownerDescriptor.getUserData(ContractProviderKey) val isFeatureTurnedOn = languageVersionSettings.supportsFeature(LanguageFeature.AllowContractsForCustomFunctions) || // This condition is here for technical purposes of compiling 1.2-runtime with contracts @@ -62,7 +62,7 @@ class ContractParsingServices(val languageVersionSettings: LanguageVersionSettin else -> parseContract(expression, trace, ownerDescriptor) } - contractProvider.setContractDescription(contractDescriptor) + contractProvider?.setContractDescription(contractDescriptor) } internal fun isContractDescriptionCall(expression: KtExpression, context: BindingContext): Boolean = @@ -76,4 +76,4 @@ class ContractParsingServices(val languageVersionSettings: LanguageVersionSettin private fun KtExpression.isContractDescriptionCallPreciseCheck(context: BindingContext): Boolean = getResolvedCall(context)?.resultingDescriptor?.isContractCallDescriptor() ?: false -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 07914dd6b71..8b037e3a113 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -39,9 +39,9 @@ import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.isContractPresentPsiCheck import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier +import org.jetbrains.kotlin.psi.psiUtil.isContractPresentPsiCheck import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultModality import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultVisibility import org.jetbrains.kotlin.resolve.DescriptorUtils.getDispatchReceiverParameterIfNeeded @@ -198,7 +198,13 @@ class FunctionDescriptorResolver( function, getDefaultModality(container, visibility, function.hasBody()), trace.bindingContext, container ) + val contractProvider = getContractProvider(functionDescriptor, trace, scope, dataFlowInfo, function) + val userData = mutableMapOf, Any>().apply { + if (contractProvider != null) { + put(ContractProviderKey, contractProvider) + } + } functionDescriptor.initialize( receiverType, @@ -208,8 +214,9 @@ class FunctionDescriptorResolver( returnType, modality, visibility, - mapOf(ContractProviderKey to contractProvider) + userData.takeIf { it.isNotEmpty() } ) + functionDescriptor.isOperator = function.hasModifier(KtTokens.OPERATOR_KEYWORD) functionDescriptor.isInfix = function.hasModifier(KtTokens.INFIX_KEYWORD) functionDescriptor.isExternal = function.hasModifier(KtTokens.EXTERNAL_KEYWORD) @@ -232,17 +239,16 @@ class FunctionDescriptorResolver( scope: LexicalScope, dataFlowInfo: DataFlowInfo, function: KtFunction - ): LazyContractProvider { + ): LazyContractProvider? { val provideByDeferredForceResolve = LazyContractProvider { expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor) } - val emptyContract = LazyContractProvider.createInitialized(null) val isContractsEnabled = languageVersionSettings.supportsFeature(LanguageFeature.AllowContractsForCustomFunctions) || // We need to enable contracts if we're compiling "kotlin"-package to be able to ship contracts in stdlib in 1.2 languageVersionSettings.getFlag(AnalysisFlag.allowKotlinPackage) - if (!isContractsEnabled || !function.isContractPresentPsiCheck()) return emptyContract + if (!isContractsEnabled || !function.isContractPresentPsiCheck()) return null return provideByDeferredForceResolve }