[FIR] Rename getOuterClass to getContainingDeclaration, fix if for local classes

Simplify checking of WRONG_NUMBER_OF_TYPE_ARGUMENTS
This commit is contained in:
Ivan Kochurkin
2021-08-12 15:12:34 +03:00
committed by TeamCityServer
parent 816e8f487c
commit d4746903c8
4 changed files with 36 additions and 44 deletions
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.getOuterClass
import org.jetbrains.kotlin.fir.resolve.getContainingDeclaration
import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -231,7 +231,7 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
}
else -> {
val factory = if (conflictingDeclaration is FirClassLikeDeclaration &&
getOuterClass(conflictingDeclaration, context.session) == null &&
conflictingDeclaration.getContainingDeclaration(context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> }
) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
@@ -487,29 +488,32 @@ fun isValidTypeParameterFromOuterClass(
return containsTypeParameter(classDeclaration)
}
fun getOuterClassAndActualTypeParametersCount(klass: FirRegularClass, session: FirSession): Pair<FirRegularClass?, Int> {
var result = klass.typeParameters.size
fun FirRegularClass.getActualTypeParametersCount(session: FirSession): Int {
var result = typeParameters.size
if (!klass.isInner) {
return Pair(null, result)
if (!isInner) {
return result
}
val outerClass = getOuterClass(klass, session)
if (outerClass != null) {
result -= outerClass.typeParameters.size
val containingClass = getContainingDeclaration(session) as? FirRegularClass
if (containingClass != null) {
result -= containingClass.typeParameters.size
}
return Pair(outerClass, result)
return result
}
fun getOuterClass(klass: FirClassLikeDeclaration, session: FirSession): FirRegularClass? {
val classId = klass.symbol.classId
val parentId = classId.relativeClassName.parent()
if (!parentId.isRoot) {
val outerClassId = ClassId(classId.packageFqName, parentId, false)
val parentSymbol = session.symbolProvider.getClassLikeSymbolByFqName(outerClassId)
return (parentSymbol as? FirRegularClassSymbol)?.fir
fun FirClassLikeDeclaration.getContainingDeclaration(session: FirSession): FirClassLikeDeclaration? {
if (isLocal) {
return (this as? FirRegularClass)?.containingClassForLocalAttr?.toFirRegularClass(session)
} else {
val classId = symbol.classId
val parentId = classId.relativeClassName.parent()
if (!parentId.isRoot) {
val containingDeclarationId = ClassId(classId.packageFqName, parentId, false)
return session.symbolProvider.getClassLikeSymbolByFqName(containingDeclarationId)?.fir
}
}
return null
}
}
@@ -208,8 +208,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
parameterClass,
index,
symbol,
typeRef,
ignoreOuterClassCheck = true
typeRef
)?.let { return it }
}
}
@@ -242,7 +241,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
currentClass = symbol.fir
} else {
if (currentClass != null) {
currentClass = getOuterClass(currentClass, session)
currentClass = currentClass.getContainingDeclaration(session) as? FirRegularClass
}
}
@@ -285,32 +284,21 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
qualifierPartIndex: Int,
symbol: FirRegularClassSymbol,
userTypeRef: FirUserTypeRef,
qualifierPartArgumentsCount: Int? = null,
ignoreOuterClassCheck: Boolean = false
qualifierPartArgumentsCount: Int? = null
): ConeClassErrorType? {
// TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null
val (outerClass, actualTypeParametersCount) = getOuterClassAndActualTypeParametersCount(
parameterClass ?: symbol.fir,
session
)
val actualTypeParametersCount = (parameterClass ?: symbol.fir).getActualTypeParametersCount(session)
if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) {
// TODO: fix obtaining outer class for cases like
// https://github.com/JetBrains/kotlin/blob/master/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.kt#L16
if (ignoreOuterClassCheck ||
(parameterClass != null && parameterClass.classId.relativeClassName.parent().isRoot)
|| outerClass != null
) {
val source = getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex)
if (source != null) {
return ConeClassErrorType(
ConeWrongNumberOfTypeArgumentsError(
actualTypeParametersCount,
parameterClass?.symbol ?: symbol,
source
)
val source = getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex)
if (source != null) {
return ConeClassErrorType(
ConeWrongNumberOfTypeArgumentsError(
actualTypeParametersCount,
parameterClass?.symbol ?: symbol,
source
)
}
)
}
}
@@ -22,7 +22,7 @@ fun test() {
Foo<String>.Bar::class
Foo<String>.Bar.Baz::class
a<Foo<String>.Bar>()
a<Foo<String>.<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Bar<!>>()
a<Foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar.Baz>()
a<Foo.Bar<Int>>()
@@ -30,7 +30,7 @@ fun test() {
}
fun <T: Foo<<!UNRESOLVED_REFERENCE!>String.Bar<!>>> x() {}
fun Foo<String>.Bar.ext() {}
fun Foo<String>.<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Bar<!>.ext() {}
fun ex1(a: Foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar<String>): Foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar<String> {
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>