[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.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.resolve.firProvider 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.PACKAGE_MEMBER
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -231,7 +231,7 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
} }
else -> { else -> {
val factory = if (conflictingDeclaration is FirClassLikeDeclaration && val factory = if (conflictingDeclaration is FirClassLikeDeclaration &&
getOuterClass(conflictingDeclaration, context.session) == null && conflictingDeclaration.getContainingDeclaration(context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> } symbols.any { it is FirClassLikeSymbol<*> }
) { ) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION 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.*
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.declarations.utils.isInner 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.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
@@ -487,29 +488,32 @@ fun isValidTypeParameterFromOuterClass(
return containsTypeParameter(classDeclaration) return containsTypeParameter(classDeclaration)
} }
fun getOuterClassAndActualTypeParametersCount(klass: FirRegularClass, session: FirSession): Pair<FirRegularClass?, Int> { fun FirRegularClass.getActualTypeParametersCount(session: FirSession): Int {
var result = klass.typeParameters.size var result = typeParameters.size
if (!klass.isInner) { if (!isInner) {
return Pair(null, result) return result
} }
val outerClass = getOuterClass(klass, session) val containingClass = getContainingDeclaration(session) as? FirRegularClass
if (outerClass != null) { if (containingClass != null) {
result -= outerClass.typeParameters.size result -= containingClass.typeParameters.size
} }
return Pair(outerClass, result) return result
} }
fun getOuterClass(klass: FirClassLikeDeclaration, session: FirSession): FirRegularClass? { fun FirClassLikeDeclaration.getContainingDeclaration(session: FirSession): FirClassLikeDeclaration? {
val classId = klass.symbol.classId if (isLocal) {
val parentId = classId.relativeClassName.parent() return (this as? FirRegularClass)?.containingClassForLocalAttr?.toFirRegularClass(session)
if (!parentId.isRoot) { } else {
val outerClassId = ClassId(classId.packageFqName, parentId, false) val classId = symbol.classId
val parentSymbol = session.symbolProvider.getClassLikeSymbolByFqName(outerClassId) val parentId = classId.relativeClassName.parent()
return (parentSymbol as? FirRegularClassSymbol)?.fir if (!parentId.isRoot) {
val containingDeclarationId = ClassId(classId.packageFqName, parentId, false)
return session.symbolProvider.getClassLikeSymbolByFqName(containingDeclarationId)?.fir
}
} }
return null return null
} }
@@ -208,8 +208,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
parameterClass, parameterClass,
index, index,
symbol, symbol,
typeRef, typeRef
ignoreOuterClassCheck = true
)?.let { return it } )?.let { return it }
} }
} }
@@ -242,7 +241,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
currentClass = symbol.fir currentClass = symbol.fir
} else { } else {
if (currentClass != null) { 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, qualifierPartIndex: Int,
symbol: FirRegularClassSymbol, symbol: FirRegularClassSymbol,
userTypeRef: FirUserTypeRef, userTypeRef: FirUserTypeRef,
qualifierPartArgumentsCount: Int? = null, qualifierPartArgumentsCount: Int? = null
ignoreOuterClassCheck: Boolean = false
): ConeClassErrorType? { ): ConeClassErrorType? {
// TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null // TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null
val (outerClass, actualTypeParametersCount) = getOuterClassAndActualTypeParametersCount( val actualTypeParametersCount = (parameterClass ?: symbol.fir).getActualTypeParametersCount(session)
parameterClass ?: symbol.fir,
session
)
if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) { if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) {
// TODO: fix obtaining outer class for cases like val source = getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex)
// https://github.com/JetBrains/kotlin/blob/master/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.kt#L16 if (source != null) {
if (ignoreOuterClassCheck || return ConeClassErrorType(
(parameterClass != null && parameterClass.classId.relativeClassName.parent().isRoot) ConeWrongNumberOfTypeArgumentsError(
|| outerClass != null actualTypeParametersCount,
) { parameterClass?.symbol ?: symbol,
val source = getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex) source
if (source != null) {
return ConeClassErrorType(
ConeWrongNumberOfTypeArgumentsError(
actualTypeParametersCount,
parameterClass?.symbol ?: symbol,
source
)
) )
} )
} }
} }
@@ -22,7 +22,7 @@ fun test() {
Foo<String>.Bar::class Foo<String>.Bar::class
Foo<String>.Bar.Baz::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<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar.Baz>()
a<Foo.Bar<Int>>() a<Foo.Bar<Int>>()
@@ -30,7 +30,7 @@ fun test() {
} }
fun <T: Foo<<!UNRESOLVED_REFERENCE!>String.Bar<!>>> x() {} 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> { 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!>}<!> <!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>