[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
@@ -10726,6 +10726,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterizedList.kt");
}
@Test
@TestMetadata("unsupported.kt")
public void testUnsupported() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.kt");
}
@Test
@TestMetadata("withExplicitReceiver.kt")
public void testWithExplicitReceiver() throws Exception {
@@ -10726,6 +10726,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterizedList.kt");
}
@Test
@TestMetadata("unsupported.kt")
public void testUnsupported() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.kt");
}
@Test
@TestMetadata("withExplicitReceiver.kt")
public void testWithExplicitReceiver() throws Exception {
@@ -10726,6 +10726,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterizedList.kt");
}
@Test
@TestMetadata("unsupported.kt")
public void testUnsupported() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.kt");
}
@Test
@TestMetadata("withExplicitReceiver.kt")
public void testWithExplicitReceiver() throws Exception {
@@ -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
)
)
}
}
}
@@ -93,13 +93,18 @@ public class KtFunctionType extends KtElementImplStub<KotlinPlaceHolderStub<KtFu
return receiverDeclaration.getTypeReference();
}
public List<KtTypeReference> getContextReceiversTypeReferences() {
@Nullable
public KtContextReceiverList getContextReceiverList() {
KtFunctionTypeReceiver receiverDeclaration = getReceiver();
if (receiverDeclaration == null) {
return null;
}
KtTypeReference receiverTypeRef = receiverDeclaration.getTypeReference();
KtContextReceiverList contextReceiverList = receiverTypeRef.getStubOrPsiChild(KtStubElementTypes.CONTEXT_RECEIVER_LIST);
return receiverTypeRef.getStubOrPsiChild(KtStubElementTypes.CONTEXT_RECEIVER_LIST);
}
public List<KtTypeReference> getContextReceiversTypeReferences() {
KtContextReceiverList contextReceiverList = getContextReceiverList();
if (contextReceiverList != null) {
return contextReceiverList.typeReferences();
} else {
@@ -0,0 +1,15 @@
// !DIAGNOSTICS: -UNCHECKED_CAST
context(Any)
fun f(g: context(Any) () -> Unit, value: Any): context(A) () -> Unit {
return value as (context(A) () -> Unit)
}
context(String, Int)
class A {
context(Any)
val p: Any get() = 42
context(String, Int)
fun m() {}
}
@@ -0,0 +1,15 @@
// !DIAGNOSTICS: -UNCHECKED_CAST
<!UNSUPPORTED_FEATURE!>context(Any)<!>
fun f(g: <!UNSUPPORTED_FEATURE!>context(Any)<!> () -> Unit, value: Any): <!UNSUPPORTED_FEATURE!>context(A)<!> () -> Unit {
return value as (<!UNSUPPORTED_FEATURE!>context(A)<!> () -> Unit)
}
<!UNSUPPORTED_FEATURE!>context(String, Int)<!>
class A {
<!UNSUPPORTED_FEATURE!>context(Any)<!>
val p: Any get() = 42
<!UNSUPPORTED_FEATURE!>context(String, Int)<!>
fun m() {}
}
@@ -0,0 +1,12 @@
package
public fun f(/*0*/ g: context(kotlin.Any) () -> kotlin.Unit, /*1*/ value: kotlin.Any): context(A) () -> kotlin.Unit
public final class A {
public constructor A()
public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -10732,6 +10732,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterizedList.kt");
}
@Test
@TestMetadata("unsupported.kt")
public void testUnsupported() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.kt");
}
@Test
@TestMetadata("withExplicitReceiver.kt")
public void testWithExplicitReceiver() throws Exception {