diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt index 6c21410b410..79366fe886a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt @@ -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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 7a6e3ef49ca..4b9906c88f4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -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 { - 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 -} +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index 9852ef0a413..d66533ecc24 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -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 ) - } + ) } } diff --git a/compiler/testData/diagnostics/tests/generics/genericsInType.fir.kt b/compiler/testData/diagnostics/tests/generics/genericsInType.fir.kt index be6852f4be5..9dddfe2db88 100644 --- a/compiler/testData/diagnostics/tests/generics/genericsInType.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/genericsInType.fir.kt @@ -22,7 +22,7 @@ fun test() { Foo.Bar::class Foo.Bar.Baz::class - a.Bar>() + a.Bar>() a.Bar.Baz>() a>() @@ -30,7 +30,7 @@ fun test() { } fun String.Bar>> x() {} -fun Foo.Bar.ext() {} +fun Foo.Bar.ext() {} fun ex1(a: Foo.Bar): Foo.Bar { }