FIR: introduce type resolvers #KT-24019 Fixed

This commit is contained in:
Simon Ogorodnik
2018-03-20 01:25:51 +03:00
committed by Mikhail Glukhikh
parent aa20d88dff
commit 3e7b9c4e27
22 changed files with 386 additions and 3 deletions
@@ -13,7 +13,7 @@ class ConeClassTypeImpl(
override val typeArguments: List<ConeKotlinTypeProjection>
) : ConeClassType()
class NewKotlinTypeProjectionInImpl(override val type: ConeKotlinType) : ConeKotlinTypeProjectionIn()
class ConeKotlinTypeProjectionInImpl(override val type: ConeKotlinType) : ConeKotlinTypeProjectionIn()
class ConeKotlinTypeProjectionOutImpl(override val type: ConeKotlinType) : ConeKotlinTypeProjectionOut()
@@ -0,0 +1,21 @@
/*
* 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.descriptors
import org.jetbrains.kotlin.fir.UnambiguousFqName
import org.jetbrains.kotlin.fir.declarations.FirResolvedClass
import org.jetbrains.kotlin.fir.descriptors.ConeClassDescriptor
import org.jetbrains.kotlin.fir.descriptors.ConeClassifierDescriptor
import org.jetbrains.kotlin.fir.descriptors.ConeTypeParameterDescriptor
import org.jetbrains.kotlin.fir.types.ConeKotlinType
class ConeClassDescriptorImpl(
override val typeParameters: List<ConeTypeParameterDescriptor>,
override val fqName: UnambiguousFqName,
override val superTypes: List<ConeKotlinType>,
override val nestedClassifiers: List<ConeClassifierDescriptor>
) : ConeClassDescriptor, AbstractFirBasedDescriptor<FirResolvedClass>() {
}
@@ -0,0 +1,80 @@
/*
* 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.descriptors
import org.jetbrains.kotlin.fir.FirDescriptorOwner
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.UnambiguousFqName
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedClassImpl
import org.jetbrains.kotlin.fir.descriptors.ConeClassifierDescriptor
import org.jetbrains.kotlin.fir.descriptors.ConeTypeParameterDescriptor
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
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.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
class FirClassifierResolveTransformer : FirTransformer<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose()
}
lateinit var packageFqName: FqNameUnsafe
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
packageFqName = file.packageFqName.toUnsafe()
return file.also { it.acceptChildren(this, null) }.compose()
}
// TODO: Extract to separate transformer?
override fun transformType(type: FirType, data: Nothing?): CompositeTransformResult<FirType> {
val typeResolver = FirTypeResolver.getInstance(type.session)
return FirResolvedTypeImpl(type.session, type.psi, typeResolver.resolveType(type), false, type.annotations).compose()
}
override fun transformResolvedType(resolvedType: FirResolvedType, data: Nothing?): CompositeTransformResult<FirType> {
return resolvedType.compose()
}
var className: FqName = FqName.ROOT
override fun transformClass(klass: FirClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
val actualClassName = className.child(klass.name)
className = actualClassName
klass.transformChildren(this, data)
val superTypes = klass.superTypes.map {
(it as FirResolvedType).type
}
className = className.parent()
val typeParameters =
klass.typeParameters.filterIsInstance<FirDescriptorOwner<*>>().mapNotNull { it.descriptor as? ConeTypeParameterDescriptor }
val nestedClassifiers =
klass.declarations.filterIsInstance<FirDescriptorOwner<*>>().mapNotNull { it.descriptor as? ConeClassifierDescriptor }
val descriptor = ConeClassDescriptorImpl(
typeParameters,
UnambiguousFqName(packageFqName, actualClassName),
superTypes,
nestedClassifiers
)
return FirResolvedClassImpl(klass, descriptor).compose()
}
override fun transformResolvedClass(resolvedClass: FirResolvedClass, data: Nothing?): CompositeTransformResult<FirDeclaration> {
return resolvedClass.compose()
}
}
@@ -0,0 +1,21 @@
/*
* 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.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirQualifierPart
interface FirQualifierResolver {
fun resolveType(parts: List<FirQualifierPart>): ConeKotlinType?
companion object {
fun getInstance(session: FirSession): FirQualifierResolver = session.service()
}
}
@@ -0,0 +1,61 @@
/*
* 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.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.UnambiguousFqName
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinTypeProjectionInImpl
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinTypeProjectionOutImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.Variance
class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver {
override fun resolveType(parts: List<FirQualifierPart>): ConeKotlinType? {
val firProvider = FirProvider.getInstance(session)
if (parts.isNotEmpty()) {
val lastPart = mutableListOf<FirQualifierPart>()
val firstPart = parts.toMutableList()
while (firstPart.isNotEmpty()) {
lastPart.add(0, firstPart.last())
firstPart.removeAt(firstPart.lastIndex)
val fqName = UnambiguousFqName(firstPart.toFqNameUnsafe(), lastPart.toFqName())
val foundClassifier = firProvider.getFirClassifierByFqName(fqName)
if (foundClassifier != null) {
return ConeClassTypeImpl(fqName, parts.flatMap {
it.typeArguments.map {
when (it) {
is FirStarProjection -> StarProjection
is FirTypeProjectionWithVariance -> {
val type = (it.type as FirResolvedType).type
when (it.variance) {
Variance.INVARIANT -> type
Variance.IN_VARIANCE -> ConeKotlinTypeProjectionInImpl(type)
Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOutImpl(type)
}
}
else -> error("!")
}
}
})
}
}
return null
} else {
return null
}
}
private fun List<FirQualifierPart>.toFqNameUnsafe() = toFqName().toUnsafe()
private fun List<FirQualifierPart>.toFqName() = fold(FqName.ROOT) { a, b -> a.child(b.name) }
}
@@ -5,6 +5,16 @@
package org.jetbrains.kotlin.fir.resolve
class FirTypeResolver {
import org.jetbrains.kotlin.fir.FirSession
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): ConeKotlinType
companion object {
fun getInstance(session: FirSession): FirTypeResolver = session.service()
}
}
@@ -0,0 +1,31 @@
/*
* 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.resolve.impl
import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver
import org.jetbrains.kotlin.fir.resolve.FirTypeResolver
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeKotlinErrorType
class FirTypeResolverImpl : FirTypeResolver {
override fun resolveType(type: FirType): ConeKotlinType {
return when (type) {
is FirResolvedType -> type.type
is FirUserType -> {
val qualifierResolver = FirQualifierResolver.getInstance(type.session)
// TODO: Imports
qualifierResolver.resolveType(type.qualifier) ?: ConeKotlinErrorType("Failed to resolve qualified type")
}
is FirErrorType -> {
ConeKotlinErrorType(type.reason)
}
is FirFunctionType, is FirDynamicType, is FirImplicitType, is FirDelegatedType -> {
ConeKotlinErrorType("Not supported: $type")
}
else -> error("!")
}
}
}
@@ -371,7 +371,12 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
is ConeClassType -> {
val sb = StringBuilder()
val fqName = fqName
sb.append(fqName.packageFqName.asString().replace('.', '/'))
val packageFqName = fqName.packageFqName
if (packageFqName.isRoot) {
sb.append("<root>")
} else {
sb.append(packageFqName.asString().replace('.', '/'))
}
sb.append('.')
sb.append(fqName.classFqName.asString())
sb.append(typeArguments.joinToString { it ->
@@ -0,0 +1,10 @@
/*
* 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.declarations
import org.jetbrains.kotlin.fir.FirDescriptorOwner
interface FirResolvedClass : FirClass, FirDescriptorOwner<FirResolvedClass>
@@ -0,0 +1,19 @@
/*
* 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.declarations.impl
import org.jetbrains.kotlin.fir.FirBasedDescriptor
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirResolvedClass
class FirResolvedClassImpl(val delegate: FirClass, override val descriptor: FirBasedDescriptor<FirResolvedClass>) :
FirResolvedClass, FirClass by delegate {
init {
descriptor.bind(this)
}
}
@@ -66,6 +66,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformClass(enumEntry, data)
}
open fun transformResolvedClass(resolvedClass: FirResolvedClass, data: D): CompositeTransformResult<FirDeclaration> {
return transformClass(resolvedClass, data)
}
open fun transformTypeAlias(typeAlias: FirTypeAlias, data: D): CompositeTransformResult<FirDeclaration> {
return transformMemberDeclaration(typeAlias, data)
}
@@ -246,6 +250,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformEnumEntry(enumEntry, data)
}
final override fun visitResolvedClass(resolvedClass: FirResolvedClass, data: D): CompositeTransformResult<FirElement> {
return transformResolvedClass(resolvedClass, data)
}
final override fun visitCallableMember(callableMember: FirCallableMember, data: D): CompositeTransformResult<FirElement> {
return transformCallableMember(callableMember, data)
}
@@ -66,6 +66,10 @@ abstract class FirVisitor<out R, in D> {
return visitClass(enumEntry, data)
}
open fun visitResolvedClass(resolvedClass: FirResolvedClass, data: D): R {
return visitClass(resolvedClass, data)
}
open fun visitTypeAlias(typeAlias: FirTypeAlias, data: D): R {
return visitMemberDeclaration(typeAlias, data)
}
@@ -66,6 +66,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitClass(enumEntry, null)
}
open fun visitResolvedClass(resolvedClass: FirResolvedClass) {
visitClass(resolvedClass, null)
}
open fun visitTypeAlias(typeAlias: FirTypeAlias) {
visitMemberDeclaration(typeAlias, null)
}
@@ -246,6 +250,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitEnumEntry(enumEntry)
}
final override fun visitResolvedClass(resolvedClass: FirResolvedClass, data: Nothing?) {
visitResolvedClass(resolvedClass)
}
final override fun visitCallableMember(callableMember: FirCallableMember, data: Nothing?) {
visitCallableMember(callableMember)
}