diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt index 9682464c2bd..35d08bcb2b0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/descriptors/FirTypeResolveTransformer.kt @@ -6,40 +6,65 @@ package org.jetbrains.kotlin.descriptors import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirTypeResolver -import org.jetbrains.kotlin.fir.scopes.FirImportingScope -import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeImportingScope +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitImportingScope +import org.jetbrains.kotlin.fir.scopes.impl.FirNestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.FirSelfImportingScope +import org.jetbrains.kotlin.fir.transformInplace +import org.jetbrains.kotlin.fir.types.ConeClassType +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirResolvedType import org.jetbrains.kotlin.fir.types.FirType import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.compose +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName class FirTypeResolveTransformer : FirTransformer() { override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { return (element.transformChildren(this, data) as E).compose() } - lateinit var importingScope: FirImportingScope + lateinit var scope: FirCompositeScope + lateinit var packageFqName: FqName + var className: FqName = FqName.ROOT override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { - importingScope = FirCompositeImportingScope( - FirExplicitImportingScope(file.imports), - FirSelfImportingScope(file.packageFqName, file.session) + scope = FirCompositeScope( + mutableListOf( + FirExplicitImportingScope(file.imports), + FirSelfImportingScope(file.packageFqName, file.session) + ) ) + packageFqName = file.packageFqName return file.also { it.transformChildren(this, null) }.compose() } + override fun transformClass(klass: FirClass, data: Nothing?): CompositeTransformResult { + klass.transformChildren(SuperTypeResolver(), null) + className = className.child(klass.name) + scope.scopes += FirNestedClassifierScope(ClassId(packageFqName, className, false), klass.session) + val result = super.transformClass(klass, data) + scope.scopes.also { it.removeAt(it.lastIndex) } + className = className.parent() + + return result + } + override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult { val typeResolver = FirTypeResolver.getInstance(type.session) return FirResolvedTypeImpl( type.session, type.psi, - typeResolver.resolveType(type, importingScope), + typeResolver.resolveType(type, scope), false, type.annotations ).compose() @@ -48,4 +73,22 @@ class FirTypeResolveTransformer : FirTransformer() { override fun transformResolvedType(resolvedType: FirResolvedType, data: Nothing?): CompositeTransformResult { return resolvedType.compose() } + + + private inner class SuperTypeResolver : FirTransformer() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + return element.compose() + } + + override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult { + val transformedType = this@FirTypeResolveTransformer.transformType(type, data).single as FirResolvedType + + val classId = (transformedType.type as? ConeClassType)?.fqName ?: return transformedType.compose() + val firProvider = FirProvider.getInstance(transformedType.session) + // ??? + firProvider.getFirClassifierByFqName(classId)!!.transformChildren(this, data) + + return transformedType.compose() + } + } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt index a93c9121d72..a1a51618ab7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt @@ -6,14 +6,14 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.scopes.FirImportingScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.service import org.jetbrains.kotlin.fir.types.FirType import org.jetbrains.kotlin.fir.types.ConeKotlinType interface FirTypeResolver { - fun resolveType(type: FirType, importingScope: FirImportingScope): ConeKotlinType + fun resolveType(type: FirType, scope: FirScope): ConeKotlinType companion object { fun getInstance(session: FirSession): FirTypeResolver = session.service() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt index a46f533cdbc..3a5a3d70f0b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt @@ -7,12 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.impl import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver import org.jetbrains.kotlin.fir.resolve.FirTypeResolver -import org.jetbrains.kotlin.fir.scopes.FirImportingScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeKotlinErrorType class FirTypeResolverImpl : FirTypeResolver { - override fun resolveType(type: FirType, importingScope: FirImportingScope): ConeKotlinType { + override fun resolveType(type: FirType, scope: FirScope): ConeKotlinType { return when (type) { is FirResolvedType -> type.type is FirUserType -> { @@ -20,7 +20,7 @@ class FirTypeResolverImpl : FirTypeResolver { val qualifierResolver = FirQualifierResolver.getInstance(type.session) var resolvedType: ConeKotlinType? = null - importingScope.processClassifiersByName(type.qualifier.first().name) { fqName -> + scope.processClassifiersByName(type.qualifier.first().name) { fqName -> resolvedType = qualifierResolver.resolveTypeWithPrefix(type.qualifier.drop(1), fqName) resolvedType == null } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt similarity index 92% rename from compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirImportingScope.kt rename to compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt index 5637c23ddc6..78ee8082756 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt @@ -8,6 +8,6 @@ package org.jetbrains.kotlin.fir.scopes import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -interface FirImportingScope { +interface FirScope { fun processClassifiersByName(name: Name, processor: (ClassId) -> Boolean): Boolean } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirCompositeImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirCompositeScope.kt similarity index 79% rename from compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirCompositeImportingScope.kt rename to compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirCompositeScope.kt index 7d119fc67ee..305438a1929 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirCompositeImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirCompositeScope.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.fir.scopes.impl -import org.jetbrains.kotlin.fir.scopes.FirImportingScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -class FirCompositeImportingScope(vararg val scopes: FirImportingScope) : FirImportingScope { +class FirCompositeScope(val scopes: MutableList) : FirScope { override fun processClassifiersByName(name: Name, processor: (ClassId) -> Boolean): Boolean { for (scope in scopes) { if (!scope.processClassifiersByName(name, processor)) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirExplicitImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirExplicitImportingScope.kt index 5bb22149bc9..3612967b21c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirExplicitImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirExplicitImportingScope.kt @@ -7,11 +7,11 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.declarations.FirImport import org.jetbrains.kotlin.fir.declarations.FirResolvedImport -import org.jetbrains.kotlin.fir.scopes.FirImportingScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -class FirExplicitImportingScope(imports: List) : FirImportingScope { +class FirExplicitImportingScope(imports: List) : FirScope { // TODO: Resolve imports! Instead of computing it resolution results here private val simpleImports = diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirNestedClassifierScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirNestedClassifierScope.kt new file mode 100644 index 00000000000..5d699159f8c --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirNestedClassifierScope.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.scopes.impl + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.resolve.FirProvider +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.types.ConeClassType +import org.jetbrains.kotlin.fir.types.FirResolvedType +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name + +class FirNestedClassifierScope(val classId: ClassId, val session: FirSession) : FirScope { + + private val firProvider = FirProvider.getInstance(session) + + fun ClassId.getFir(): FirMemberDeclaration? { + return firProvider.getFirClassifierByFqName(this) + } + + private val superScopes by lazy { + val self = classId.getFir() + when (self) { + is FirClass -> { + val superTypes = self.superTypes as List + FirCompositeScope(superTypes.mapTo(ArrayList(superTypes.size)) { + FirNestedClassifierScope((it.type as ConeClassType).fqName, session) + }) + } + else -> error("!") + } + } + + override fun processClassifiersByName(name: Name, processor: (ClassId) -> Boolean): Boolean { + val child = ClassId(classId.packageFqName, classId.relativeClassName.child(name), false) + if (child.getFir() != null && !processor(child)) return false + + return superScopes.processClassifiersByName(name, processor) + } + + +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfImportingScope.kt index 2896b675c4b..aa8cae7f15d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfImportingScope.kt @@ -7,13 +7,13 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.resolve.FirProvider -import org.jetbrains.kotlin.fir.scopes.FirImportingScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.service import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -class FirSelfImportingScope(val fqName: FqName, val session: FirSession) : FirImportingScope { +class FirSelfImportingScope(val fqName: FqName, val session: FirSession) : FirScope { override fun processClassifiersByName(name: Name, processor: (ClassId) -> Boolean): Boolean { diff --git a/compiler/testData/fir/resolve/NestedSuperType.kt b/compiler/testData/fir/resolve/NestedSuperType.kt index b0c32365dcb..ca28a0dc3dd 100644 --- a/compiler/testData/fir/resolve/NestedSuperType.kt +++ b/compiler/testData/fir/resolve/NestedSuperType.kt @@ -6,4 +6,8 @@ abstract class My { } } +} + +class Your : My() { + class NestedThree : NestedOne() } \ No newline at end of file diff --git a/compiler/testData/fir/resolve/NestedSuperType.txt b/compiler/testData/fir/resolve/NestedSuperType.txt index e27c0724bd6..52f70dc20a0 100644 --- a/compiler/testData/fir/resolve/NestedSuperType.txt +++ b/compiler/testData/fir/resolve/NestedSuperType.txt @@ -1,9 +1,14 @@ FILE: NestedSuperType.kt unknown abstract class My() { unknown abstract class NestedOne() : R/p.My/ { - unknown abstract class NestedTwo() : R/error: Failed to resolve qualified type/ { + unknown abstract class NestedTwo() : R/p.My.NestedOne/ { } } } + unknown final class Your() : R/p.My/ { + unknown final class NestedThree() : R/p.My.NestedOne/ { + } + + }