[FIR] Implement TYPEALIAS_SHOULD_EXPAND_TO_CLASS
This commit is contained in:
committed by
teamcityserver
parent
e8a790993b
commit
937846b62d
+3
@@ -921,6 +921,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val TYPE_ALIAS by object : DiagnosticGroup("Type alias") {
|
val TYPE_ALIAS by object : DiagnosticGroup("Type alias") {
|
||||||
val TOPLEVEL_TYPEALIASES_ONLY by error<KtTypeAlias>()
|
val TOPLEVEL_TYPEALIASES_ONLY by error<KtTypeAlias>()
|
||||||
val RECURSIVE_TYPEALIAS_EXPANSION by error<KtElement>()
|
val RECURSIVE_TYPEALIAS_EXPANSION by error<KtElement>()
|
||||||
|
val TYPEALIAS_SHOULD_EXPAND_TO_CLASS by error<KtElement> {
|
||||||
|
parameter<ConeKotlinType>("expandedType")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val EXTENDED_CHECKERS by object : DiagnosticGroup("Extended checkers") {
|
val EXTENDED_CHECKERS by object : DiagnosticGroup("Extended checkers") {
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ object FirErrors {
|
|||||||
// Type alias
|
// Type alias
|
||||||
val TOPLEVEL_TYPEALIASES_ONLY by error0<KtTypeAlias>()
|
val TOPLEVEL_TYPEALIASES_ONLY by error0<KtTypeAlias>()
|
||||||
val RECURSIVE_TYPEALIAS_EXPANSION by error0<KtElement>()
|
val RECURSIVE_TYPEALIAS_EXPANSION by error0<KtElement>()
|
||||||
|
val TYPEALIAS_SHOULD_EXPAND_TO_CLASS by error1<KtElement, ConeKotlinType>()
|
||||||
|
|
||||||
// Extended checkers
|
// Extended checkers
|
||||||
val REDUNDANT_VISIBILITY_MODIFIER by warning0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
val REDUNDANT_VISIBILITY_MODIFIER by warning0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||||
|
|||||||
+37
@@ -12,12 +12,49 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedDynamicType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
|
||||||
object FirTypeAliasChecker : FirMemberDeclarationChecker() {
|
object FirTypeAliasChecker : FirMemberDeclarationChecker() {
|
||||||
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (declaration !is FirTypeAlias) return
|
if (declaration !is FirTypeAlias) return
|
||||||
|
|
||||||
if (context.containingDeclarations.lastOrNull() !is FirFile) {
|
if (context.containingDeclarations.lastOrNull() !is FirFile) {
|
||||||
reporter.reportOn(declaration.source, FirErrors.TOPLEVEL_TYPEALIASES_ONLY, context)
|
reporter.reportOn(declaration.source, FirErrors.TOPLEVEL_TYPEALIASES_ONLY, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun containsTypeParameter(type: ConeKotlinType): Boolean {
|
||||||
|
if (type is ConeTypeParameterType) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type is ConeClassLikeType && type.lookupTag.toSymbol(context.session) is FirTypeAliasSymbol) {
|
||||||
|
for (typeArgument in type.typeArguments) {
|
||||||
|
val typeArgumentType = (typeArgument as? ConeKotlinType) ?: (typeArgument as? ConeKotlinTypeProjection)?.type
|
||||||
|
if (typeArgumentType != null && containsTypeParameter(typeArgumentType)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val expandedTypeRef = declaration.expandedTypeRef
|
||||||
|
val fullyExpandedType = expandedTypeRef.coneType.fullyExpandedType(context.session)
|
||||||
|
|
||||||
|
if (containsTypeParameter(fullyExpandedType) ||
|
||||||
|
fullyExpandedType is ConeClassErrorType && fullyExpandedType.diagnostic is ConeUnsupportedDynamicType
|
||||||
|
) {
|
||||||
|
reporter.reportOn(
|
||||||
|
declaration.expandedTypeRef.source,
|
||||||
|
FirErrors.TYPEALIAS_SHOULD_EXPAND_TO_CLASS,
|
||||||
|
expandedTypeRef.coneType,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -308,6 +308,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.THROWABLE_TYPE_MISMATCH
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.THROWABLE_TYPE_MISMATCH
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOO_MANY_ARGUMENTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOO_MANY_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOPLEVEL_TYPEALIASES_ONLY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOPLEVEL_TYPEALIASES_ONLY
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPEALIAS_SHOULD_EXPAND_TO_CLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_CANT_BE_USED_FOR_CONST_VAL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_CANT_BE_USED_FOR_CONST_VAL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
|
||||||
@@ -1183,6 +1184,11 @@ class FirDefaultErrorMessages {
|
|||||||
// Type alias
|
// Type alias
|
||||||
map.put(TOPLEVEL_TYPEALIASES_ONLY, "Nested and local type aliases are not supported")
|
map.put(TOPLEVEL_TYPEALIASES_ONLY, "Nested and local type aliases are not supported")
|
||||||
map.put(RECURSIVE_TYPEALIAS_EXPANSION, "Recursive type alias in expansion")
|
map.put(RECURSIVE_TYPEALIAS_EXPANSION, "Recursive type alias in expansion")
|
||||||
|
map.put(
|
||||||
|
TYPEALIAS_SHOULD_EXPAND_TO_CLASS,
|
||||||
|
"Type alias expands to {0}, which is not a class, an interface, or an object",
|
||||||
|
RENDER_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
// Returns
|
// Returns
|
||||||
map.put(RETURN_NOT_ALLOWED, "'return' is not allowed here")
|
map.put(RETURN_NOT_ALLOWED, "'return' is not allowed here")
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ typealias TTNullableTString = TNullableTString
|
|||||||
fun f3() = TTNullableTString::class
|
fun f3() = TTNullableTString::class
|
||||||
|
|
||||||
inline fun <reified T> f4(b: Boolean): Any {
|
inline fun <reified T> f4(b: Boolean): Any {
|
||||||
<!TOPLEVEL_TYPEALIASES_ONLY!>typealias X = T<!>
|
<!TOPLEVEL_TYPEALIASES_ONLY!>typealias X = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>T<!><!>
|
||||||
<!TOPLEVEL_TYPEALIASES_ONLY!>typealias Y = T?<!>
|
<!TOPLEVEL_TYPEALIASES_ONLY!>typealias Y = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>T?<!><!>
|
||||||
return if (b) <!UNRESOLVED_REFERENCE!>X<!>::class else <!UNRESOLVED_REFERENCE!>Y<!>::class
|
return if (b) <!UNRESOLVED_REFERENCE!>X<!>::class else <!UNRESOLVED_REFERENCE!>Y<!>::class
|
||||||
}
|
}
|
||||||
|
|||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
|
||||||
|
|
||||||
typealias ToTypeParam1<T> = T
|
|
||||||
typealias ToTypeParam2<T> = ToTypeParam1<T>
|
|
||||||
typealias ToTypeParam3<T1, T2> = ToTypeParam2<T1>
|
|
||||||
typealias ToTypeParam4 = ToTypeParam1<Any>
|
|
||||||
|
|
||||||
typealias ToFun1 = () -> Unit
|
|
||||||
typealias ToFun2<T> = (T) -> Unit
|
|
||||||
|
|
||||||
class Outer {
|
|
||||||
typealias ToTypeParam1<T> = T
|
|
||||||
typealias ToTypeParam2<T> = ToTypeParam1<T>
|
|
||||||
typealias ToTypeParam3<T1, T2> = ToTypeParam2<T1>
|
|
||||||
typealias ToTypeParam4 = ToTypeParam1<Any>
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
||||||
|
|
||||||
|
typealias Dyn = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS, UNSUPPORTED!>dynamic<!>
|
||||||
|
|
||||||
typealias ToTypeParam1<T> = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>T<!>
|
typealias ToTypeParam1<T> = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>T<!>
|
||||||
typealias ToTypeParam2<T> = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>ToTypeParam1<T><!>
|
typealias ToTypeParam2<T> = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>ToTypeParam1<T><!>
|
||||||
typealias ToTypeParam3<T1, T2> = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>ToTypeParam2<T1><!>
|
typealias ToTypeParam3<T1, T2> = <!TYPEALIAS_SHOULD_EXPAND_TO_CLASS!>ToTypeParam2<T1><!>
|
||||||
|
|||||||
+2
@@ -10,9 +10,11 @@ public final class Outer {
|
|||||||
public typealias ToTypeParam3</*0*/ T1, /*1*/ T2> = Outer.ToTypeParam2<T1>
|
public typealias ToTypeParam3</*0*/ T1, /*1*/ T2> = Outer.ToTypeParam2<T1>
|
||||||
public typealias ToTypeParam4 = Outer.ToTypeParam1<kotlin.Any>
|
public typealias ToTypeParam4 = Outer.ToTypeParam1<kotlin.Any>
|
||||||
}
|
}
|
||||||
|
public typealias Dyn = [ERROR : dynamic type in wrong context]
|
||||||
public typealias ToFun1 = () -> kotlin.Unit
|
public typealias ToFun1 = () -> kotlin.Unit
|
||||||
public typealias ToFun2</*0*/ T> = (T) -> kotlin.Unit
|
public typealias ToFun2</*0*/ T> = (T) -> kotlin.Unit
|
||||||
public typealias ToTypeParam1</*0*/ T> = T
|
public typealias ToTypeParam1</*0*/ T> = T
|
||||||
public typealias ToTypeParam2</*0*/ T> = ToTypeParam1<T>
|
public typealias ToTypeParam2</*0*/ T> = ToTypeParam1<T>
|
||||||
public typealias ToTypeParam3</*0*/ T1, /*1*/ T2> = ToTypeParam2<T1>
|
public typealias ToTypeParam3</*0*/ T1, /*1*/ T2> = ToTypeParam2<T1>
|
||||||
public typealias ToTypeParam4 = ToTypeParam1<kotlin.Any>
|
public typealias ToTypeParam4 = ToTypeParam1<kotlin.Any>
|
||||||
|
|
||||||
|
|||||||
+7
@@ -2498,6 +2498,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.TYPEALIAS_SHOULD_EXPAND_TO_CLASS) { firDiagnostic ->
|
||||||
|
TypealiasShouldExpandToClassImpl(
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.REDUNDANT_VISIBILITY_MODIFIER) { firDiagnostic ->
|
add(FirErrors.REDUNDANT_VISIBILITY_MODIFIER) { firDiagnostic ->
|
||||||
RedundantVisibilityModifierImpl(
|
RedundantVisibilityModifierImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
|||||||
+5
@@ -1757,6 +1757,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = RecursiveTypealiasExpansion::class
|
override val diagnosticClass get() = RecursiveTypealiasExpansion::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class TypealiasShouldExpandToClass : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = TypealiasShouldExpandToClass::class
|
||||||
|
abstract val expandedType: KtType
|
||||||
|
}
|
||||||
|
|
||||||
abstract class RedundantVisibilityModifier : KtFirDiagnostic<KtModifierListOwner>() {
|
abstract class RedundantVisibilityModifier : KtFirDiagnostic<KtModifierListOwner>() {
|
||||||
override val diagnosticClass get() = RedundantVisibilityModifier::class
|
override val diagnosticClass get() = RedundantVisibilityModifier::class
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -2841,6 +2841,14 @@ internal class RecursiveTypealiasExpansionImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class TypealiasShouldExpandToClassImpl(
|
||||||
|
override val expandedType: KtType,
|
||||||
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.TypealiasShouldExpandToClass(), KtAbstractFirDiagnostic<KtElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class RedundantVisibilityModifierImpl(
|
internal class RedundantVisibilityModifierImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user