FIR IDE: add ability to specify type argument in KtClassTypeBuilder

This commit is contained in:
Ilya Kirillov
2021-06-11 14:45:59 +02:00
committed by TeamCityServer
parent 148c90dd1e
commit af9e6253e4
4 changed files with 37 additions and 7 deletions
@@ -5,12 +5,14 @@
package org.jetbrains.kotlin.idea.frontend.api.components package org.jetbrains.kotlin.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.types.Variance
abstract class KtTypeCreator : KtAnalysisSessionComponent() { abstract class KtTypeCreator : KtAnalysisSessionComponent() {
abstract fun buildClassType(builder: KtClassTypeBuilder): KtClassType abstract fun buildClassType(builder: KtClassTypeBuilder): KtClassType
@@ -35,16 +37,20 @@ inline fun KtTypeCreatorMixIn.buildClassType(
sealed class KtTypeBuilder sealed class KtTypeBuilder
sealed class KtClassTypeBuilder : KtTypeBuilder() { sealed class KtClassTypeBuilder : KtTypeBuilder() {
private val _arguments = mutableListOf<KtType>() private val _arguments = mutableListOf<KtTypeArgument>()
var nullability: KtTypeNullability = KtTypeNullability.NON_NULLABLE var nullability: KtTypeNullability = KtTypeNullability.NON_NULLABLE
val arguments: List<KtType> get() = _arguments val arguments: List<KtTypeArgument> get() = _arguments
fun argument(argument: KtType) { fun argument(argument: KtTypeArgument) {
_arguments += argument _arguments += argument
} }
fun argument(type: KtType, variance: Variance = Variance.INVARIANT) {
_arguments += KtTypeArgumentWithVariance(type, variance, type.token)
}
class ByClassId(val classId: ClassId) : KtClassTypeBuilder() class ByClassId(val classId: ClassId) : KtClassTypeBuilder()
class BySymbol(val symbol: KtClassOrObjectSymbol) : KtClassTypeBuilder() class BySymbol(val symbol: KtClassOrObjectSymbol) : KtClassTypeBuilder()
} }
@@ -13,7 +13,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.idea.frontend.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
import org.jetbrains.kotlin.idea.asJava.asPsiType import org.jetbrains.kotlin.idea.asJava.asPsiType
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
@@ -22,11 +25,13 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KT_DIAGNOSTIC_CONV
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.types.model.convertVariance
internal interface KtFirAnalysisSessionComponent { internal interface KtFirAnalysisSessionComponent {
val analysisSession: KtFirAnalysisSession val analysisSession: KtFirAnalysisSession
val rootModuleSession: FirSession get() = analysisSession.firResolveState.rootModuleSession val rootModuleSession: FirSession get() = analysisSession.firResolveState.rootModuleSession
val typeContext: ConeInferenceContext get() = rootModuleSession.typeContext
val firSymbolBuilder get() = analysisSession.firSymbolBuilder val firSymbolBuilder get() = analysisSession.firSymbolBuilder
val firResolveState get() = analysisSession.firResolveState val firResolveState get() = analysisSession.firResolveState
@@ -50,6 +55,14 @@ internal interface KtFirAnalysisSessionComponent {
return coneType return coneType
} }
val KtTypeArgument.coneTypeProjection: ConeTypeProjection
get() = when (this) {
is KtStarProjectionTypeArgument -> ConeStarProjection
is KtTypeArgumentWithVariance -> {
typeContext.createTypeArgument(type.coneType, variance.convertVariance()) as ConeTypeProjection
}
}
fun createTypeCheckerContext() = ConeTypeCheckerContext( fun createTypeCheckerContext() = ConeTypeCheckerContext(
isErrorTypeEqualsToAnything = true, isErrorTypeEqualsToAnything = true,
isStubTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true,
@@ -40,9 +40,10 @@ internal class KtFirTypeCreator(
} }
} }
val coneType = rootModuleSession.typeContext.createSimpleType( val typeContext = rootModuleSession.typeContext
val coneType = typeContext.createSimpleType(
lookupTag, lookupTag,
builder.arguments.map { it.coneType }, builder.arguments.map { it.coneTypeProjection },
builder.nullability.isNullable builder.nullability.isNullable
) as ConeClassLikeType ) as ConeClassLikeType
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescrip
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.types.Variance
import org.junit.Test import org.junit.Test
internal class TypeCreatorTest : KotlinLightCodeInsightFixtureTestCase() { internal class TypeCreatorTest : KotlinLightCodeInsightFixtureTestCase() {
@@ -73,6 +74,15 @@ internal class TypeCreatorTest : KotlinLightCodeInsightFixtureTestCase() {
} }
} }
@Test
fun testTypeArgumentVariance() {
doTest("KClass<out Number>") {
buildClassType(StandardClassIds.KClass) {
argument(buildClassType(StandardClassIds.Number), variance = Variance.OUT_VARIANCE)
}
}
}
companion object { companion object {
private val RENDERING_OPTIONS = KtTypeRendererOptions.SHORT_NAMES private val RENDERING_OPTIONS = KtTypeRendererOptions.SHORT_NAMES