FIR IDE: introduce KtFunctionalType
This commit is contained in:
+3
-1
@@ -19,6 +19,8 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtNamedSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtFunctionalType
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtTypeArgumentList
|
||||
@@ -109,7 +111,7 @@ private class FunctionLookupElementFactory {
|
||||
|
||||
private fun KtAnalysisSession.insertLambdaBraces(symbol: KtFunctionSymbol): Boolean {
|
||||
val singleParam = symbol.valueParameters.singleOrNull()
|
||||
return singleParam != null && !singleParam.hasDefaultValue && singleParam.annotatedType.type.isBuiltInFunctionalType()
|
||||
return singleParam != null && !singleParam.hasDefaultValue && singleParam.annotatedType.type is KtFunctionalType
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.createInsertHandler(symbol: KtFunctionSymbol): InsertHandler<LookupElement> {
|
||||
|
||||
@@ -77,8 +77,6 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali
|
||||
|
||||
fun PsiElement.getExpectedType(): KtType? = expressionTypeProvider.getExpectedType(this)
|
||||
|
||||
fun KtType.isBuiltInFunctionalType(): Boolean = typeProvider.isBuiltinFunctionalType(this)
|
||||
|
||||
val builtinTypes: KtBuiltinTypes get() = typeProvider.builtinTypes
|
||||
|
||||
fun KtClassOrObjectSymbol.buildSelfClassType(): KtType = typeProvider.buildSelfClassType(this)
|
||||
|
||||
+1
-3
@@ -5,14 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
|
||||
abstract class KtTypeProvider : KtAnalysisSessionComponent() {
|
||||
//TODO get rid of it
|
||||
abstract fun isBuiltinFunctionalType(type: KtType): Boolean
|
||||
|
||||
abstract val builtinTypes: KtBuiltinTypes
|
||||
|
||||
abstract fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType
|
||||
|
||||
@@ -33,12 +33,22 @@ sealed class KtDenotableType : KtType {
|
||||
abstract fun asString(): String
|
||||
}
|
||||
|
||||
abstract class KtClassType : KtDenotableType(), KtTypeWithNullability {
|
||||
sealed class KtClassType : KtDenotableType(), KtTypeWithNullability {
|
||||
abstract val classId: ClassId
|
||||
abstract val classSymbol: KtClassLikeSymbol
|
||||
abstract val typeArguments: List<KtTypeArgument>
|
||||
}
|
||||
|
||||
abstract class KtFunctionalType : KtClassType() {
|
||||
abstract val isSuspend: Boolean
|
||||
abstract val arity: Int
|
||||
abstract val receiverType: KtType?
|
||||
abstract val parameterTypes: List<KtType>
|
||||
abstract val returnType: KtType
|
||||
}
|
||||
|
||||
abstract class KtUsualClassType : KtClassType()
|
||||
|
||||
abstract class KtErrorType : KtType {
|
||||
abstract val error: String
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclaration
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirClassType
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
||||
@@ -161,7 +160,7 @@ internal fun KtType.mapSupertype(
|
||||
annotations: List<KtAnnotationCall>
|
||||
): PsiClassType? {
|
||||
if (this !is KtClassType) return null
|
||||
require(this is KtFirClassType)
|
||||
require(this is KtFirType)
|
||||
val contextSymbol = classSymbol
|
||||
require(contextSymbol is KtFirSymbol<*>)
|
||||
|
||||
|
||||
+8
-1
@@ -9,10 +9,12 @@ import com.google.common.collect.MapMaker
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
@@ -47,6 +49,8 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
private val resolveState by weakRef(resolveState)
|
||||
|
||||
private val firProvider get() = resolveState.rootModuleSession.symbolProvider
|
||||
val rootSession: FirSession = resolveState.rootModuleSession
|
||||
|
||||
|
||||
constructor(
|
||||
resolveState: FirModuleResolveState,
|
||||
@@ -205,7 +209,10 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
|
||||
fun buildKtType(coneType: ConeKotlinType): KtType = typesCache.cache(coneType) {
|
||||
when (coneType) {
|
||||
is ConeClassLikeTypeImpl -> KtFirClassType(coneType, token, this)
|
||||
is ConeClassLikeTypeImpl -> {
|
||||
if (coneType.isFunctionalType(rootSession)) KtFirFunctionalType(coneType, token, this)
|
||||
else KtFirUsualClassType(coneType, token, this)
|
||||
}
|
||||
is ConeTypeParameterType -> KtFirTypeParameterType(coneType, token, this)
|
||||
is ConeClassErrorType -> KtFirErrorType(coneType, token)
|
||||
is ConeFlexibleType -> KtFirFlexibleType(coneType, token, this)
|
||||
|
||||
+4
-3
@@ -11,7 +11,8 @@ import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.components.KtBuiltinTypes
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirClassType
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirUsualClassType
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.ValidityAwareCachedValue
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
@@ -39,7 +40,7 @@ internal class KtFirBuiltInTypes(builtinTypes: BuiltinTypes, builder: KtSymbolBy
|
||||
override val NULLABLE_ANY: KtType by cachedBuiltin(builtinTypes.nullableAnyType)
|
||||
override val NULLABLE_NOTHING: KtType by cachedBuiltin(builtinTypes.nullableNothingType)
|
||||
|
||||
private fun cachedBuiltin(builtinTypeRef: FirImplicitBuiltinTypeRef) = cached {
|
||||
KtFirClassType(builtinTypeRef.type as ConeClassLikeTypeImpl, token, builder) // TODO builder leaking
|
||||
private fun cachedBuiltin(builtinTypeRef: FirImplicitBuiltinTypeRef): ValidityAwareCachedValue<KtFirUsualClassType> = cached {
|
||||
KtFirUsualClassType(builtinTypeRef.type as ConeClassLikeTypeImpl, token, builder) // TODO builder leaking
|
||||
}
|
||||
}
|
||||
-6
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
||||
@@ -23,11 +22,6 @@ internal class KtFirTypeProvider(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
override val token: ValidityToken,
|
||||
) : KtTypeProvider(), KtFirAnalysisSessionComponent {
|
||||
override fun isBuiltinFunctionalType(type: KtType): Boolean = withValidityAssertion {
|
||||
check(type is KtFirType)
|
||||
type.coneType.isBuiltinFunctionalType(analysisSession.firResolveState.rootModuleSession) //TODO use correct session here
|
||||
}
|
||||
|
||||
override val builtinTypes: KtBuiltinTypes =
|
||||
KtFirBuiltInTypes(analysisSession.firResolveState.rootModuleSession.builtinTypes, analysisSession.firSymbolBuilder, token)
|
||||
|
||||
|
||||
+49
-4
@@ -5,8 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.idea.frontend.api.*
|
||||
@@ -26,11 +25,11 @@ internal interface KtFirType : KtType, ValidityTokenOwner {
|
||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
||||
}
|
||||
|
||||
internal class KtFirClassType(
|
||||
internal class KtFirUsualClassType(
|
||||
coneType: ConeClassLikeTypeImpl,
|
||||
override val token: ValidityToken,
|
||||
private val firBuilder: KtSymbolByFirBuilder,
|
||||
) : KtClassType(), KtFirType {
|
||||
) : KtUsualClassType(), KtFirType {
|
||||
override val coneType by weakRef(coneType)
|
||||
|
||||
override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId }
|
||||
@@ -50,6 +49,52 @@ internal class KtFirClassType(
|
||||
}
|
||||
}
|
||||
|
||||
internal class KtFirFunctionalType(
|
||||
coneType: ConeClassLikeTypeImpl,
|
||||
override val token: ValidityToken,
|
||||
private val firBuilder: KtSymbolByFirBuilder,
|
||||
) : KtFunctionalType(), KtFirType {
|
||||
override val coneType by weakRef(coneType)
|
||||
|
||||
override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId }
|
||||
override val classSymbol: KtClassLikeSymbol by cached {
|
||||
firBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag) ?: error("Class ${coneType.lookupTag} was not found")
|
||||
}
|
||||
override val typeArguments: List<KtTypeArgument> by cached {
|
||||
coneType.typeArguments.map { typeArgument ->
|
||||
firBuilder.buildTypeArgument(typeArgument)
|
||||
}
|
||||
}
|
||||
|
||||
override val nullability: KtTypeNullability get() = withValidityAssertion { KtTypeNullability.create(coneType.isNullable) }
|
||||
|
||||
override val isSuspend: Boolean get() = withValidityAssertion { coneType.isSuspendFunctionType(firBuilder.rootSession) }
|
||||
override val arity: Int
|
||||
get() = withValidityAssertion {
|
||||
if (coneType.isExtensionFunctionType) coneType.typeArguments.size - 2
|
||||
else coneType.typeArguments.size - 1
|
||||
}
|
||||
|
||||
override val receiverType: KtType?
|
||||
get() = withValidityAssertion {
|
||||
if (coneType.isExtensionFunctionType) (typeArguments.first() as KtTypeArgumentWithVariance).type
|
||||
else null
|
||||
}
|
||||
|
||||
override val parameterTypes: List<KtType> by cached {
|
||||
val parameterTypeArgs = if (coneType.isExtensionFunctionType) typeArguments.subList(1, typeArguments.lastIndex)
|
||||
else typeArguments.subList(0, typeArguments.lastIndex)
|
||||
parameterTypeArgs.map { (it as KtTypeArgumentWithVariance).type }
|
||||
}
|
||||
|
||||
override val returnType: KtType
|
||||
get() = withValidityAssertion { (typeArguments.last() as KtTypeArgumentWithVariance).type }
|
||||
|
||||
override fun asString(): String = withValidityAssertion {
|
||||
coneType.render() //todo
|
||||
}
|
||||
}
|
||||
|
||||
internal class KtFirErrorType(
|
||||
coneType: ConeClassErrorType,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user