FIR: introduce classifier scopes #KT-24022 Fixed

This commit is contained in:
Mikhail Glukhikh
2018-03-20 17:27:54 +03:00
parent 1ba498b021
commit d5463193fd
10 changed files with 120 additions and 20 deletions
@@ -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()
@@ -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
}
@@ -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
}
@@ -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)) {
@@ -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 =
@@ -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)
}
}
@@ -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 {
+4
View File
@@ -6,4 +6,8 @@ abstract class My {
}
}
}
class Your : My() {
class NestedThree : NestedOne()
}
+6 -1
View File
@@ -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/ {
}
}