FIR: introduce classifier scopes #KT-24022 Fixed
This commit is contained in:
+50
-7
@@ -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<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
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<FirFile> {
|
||||
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<FirDeclaration> {
|
||||
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<FirType> {
|
||||
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<Nothing?>() {
|
||||
override fun transformResolvedType(resolvedType: FirResolvedType, data: Nothing?): CompositeTransformResult<FirType> {
|
||||
return resolvedType.compose()
|
||||
}
|
||||
|
||||
|
||||
private inner class SuperTypeResolver : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
+3
-3
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
+2
-2
@@ -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>) : FirScope {
|
||||
override fun processClassifiersByName(name: Name, processor: (ClassId) -> Boolean): Boolean {
|
||||
for (scope in scopes) {
|
||||
if (!scope.processClassifiersByName(name, processor)) {
|
||||
+2
-2
@@ -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<FirImport>) : FirImportingScope {
|
||||
class FirExplicitImportingScope(imports: List<FirImport>) : FirScope {
|
||||
|
||||
// TODO: Resolve imports! Instead of computing it resolution results here
|
||||
private val simpleImports =
|
||||
|
||||
+48
@@ -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<FirResolvedType>
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
|
||||
|
||||
@@ -6,4 +6,8 @@ abstract class My {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Your : My() {
|
||||
class NestedThree : NestedOne()
|
||||
}
|
||||
+6
-1
@@ -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/ {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user