[FE] Move type-related checks to TypeResolver

This commit is contained in:
Anastasiya Shadrina
2021-11-03 19:54:08 +07:00
committed by TeamCityServer
parent 9896cbd2b8
commit 7ab9b68ad5
10 changed files with 95 additions and 38 deletions
@@ -348,10 +348,13 @@ class TypeResolver(
val receiverTypeRef = type.receiverTypeReference
val receiverType = if (receiverTypeRef?.typeElement == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
val contextReceiversTypeRefs = type.contextReceiversTypeReferences
val contextReceiversTypes = contextReceiversTypeRefs?.mapNotNull {
resolveType(c.noBareTypes(), it)
} ?: emptyList()
val contextReceiverList = type.contextReceiverList
val contextReceiversTypes = if (contextReceiverList != null) {
checkContextReceiversAreEnabled(contextReceiverList)
contextReceiverList.typeReferences().map { typeRef ->
resolveType(c.noBareTypes(), typeRef)
}
} else emptyList()
val parameterDescriptors = resolveParametersOfFunctionType(type.parameters)
checkParametersOfFunctionType(parameterDescriptors)
@@ -430,6 +433,10 @@ class TypeResolver(
}
}
override fun visitContextReceiverList(contextReceiverList: KtContextReceiverList) {
checkContextReceiversAreEnabled(contextReceiverList)
}
override fun visitDynamicType(type: KtDynamicType) {
result = type(dynamicCallableDescriptors.dynamicType.replaceAnnotations(annotations))
if (!dynamicTypesSettings.dynamicTypesAllowed) {
@@ -469,6 +476,17 @@ class TypeResolver(
c.trace.report(Errors.UNSUPPORTED.on(it, "val or var on parameter in function type"))
}
}
private fun checkContextReceiversAreEnabled(contextReceiverList: KtContextReceiverList) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
c.trace.report(
UNSUPPORTED_FEATURE.on(
contextReceiverList,
LanguageFeature.ContextReceivers to languageVersionSettings
)
)
}
}
})
return result ?: type(ErrorUtils.createErrorType(typeElement?.getDebugText() ?: "No type element"))
@@ -26,37 +26,5 @@ object ContextualDeclarationChecker : DeclarationChecker {
)
return
}
val types = mutableListOf<KtTypeReference?>()
when (declaration) {
is KtFunction -> {
types.addAll(declaration.valueParameters.mapNotNull { it.typeReference })
types.add(declaration.receiverTypeReference)
types.add(declaration.typeReference)
}
is KtProperty -> {
types.add(declaration.receiverTypeReference)
types.add(declaration.typeReference)
}
is KtClass -> {
types.addAll(declaration.primaryConstructor?.valueParameters?.map { it.typeReference } ?: emptyList())
}
is KtTypeAlias -> {
types.add(declaration.getTypeReference())
}
}
fun KtTypeReference.isOrHasContextualType(): Boolean {
val typeElement = typeElement as? KtFunctionType ?: return false
return !typeElement.contextReceiversTypeReferences.isNullOrEmpty()
|| typeElement.typeArgumentsAsTypes.any(KtTypeReference::isOrHasContextualType)
}
types.filterNotNull().filter { it.isOrHasContextualType() }.forEach {
context.trace.report(
Errors.UNSUPPORTED_FEATURE.on(
it, LanguageFeature.ContextReceivers to context.languageVersionSettings
)
)
}
}
}