[K2] Disappeared UNSUPPORTED

Prohibit named parameters in function types in supertype position

^KT-59881
This commit is contained in:
Anastasia.Nekrasova
2023-11-23 13:55:46 +02:00
committed by Space Team
parent 5147a5e805
commit 00119c6a97
8 changed files with 78 additions and 22 deletions
@@ -5,30 +5,33 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind import com.intellij.psi.impl.source.tree.ElementType
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirFunctionTypeParameter
import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirField import org.jetbrains.kotlin.fir.declarations.FirField
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.util.getChildren
object FirSupertypesChecker : FirClassChecker() { object FirSupertypesChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -89,6 +92,7 @@ object FirSupertypesChecker : FirClassChecker() {
} }
checkClassCannotBeExtendedDirectly(symbol, reporter, superTypeRef, context) checkClassCannotBeExtendedDirectly(symbol, reporter, superTypeRef, context)
checkNamedFunctionTypeParameter(superTypeRef, context, reporter)
if (coneType.typeArguments.isNotEmpty()) { if (coneType.typeArguments.isNotEmpty()) {
checkProjectionInImmediateArgumentToSupertype(coneType, superTypeRef, reporter, context) checkProjectionInImmediateArgumentToSupertype(coneType, superTypeRef, reporter, context)
@@ -107,7 +111,7 @@ object FirSupertypesChecker : FirClassChecker() {
private fun checkAnnotationOnSuperclass( private fun checkAnnotationOnSuperclass(
superTypeRef: FirTypeRef, superTypeRef: FirTypeRef,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter,
) { ) {
for (annotation in superTypeRef.annotations) { for (annotation in superTypeRef.annotations) {
if (annotation.useSiteTarget != null) { if (annotation.useSiteTarget != null) {
@@ -120,7 +124,7 @@ object FirSupertypesChecker : FirClassChecker() {
symbol: FirClassifierSymbol<*>?, symbol: FirClassifierSymbol<*>?,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
superTypeRef: FirTypeRef, superTypeRef: FirTypeRef,
context: CheckerContext context: CheckerContext,
) { ) {
if (symbol is FirRegularClassSymbol && symbol.classId == StandardClassIds.Enum) { if (symbol is FirRegularClassSymbol && symbol.classId == StandardClassIds.Enum) {
reporter.reportOn(superTypeRef.source, FirErrors.CLASS_CANNOT_BE_EXTENDED_DIRECTLY, symbol, context) reporter.reportOn(superTypeRef.source, FirErrors.CLASS_CANNOT_BE_EXTENDED_DIRECTLY, symbol, context)
@@ -131,7 +135,7 @@ object FirSupertypesChecker : FirClassChecker() {
coneType: ConeKotlinType, coneType: ConeKotlinType,
superTypeRef: FirTypeRef, superTypeRef: FirTypeRef,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
context: CheckerContext context: CheckerContext,
) { ) {
val typeRefAndSourcesForArguments = extractArgumentsTypeRefAndSource(superTypeRef) ?: return val typeRefAndSourcesForArguments = extractArgumentsTypeRefAndSource(superTypeRef) ?: return
for ((index, typeArgument) in coneType.typeArguments.withIndex()) { for ((index, typeArgument) in coneType.typeArguments.withIndex()) {
@@ -152,7 +156,7 @@ object FirSupertypesChecker : FirClassChecker() {
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
superTypeRef: FirTypeRef, superTypeRef: FirTypeRef,
coneType: ConeKotlinType, coneType: ConeKotlinType,
context: CheckerContext context: CheckerContext,
) { ) {
if (symbol is FirRegularClassSymbol && symbol.classKind == ClassKind.INTERFACE) { if (symbol is FirRegularClassSymbol && symbol.classKind == ClassKind.INTERFACE) {
for (typeArgument in fullyExpandedType.typeArguments) { for (typeArgument in fullyExpandedType.typeArguments) {
@@ -167,7 +171,7 @@ object FirSupertypesChecker : FirClassChecker() {
private fun checkDelegationNotToInterface( private fun checkDelegationNotToInterface(
declaration: FirClass, declaration: FirClass,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter,
) { ) {
for (subDeclaration in declaration.declarations) { for (subDeclaration in declaration.declarations) {
if (subDeclaration is FirField) { if (subDeclaration is FirField) {
@@ -180,4 +184,39 @@ object FirSupertypesChecker : FirClassChecker() {
} }
} }
} }
private fun checkNamedFunctionTypeParameter(
superTypeRef: FirTypeRef,
context: CheckerContext,
reporter: DiagnosticReporter,
) {
val delegatedTypeRef = (superTypeRef as? FirResolvedTypeRef)?.delegatedTypeRef ?: return
if (delegatedTypeRef !is FirFunctionTypeRef) return
for (parameter in delegatedTypeRef.parameters) {
if (parameter.name != null) {
val source = parameter.findSourceForParameterName() ?: continue
reporter.reportOn(
source,
FirErrors.UNSUPPORTED,
"named parameter in function type in supertype position",
context
)
}
}
}
private fun FirFunctionTypeParameter.findSourceForParameterName(): KtSourceElement? {
val source = this.source ?: return null
val name = this.name ?: return null
val treeStructure = source.treeStructure
val nodes = source.lighterASTNode.getChildren(treeStructure)
val node = nodes.find { it.tokenType == KtTokens.IDENTIFIER && treeStructure.toString(it) == name.identifier } ?: return null
return node.toKtLightSourceElement(
treeStructure,
startOffset = node.startOffset,
endOffset = node.endOffset
)
}
} }
@@ -1,9 +0,0 @@
abstract class A : Function1<Any, Unit>
abstract class B : (Int)->Unit
// Named parameter is prohibited because of possible inconsistency between
// type declaration and actual override
class C : (x: Int)->Unit {
override fun invoke(p1: Int): Unit {}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
abstract class A : Function1<Any, Unit> abstract class A : Function1<Any, Unit>
abstract class B : (Int)->Unit abstract class B : (Int)->Unit
@@ -6,4 +7,14 @@ abstract class B : (Int)->Unit
// type declaration and actual override // type declaration and actual override
class C : (<!UNSUPPORTED!>x<!>: Int)->Unit { class C : (<!UNSUPPORTED!>x<!>: Int)->Unit {
override fun invoke(p1: Int): Unit {} override fun invoke(p1: Int): Unit {}
} }
class D : (<!UNSUPPORTED!>Int<!>: Int)->Unit {
override fun invoke(p1: Int): Unit {}
}
class E : ((k: String) -> Unit) -> Unit {
override fun invoke(p1: (k: String) -> Unit) {
}
}
@@ -23,3 +23,20 @@ public final class C : (x: kotlin.Int) -> kotlin.Unit {
public open override /*1*/ fun invoke(/*0*/ p1: kotlin.Int): kotlin.Unit public open override /*1*/ fun invoke(/*0*/ p1: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
public final class D : (Int: kotlin.Int) -> kotlin.Unit {
public constructor D()
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 open override /*1*/ fun invoke(/*0*/ p1: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class E : ((k: kotlin.String) -> kotlin.Unit) -> kotlin.Unit {
public constructor E()
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 open override /*1*/ fun invoke(/*0*/ p1: (k: kotlin.String) -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1 +0,0 @@
class A : (categoryName: <!SYNTAX!><!>)<!SYNTAX!><!> <!SYNTAX!><!>{<!SYNTAX!><!>
@@ -1 +1,2 @@
// FIR_IDENTICAL
class A : (<!UNSUPPORTED!>categoryName<!>: <!SYNTAX!><!>)<!SYNTAX!><!> <!SYNTAX!><!>{<!SYNTAX!><!> class A : (<!UNSUPPORTED!>categoryName<!>: <!SYNTAX!><!>)<!SYNTAX!><!> <!SYNTAX!><!>{<!SYNTAX!><!>
@@ -1,3 +0,0 @@
package typeReferenceError
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Pair<!><<!SYNTAX!><!>:(<!UNSUPPORTED!>val<!> c: <!SYNTAX!><!SYNTAX!><!>fun<!><!SYNTAX!><!> <!UNRESOLVED_REFERENCE!>main<!><!NO_CONSTRUCTOR!>()<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package typeReferenceError package typeReferenceError
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Pair<!><<!SYNTAX!><!>:(<!UNSUPPORTED!>val<!> <!UNSUPPORTED!>c<!>: <!SYNTAX!><!SYNTAX!><!>fun<!><!SYNTAX!><!> <!UNRESOLVED_REFERENCE!>main<!><!NO_CONSTRUCTOR!>()<!> <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class Pair<!><<!SYNTAX!><!>:(<!UNSUPPORTED!>val<!> <!UNSUPPORTED!>c<!>: <!SYNTAX!><!SYNTAX!><!>fun<!><!SYNTAX!><!> <!UNRESOLVED_REFERENCE!>main<!><!NO_CONSTRUCTOR!>()<!>