FIR: introduce type resolvers #KT-24019 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
aa20d88dff
commit
3e7b9c4e27
@@ -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>() {
|
||||
}
|
||||
+80
@@ -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("!")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user