[FIR] Implement TYPEALIAS_SHOULD_EXPAND_TO_CLASS

This commit is contained in:
Ivan Kochurkin
2021-06-16 17:21:32 +03:00
committed by teamcityserver
parent e8a790993b
commit 937846b62d
11 changed files with 74 additions and 18 deletions
@@ -921,6 +921,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val TYPE_ALIAS by object : DiagnosticGroup("Type alias") {
val TOPLEVEL_TYPEALIASES_ONLY by error<KtTypeAlias>()
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") {
@@ -500,6 +500,7 @@ object FirErrors {
// Type alias
val TOPLEVEL_TYPEALIASES_ONLY by error0<KtTypeAlias>()
val RECURSIVE_TYPEALIAS_EXPANSION by error0<KtElement>()
val TYPEALIAS_SHOULD_EXPAND_TO_CLASS by error1<KtElement, ConeKotlinType>()
// Extended checkers
val REDUNDANT_VISIBILITY_MODIFIER by warning0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
@@ -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.FirMemberDeclaration
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() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirTypeAlias) return
if (context.containingDeclarations.lastOrNull() !is FirFile) {
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
)
}
}
}
@@ -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.TOO_MANY_ARGUMENTS
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_CANT_BE_USED_FOR_CONST_VAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
@@ -1183,6 +1184,11 @@ class FirDefaultErrorMessages {
// Type alias
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(
TYPEALIAS_SHOULD_EXPAND_TO_CLASS,
"Type alias expands to {0}, which is not a class, an interface, or an object",
RENDER_TYPE
)
// Returns
map.put(RETURN_NOT_ALLOWED, "'return' is not allowed here")