FIR IDE/LC: introduce/use KtTypeMappingMode

This commit is contained in:
Jinseong Jeon
2021-11-04 15:06:42 -07:00
committed by Ilya Kirillov
parent 0da9ef873a
commit 4eec381d1b
12 changed files with 114 additions and 55 deletions
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10JvmTypeMapperContext
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
@@ -32,24 +33,34 @@ internal class KtFe10PsiTypeProvider(override val analysisSession: KtFe10Analysi
private val typeMapper by lazy { KtFe10JvmTypeMapperContext(analysisSession.resolveSession) }
override fun asPsiType(type: KtType, useSitePosition: PsiElement, mode: TypeMappingMode): PsiType? = withValidityAssertion {
override fun asPsiType(
type: KtType,
useSitePosition: PsiElement,
mode: KtTypeMappingMode,
isAnnotationMethod: Boolean,
): PsiType? = withValidityAssertion {
val kotlinType = (type as KtFe10Type).type
if (kotlinType.isError || kotlinType.arguments.any { !it.isStarProjection && it.type.isError }) {
return null
}
return asPsiType(simplifyType(kotlinType), useSitePosition, mode)
return asPsiType(simplifyType(kotlinType), useSitePosition, mode.toTypeMappingMode(type, isAnnotationMethod))
}
override fun getOptimalModeForReturnType(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode = withValidityAssertion {
private fun KtTypeMappingMode.toTypeMappingMode(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode {
require(type is KtFe10Type)
typeMapper.typeContext.getOptimalModeForReturnType(type.type, isAnnotationMethod)
}
override fun getOptimalModeForValueParameter(type: KtType): TypeMappingMode = withValidityAssertion {
require(type is KtFe10Type)
typeMapper.typeContext.getOptimalModeForValueParameter(type.type)
return when (this) {
KtTypeMappingMode.DEFAULT -> TypeMappingMode.DEFAULT
KtTypeMappingMode.DEFAULT_UAST -> TypeMappingMode.DEFAULT_UAST
KtTypeMappingMode.GENERIC_ARGUMENT -> TypeMappingMode.GENERIC_ARGUMENT
KtTypeMappingMode.SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
KtTypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS -> TypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS
KtTypeMappingMode.RETURN_TYPE ->
typeMapper.typeContext.getOptimalModeForReturnType(type.type, isAnnotationMethod)
KtTypeMappingMode.VALUE_PARAMETER ->
typeMapper.typeContext.getOptimalModeForValueParameter(type.type)
}
}
private fun simplifyType(type: UnwrappedType): KotlinType {
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.withFirDeclaration
@@ -55,19 +56,30 @@ internal class KtFirPsiTypeProvider(
override fun asPsiType(
type: KtType,
useSitePosition: PsiElement,
mode: TypeMappingMode,
mode: KtTypeMappingMode,
isAnnotationMethod: Boolean,
): PsiType? = withValidityAssertion {
type.coneType.asPsiType(rootModuleSession, analysisSession.firResolveState, mode, useSitePosition)
type.coneType.asPsiType(
rootModuleSession,
analysisSession.firResolveState,
mode.toTypeMappingMode(type, isAnnotationMethod),
useSitePosition
)
}
override fun getOptimalModeForReturnType(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode = withValidityAssertion {
private fun KtTypeMappingMode.toTypeMappingMode(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode {
require(type is KtFirType)
rootModuleSession.jvmTypeMapper.typeContext.getOptimalModeForReturnType(type.coneType, isAnnotationMethod)
}
override fun getOptimalModeForValueParameter(type: KtType): TypeMappingMode = withValidityAssertion {
require(type is KtFirType)
rootModuleSession.jvmTypeMapper.typeContext.getOptimalModeForValueParameter(type.coneType)
return when (this) {
KtTypeMappingMode.DEFAULT -> TypeMappingMode.DEFAULT
KtTypeMappingMode.DEFAULT_UAST -> TypeMappingMode.DEFAULT_UAST
KtTypeMappingMode.GENERIC_ARGUMENT -> TypeMappingMode.GENERIC_ARGUMENT
KtTypeMappingMode.SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
KtTypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS -> TypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS
KtTypeMappingMode.RETURN_TYPE ->
rootModuleSession.jvmTypeMapper.typeContext.getOptimalModeForReturnType(type.coneType, isAnnotationMethod)
KtTypeMappingMode.VALUE_PARAMETER ->
rootModuleSession.jvmTypeMapper.typeContext.getOptimalModeForValueParameter(type.coneType)
}
}
}
@@ -8,12 +8,15 @@ package org.jetbrains.kotlin.analysis.api.components
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
public abstract class KtPsiTypeProvider : KtAnalysisSessionComponent() {
public abstract fun asPsiType(type: KtType, useSitePosition: PsiElement, mode: TypeMappingMode): PsiType?
public abstract fun getOptimalModeForReturnType(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode
public abstract fun getOptimalModeForValueParameter(type: KtType): TypeMappingMode
public abstract fun asPsiType(
type: KtType,
useSitePosition: PsiElement,
mode: KtTypeMappingMode,
isAnnotationMethod: Boolean,
): PsiType?
}
public interface KtPsiTypeProviderMixIn : KtAnalysisSessionMixIn {
@@ -35,13 +38,9 @@ public interface KtPsiTypeProviderMixIn : KtAnalysisSessionMixIn {
*/
public fun KtType.asPsiType(
useSitePosition: PsiElement,
mode: TypeMappingMode = TypeMappingMode.DEFAULT,
mode: KtTypeMappingMode = KtTypeMappingMode.DEFAULT,
isAnnotationMethod: Boolean = false,
): PsiType? =
analysisSession.psiTypeProvider.asPsiType(this, useSitePosition, mode)
analysisSession.psiTypeProvider.asPsiType(this, useSitePosition, mode, isAnnotationMethod)
public fun KtType.getOptimalModeForReturnType(isAnnotationMethod: Boolean): TypeMappingMode =
analysisSession.psiTypeProvider.getOptimalModeForReturnType(this, isAnnotationMethod)
public fun KtType.getOptimalModeForValueParameter(): TypeMappingMode =
analysisSession.psiTypeProvider.getOptimalModeForValueParameter(this)
}
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.analysis.api.types
public enum class KtTypeMappingMode {
/**
* kotlin.Int is mapped to I
*/
DEFAULT,
/**
* kotlin.Int is mapped to I
* Type aliases are mapped to their expanded form
*/
DEFAULT_UAST,
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
*/
GENERIC_ARGUMENT,
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
* No projections allowed in immediate arguments
*/
SUPER_TYPE,
/**
* Similar to [SUPER_TYPE], except for that Kotlin collections remain as-is.
*/
SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS,
/**
* Optimal mode to convert the return type of declarations if it's part of signature.
*/
RETURN_TYPE,
/**
* Optimal mode to convert the type of value parameter if it's part of signature.
*/
VALUE_PARAMETER,
}
@@ -10,11 +10,11 @@ import com.intellij.psi.impl.PsiClassImplUtil
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.analysis.api.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.classes.createConstructors
import org.jetbrains.kotlin.light.classes.symbol.classes.createMethods
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.psi.KtClassOrObject
internal class FirLightClassForEnumEntry(
@@ -82,8 +82,7 @@ internal class FirLightClassForEnumEntry(
private val _extendsList: PsiReferenceList? by lazyPub {
val mappedType = analyzeWithSymbolAsContext(enumEntrySymbol) {
enumEntrySymbol.annotatedType
.type.asPsiType(this@FirLightClassForEnumEntry, TypeMappingMode.SUPER_TYPE) as? PsiClassType
enumEntrySymbol.annotatedType.type.asPsiType(this@FirLightClassForEnumEntry, KtTypeMappingMode.SUPER_TYPE) as? PsiClassType
?: return@lazyPub null
}
@@ -67,8 +67,7 @@ internal class FirLightFieldForEnumEntry(
private val _type: PsiType by lazyPub {
analyzeWithSymbolAsContext(enumEntrySymbol) {
enumEntrySymbol.annotatedType.type.asPsiType(this@FirLightFieldForEnumEntry)
?: this@FirLightFieldForEnumEntry.nonExistentType()
}
} ?: nonExistentType()
}
override fun getType(): PsiType = _type
@@ -41,8 +41,7 @@ internal class FirLightFieldForObjectSymbol(
private val _type: PsiType by lazyPub {
analyzeWithSymbolAsContext(objectSymbol) {
objectSymbol.buildSelfClassType().asPsiType(this@FirLightFieldForObjectSymbol)
?: this@FirLightFieldForObjectSymbol.nonExistentType()
}
} ?: nonExistentType()
}
private val _identifier: PsiIdentifier by lazyPub {
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.api.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtLiteralConstantValue
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtProperty
@@ -34,18 +35,10 @@ internal class FirLightFieldForPropertySymbol(
when {
isDelegated ->
(kotlinOrigin as? KtProperty)?.delegateExpression?.let {
val ktType = it.getKtType()
ktType?.asPsiType(
this@FirLightFieldForPropertySymbol,
ktType.getOptimalModeForReturnType(containingClass.isAnnotationType)
)
it.getKtType()?.asPsiType(this@FirLightFieldForPropertySymbol, KtTypeMappingMode.RETURN_TYPE)
}
else -> {
val ktType = propertySymbol.annotatedType.type
ktType.asPsiType(
this@FirLightFieldForPropertySymbol,
ktType.getOptimalModeForReturnType(containingClass.isAnnotationType)
)
propertySymbol.annotatedType.type.asPsiType(this@FirLightFieldForPropertySymbol, KtTypeMappingMode.RETURN_TYPE)
}
}
} ?: nonExistentType()
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.types.*
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.SpecialNames
import java.util.*
@@ -43,7 +42,7 @@ internal fun KtAnalysisSession.mapSuperType(
if (type !is KtNonErrorClassType) return null
val psiType = type.asPsiType(
psiContext,
if (kotlinCollectionAsIs) TypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS else TypeMappingMode.SUPER_TYPE,
if (kotlinCollectionAsIs) KtTypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS else KtTypeMappingMode.SUPER_TYPE,
)
return psiType as? PsiClassType
}
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyAccessorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.load.java.JvmAbi.getterName
import org.jetbrains.kotlin.load.java.JvmAbi.setterName
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -150,10 +151,10 @@ internal class FirLightAccessorMethodForSymbol(
private val _returnedType: PsiType by lazyPub {
if (!isGetter) return@lazyPub PsiType.VOID
analyzeWithSymbolAsContext(containingPropertySymbol) {
val ktType = containingPropertySymbol.annotatedType.type
ktType.asPsiType(
containingPropertySymbol.annotatedType.type.asPsiType(
this@FirLightAccessorMethodForSymbol,
ktType.getOptimalModeForReturnType(containingClass.isAnnotationType)
KtTypeMappingMode.RETURN_TYPE,
containingClass.isAnnotationType
)
} ?: nonExistentType()
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.analysis.api.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
import java.util.*
@@ -147,7 +148,8 @@ internal class FirLightSimpleMethodForSymbol(
}
ktType.asPsiType(
this@FirLightSimpleMethodForSymbol,
ktType.getOptimalModeForReturnType(containingClass.isAnnotationType)
KtTypeMappingMode.RETURN_TYPE,
containingClass.isAnnotationType
)
} ?: nonExistentType()
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.light.classes.symbol
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.psi.KtParameter
internal abstract class FirLightParameterBaseForSymbol(
@@ -49,10 +49,10 @@ internal abstract class FirLightParameterBaseForSymbol(
val convertedType = analyzeWithSymbolAsContext(parameterSymbol) {
val ktType = parameterSymbol.annotatedType.type
val typeMappingMode = when {
ktType.isSuspendFunctionType -> TypeMappingMode.DEFAULT
ktType.isSuspendFunctionType -> KtTypeMappingMode.DEFAULT
// TODO: extract type mapping mode from annotation?
// TODO: methods with declaration site wildcards?
else -> ktType.getOptimalModeForValueParameter()
else -> KtTypeMappingMode.VALUE_PARAMETER
}
ktType.asPsiType(this@FirLightParameterBaseForSymbol, typeMappingMode)
} ?: nonExistentType()