Minor: rename and refactor contract-related PSI checks in ktPsiUtil
This commit is contained in:
+8
-8
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.contracts.description.ContractProviderKey
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
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.psi.psiUtil.isContractDescriptionCallFastCheck
|
import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
|||||||
class ContractParsingServices(val languageVersionSettings: LanguageVersionSettings) {
|
class ContractParsingServices(val languageVersionSettings: LanguageVersionSettings) {
|
||||||
fun checkContractAndRecordIfPresent(expression: KtExpression, trace: BindingTrace, scope: LexicalScope, isFirstStatement: Boolean) {
|
fun checkContractAndRecordIfPresent(expression: KtExpression, trace: BindingTrace, scope: LexicalScope, isFirstStatement: Boolean) {
|
||||||
val ownerDescriptor = scope.ownerDescriptor
|
val ownerDescriptor = scope.ownerDescriptor
|
||||||
if (!isContractDescriptionCallFastCheck(expression) || ownerDescriptor !is FunctionDescriptor) return
|
if (!expression.isContractDescriptionCallPsiCheck() || ownerDescriptor !is FunctionDescriptor) return
|
||||||
val contractProvider = ownerDescriptor.getUserData(ContractProviderKey) ?: return
|
val contractProvider = ownerDescriptor.getUserData(ContractProviderKey) ?: return
|
||||||
|
|
||||||
val isFeatureTurnedOn = languageVersionSettings.supportsFeature(LanguageFeature.AllowContractsForCustomFunctions) ||
|
val isFeatureTurnedOn = languageVersionSettings.supportsFeature(LanguageFeature.AllowContractsForCustomFunctions) ||
|
||||||
@@ -42,7 +42,7 @@ class ContractParsingServices(val languageVersionSettings: LanguageVersionSettin
|
|||||||
languageVersionSettings.getFlag(AnalysisFlag.Flags.allowKotlinPackage)
|
languageVersionSettings.getFlag(AnalysisFlag.Flags.allowKotlinPackage)
|
||||||
|
|
||||||
val contractDescriptor = when {
|
val contractDescriptor = when {
|
||||||
!isContractDescriptionCallPreciseCheck(expression, trace.bindingContext) -> null
|
!expression.isContractDescriptionCallPreciseCheck(trace.bindingContext) -> null
|
||||||
|
|
||||||
!isFeatureTurnedOn -> {
|
!isFeatureTurnedOn -> {
|
||||||
trace.report(
|
trace.report(
|
||||||
@@ -65,15 +65,15 @@ class ContractParsingServices(val languageVersionSettings: LanguageVersionSettin
|
|||||||
contractProvider.setContractDescription(contractDescriptor)
|
contractProvider.setContractDescription(contractDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun isContractDescriptionCall(expression: KtExpression, context: BindingContext): Boolean =
|
||||||
|
expression.isContractDescriptionCallPsiCheck() && expression.isContractDescriptionCallPreciseCheck(context)
|
||||||
|
|
||||||
private fun parseContract(expression: KtExpression?, trace: BindingTrace, ownerDescriptor: FunctionDescriptor): ContractDescription? =
|
private fun parseContract(expression: KtExpression?, trace: BindingTrace, ownerDescriptor: FunctionDescriptor): ContractDescription? =
|
||||||
PsiContractParserDispatcher(trace, this).parseContract(expression, ownerDescriptor)
|
PsiContractParserDispatcher(trace, this).parseContract(expression, ownerDescriptor)
|
||||||
|
|
||||||
internal fun isContractDescriptionCall(expression: KtExpression, context: BindingContext): Boolean =
|
|
||||||
isContractDescriptionCallFastCheck(expression) && isContractDescriptionCallPreciseCheck(expression, context)
|
|
||||||
|
|
||||||
private fun isContractAllowedHere(scope: LexicalScope): Boolean =
|
private fun isContractAllowedHere(scope: LexicalScope): Boolean =
|
||||||
scope.kind == LexicalScopeKind.CODE_BLOCK && (scope.parent as? LexicalScope)?.kind == LexicalScopeKind.FUNCTION_INNER_SCOPE
|
scope.kind == LexicalScopeKind.CODE_BLOCK && (scope.parent as? LexicalScope)?.kind == LexicalScopeKind.FUNCTION_INNER_SCOPE
|
||||||
|
|
||||||
private fun isContractDescriptionCallPreciseCheck(expression: KtExpression, context: BindingContext): Boolean =
|
private fun KtExpression.isContractDescriptionCallPreciseCheck(context: BindingContext): Boolean =
|
||||||
expression.getResolvedCall(context)?.resultingDescriptor?.isContractCallDescriptor() ?: false
|
getResolvedCall(context)?.resultingDescriptor?.isContractCallDescriptor() ?: false
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.fastCheckIfContractPresent
|
import org.jetbrains.kotlin.psi.psiUtil.isContractPresentPsiCheck
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultModality
|
import org.jetbrains.kotlin.resolve.DescriptorResolver.getDefaultModality
|
||||||
@@ -242,7 +242,7 @@ class FunctionDescriptorResolver(
|
|||||||
// We need to enable contracts if we're compiling "kotlin"-package to be able to ship contracts in stdlib in 1.2
|
// 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)
|
languageVersionSettings.getFlag(AnalysisFlag.allowKotlinPackage)
|
||||||
|
|
||||||
if (!isContractsEnabled || !fastCheckIfContractPresent(function)) return emptyContract
|
if (!isContractsEnabled || !function.isContractPresentPsiCheck()) return emptyContract
|
||||||
|
|
||||||
return provideByDeferredForceResolve
|
return provideByDeferredForceResolve
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,17 +293,20 @@ inline fun <reified T : KtElement, R> flatMapDescendantsOfTypeVisitor(
|
|||||||
|
|
||||||
// ----------- Contracts -------------------------------------------------------------------------------------------------------------------
|
// ----------- Contracts -------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
fun fastCheckIfContractPresent(element: KtElement): Boolean {
|
fun KtElement.isContractPresentPsiCheck(): Boolean {
|
||||||
if (!isContractAllowedHere(element)) return false
|
val contractAllowedHere = this is KtNamedFunction &&
|
||||||
val firstExpression = ((element as? KtFunction)?.bodyExpression as? KtBlockExpression)?.statements?.firstOrNull() ?: return false
|
isTopLevel &&
|
||||||
return isContractDescriptionCallFastCheck(firstExpression)
|
hasBlockBody() &&
|
||||||
|
!hasModifier(KtTokens.OPERATOR_KEYWORD)
|
||||||
|
if (!contractAllowedHere) return false
|
||||||
|
|
||||||
|
val firstExpression = ((this as? KtFunction)?.bodyExpression as? KtBlockExpression)?.statements?.firstOrNull() ?: return false
|
||||||
|
|
||||||
|
return firstExpression.isContractDescriptionCallPsiCheck()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isContractAllowedHere(element: KtElement): Boolean =
|
fun KtExpression.isContractDescriptionCallPsiCheck(): Boolean =
|
||||||
element is KtNamedFunction && element.isTopLevel && element.hasBlockBody() && !element.hasModifier(KtTokens.OPERATOR_KEYWORD)
|
this is KtCallExpression && calleeExpression?.text == "contract"
|
||||||
|
|
||||||
fun isContractDescriptionCallFastCheck(expression: KtExpression): Boolean =
|
|
||||||
expression is KtCallExpression && expression.calleeExpression?.text == "contract"
|
|
||||||
|
|
||||||
|
|
||||||
// ----------- Other -----------------------------------------------------------------------------------------------------------------------
|
// ----------- Other -----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user