[FIR] Fix positioning and detecting of WRONG_NUMBER_OF_TYPE_ARGUMENTS

Refactor code and fix compilation errors caused by changes to symbol.fir
This commit is contained in:
Ivan Kochurkin
2021-07-06 22:23:04 +03:00
committed by TeamCityServer
parent 345152d198
commit dd54338ec0
49 changed files with 377 additions and 301 deletions
@@ -446,14 +446,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val TYPE_ARGUMENTS_NOT_ALLOWED by error<PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error<PsiElement> {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
parameter<FirRegularClassSymbol>("classifier")
}
val NO_TYPE_ARGUMENTS_ON_RHS by error<PsiElement> {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
}
val OUTER_CLASS_ARGUMENTS_REQUIRED by error<PsiElement>() {
parameter<FirRegularClass>("outer")
val OUTER_CLASS_ARGUMENTS_REQUIRED by error<PsiElement> {
parameter<FirRegularClassSymbol>("outer")
}
val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<PsiElement>()
@@ -295,9 +295,9 @@ object FirErrors {
val UPPER_BOUND_VIOLATED by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirRegularClassSymbol>()
val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClass>()
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClassSymbol>()
val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>()
@@ -8,14 +8,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.extractArgumentTypeRefAndSource
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.resolve.getClassThatContainsTypeParameter
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameter
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.toTypeProjections
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -23,15 +21,10 @@ import org.jetbrains.kotlin.fir.types.*
object FirOuterClassArgumentsRequiredChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
// Checking the rest super types that weren't resolved on the first OUTER_CLASS_ARGUMENTS_REQUIRED check in FirTypeResolver
for (superTypeRef in declaration.superTypeRefs) {
checkOuterClassArgumentsRequired(superTypeRef, declaration, context, reporter)
}
for (subDecl in declaration.declarations) {
if (subDecl is FirTypedDeclaration) {
checkOuterClassArgumentsRequired(subDecl.returnTypeRef, declaration, context, reporter)
}
}
}
}
@@ -41,65 +34,29 @@ private fun checkOuterClassArgumentsRequired(
context: CheckerContext,
reporter: DiagnosticReporter
) {
val type: ConeKotlinType
if (typeRef !is FirResolvedTypeRef || typeRef is FirErrorTypeRef) {
return
}
if (typeRef is FirResolvedTypeRef) {
if (typeRef is FirErrorTypeRef) {
return
}
val type: ConeKotlinType = typeRef.type
val delegatedTypeRef = typeRef.delegatedTypeRef
type = typeRef.type
val delegatedTypeRef = typeRef.delegatedTypeRef
if (delegatedTypeRef is FirUserTypeRef && type is ConeClassLikeType) {
val symbol = type.lookupTag.toSymbol(context.session)
if (delegatedTypeRef is FirUserTypeRef) {
if (symbol is FirRegularClassSymbol) {
val typeArguments = delegatedTypeRef.qualifier.toTypeProjections()
val typeParameters = symbol.typeParameterSymbols
if (type is ConeClassLikeType) {
val symbol = type.lookupTag.toSymbol(context.session)
if (symbol is FirRegularClassSymbol) {
var problemTypeParameter: FirTypeParameterRef? = null
val typeArguments = delegatedTypeRef.qualifier.toTypeProjections()
val argumentsFromOuterClassesAndParentsCount = symbol.fir.typeParameters.drop(typeArguments.size).sumOf {
val result = if (isValidTypeParameter(it, declaration, context.session)) {
1
} else {
if (problemTypeParameter == null) {
problemTypeParameter = it
}
0
}
return@sumOf result
}
val finalTypeArgumentsCount = typeArguments.size + argumentsFromOuterClassesAndParentsCount
if (finalTypeArgumentsCount != symbol.fir.typeParameters.size) {
val source = typeRef.source
if (problemTypeParameter != null) {
var outerClass: FirRegularClass? = null
context.findClosest<FirRegularClass> {
outerClass = getClassThatContainsTypeParameter(it, problemTypeParameter!!)
return@findClosest outerClass != null
}
if (outerClass != null) {
reporter.reportOn(source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass!!, context)
}
} else {
reporter.reportOn(
source,
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
symbol.fir.typeParameters.size - argumentsFromOuterClassesAndParentsCount,
symbol,
context
)
}
}
for (index in typeArguments.size until typeParameters.size) {
val typeParameter = typeParameters[index]
if (!isValidTypeParameterFromOuterClass(typeParameter, declaration, context.session)) {
val outerClass = typeParameter.containingDeclarationSymbol as FirRegularClassSymbol
reporter.reportOn(typeRef.source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass, context)
break
}
}
}
} else if (typeRef is ConeKotlinType) {
type = typeRef
} else {
return
}
for (index in type.typeArguments.indices) {
@@ -717,7 +717,7 @@ class FirDefaultErrorMessages {
WRONG_NUMBER_OF_TYPE_ARGUMENTS,
"{0,choice,0#No type arguments|1#One type argument|1<{0,number,integer} type arguments} expected for {1}",
null,
SYMBOL
RENDER_CLASS_OR_OBJECT_NAME
)
map.put(
OUTER_CLASS_ARGUMENTS_REQUIRED,
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -80,17 +81,17 @@ object FirDiagnosticRenderers {
"$classOrObject $name"
}
val RENDER_CLASS_OR_OBJECT_NAME = Renderer { firClassLike: FirClassLikeDeclaration ->
val RENDER_CLASS_OR_OBJECT_NAME = Renderer { firClassLike: FirClassLikeSymbol<*> ->
val name = firClassLike.classId.relativeClassName.shortName().asString()
val prefix = when (firClassLike) {
is FirTypeAlias -> "typealias"
is FirRegularClass -> {
is FirTypeAliasSymbol -> "typealias"
is FirRegularClassSymbol -> {
when {
firClassLike.isCompanion -> "companion object"
firClassLike.isInterface -> "interface"
firClassLike.isEnumClass -> "enum class"
firClassLike.isFromEnumClass -> "enum entry"
firClassLike.isLocalClassOrAnonymousObject() -> "object"
firClassLike.isLocalClassOrAnonymousObject -> "object"
else -> "class"
}
}
@@ -68,9 +68,9 @@ private fun ConeDiagnostic.toFirDiagnostic(
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source ?: source)
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
is ConeWrongNumberOfTypeArgumentsError ->
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(this.source ?: qualifiedAccessSource ?: source, this.desiredCount, this.symbol)
is ConeOuterClassArgumentsRequired ->
FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(qualifiedAccessSource ?: source, this.type)
FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(qualifiedAccessSource ?: source, this.symbol)
is ConeNoTypeArgumentsOnRhsError ->
FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
is ConeSimpleDiagnostic -> when (source.kind) {