AA: pass wildcard suppression hints on declarations

^KT-61734
This commit is contained in:
Jinseong Jeon
2024-02-22 21:48:47 -08:00
committed by teamcity
parent d089db5a45
commit 9c16c52564
4 changed files with 79 additions and 14 deletions
@@ -45,7 +45,8 @@ internal class KtFe10PsiTypeProvider(
useSitePosition: PsiElement, useSitePosition: PsiElement,
mode: KtTypeMappingMode, mode: KtTypeMappingMode,
isAnnotationMethod: Boolean, isAnnotationMethod: Boolean,
allowErrorTypes: Boolean suppressWildcards: Boolean?,
allowErrorTypes: Boolean,
): PsiTypeElement? { ): PsiTypeElement? {
val kotlinType = (type as KtFe10Type).fe10Type val kotlinType = (type as KtFe10Type).fe10Type
@@ -57,10 +58,18 @@ internal class KtFe10PsiTypeProvider(
if (!analysisSession.useSiteModule.platform.has<JvmPlatform>()) return null if (!analysisSession.useSiteModule.platform.has<JvmPlatform>()) return null
return asPsiTypeElement(simplifyType(kotlinType), useSitePosition, mode.toTypeMappingMode(type, isAnnotationMethod)) return asPsiTypeElement(
simplifyType(kotlinType),
useSitePosition,
mode.toTypeMappingMode(type, isAnnotationMethod, suppressWildcards),
)
} }
private fun KtTypeMappingMode.toTypeMappingMode(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode { private fun KtTypeMappingMode.toTypeMappingMode(
type: KtType,
isAnnotationMethod: Boolean,
suppressWildcards: Boolean?,
): TypeMappingMode {
require(type is KtFe10Type) require(type is KtFe10Type)
return when (this) { return when (this) {
KtTypeMappingMode.DEFAULT -> TypeMappingMode.DEFAULT KtTypeMappingMode.DEFAULT -> TypeMappingMode.DEFAULT
@@ -79,7 +88,11 @@ internal class KtFe10PsiTypeProvider(
if (type.fe10Type.arguments.isEmpty()) if (type.fe10Type.arguments.isEmpty())
typeMappingMode typeMappingMode
else else
typeMappingMode.updateArgumentModeFromAnnotations(type.fe10Type, typeMapper.typeContext) typeMappingMode.updateArgumentModeFromAnnotations(
type.fe10Type,
typeMapper.typeContext,
suppressWildcards,
)
} }
} }
@@ -72,7 +72,8 @@ internal class KtFirPsiTypeProvider(
useSitePosition: PsiElement, useSitePosition: PsiElement,
mode: KtTypeMappingMode, mode: KtTypeMappingMode,
isAnnotationMethod: Boolean, isAnnotationMethod: Boolean,
allowErrorTypes: Boolean suppressWildcards: Boolean?,
allowErrorTypes: Boolean,
): PsiTypeElement? { ): PsiTypeElement? {
val coneType = type.coneType val coneType = type.coneType
@@ -85,10 +86,19 @@ internal class KtFirPsiTypeProvider(
if (!rootModuleSession.moduleData.platform.has<JvmPlatform>()) return null if (!rootModuleSession.moduleData.platform.has<JvmPlatform>()) return null
return coneType.simplifyType(rootModuleSession, useSitePosition) return coneType.simplifyType(rootModuleSession, useSitePosition)
.asPsiTypeElement(rootModuleSession, mode.toTypeMappingMode(type, isAnnotationMethod), useSitePosition, allowErrorTypes) .asPsiTypeElement(
rootModuleSession,
mode.toTypeMappingMode(type, isAnnotationMethod, suppressWildcards),
useSitePosition,
allowErrorTypes,
)
} }
private fun KtTypeMappingMode.toTypeMappingMode(type: KtType, isAnnotationMethod: Boolean): TypeMappingMode { private fun KtTypeMappingMode.toTypeMappingMode(
type: KtType,
isAnnotationMethod: Boolean,
suppressWildcards: Boolean?,
): TypeMappingMode {
require(type is KtFirType) require(type is KtFirType)
val expandedType = type.coneType.fullyExpandedType(rootModuleSession) val expandedType = type.coneType.fullyExpandedType(rootModuleSession)
return when (this) { return when (this) {
@@ -110,7 +120,11 @@ internal class KtFirPsiTypeProvider(
if (expandedType.typeArguments.isEmpty()) if (expandedType.typeArguments.isEmpty())
typeMappingMode typeMappingMode
else else
typeMappingMode.updateArgumentModeFromAnnotations(expandedType, rootModuleSession.jvmTypeMapper.typeContext) typeMappingMode.updateArgumentModeFromAnnotations(
expandedType,
rootModuleSession.jvmTypeMapper.typeContext,
suppressWildcards,
)
} }
} }
@@ -18,7 +18,8 @@ public abstract class KtPsiTypeProvider : KtAnalysisSessionComponent() {
useSitePosition: PsiElement, useSitePosition: PsiElement,
mode: KtTypeMappingMode, mode: KtTypeMappingMode,
isAnnotationMethod: Boolean, isAnnotationMethod: Boolean,
allowErrorTypes: Boolean suppressWildcards: Boolean?,
allowErrorTypes: Boolean,
): PsiTypeElement? ): PsiTypeElement?
public abstract fun asKtType( public abstract fun asKtType(
@@ -46,15 +47,29 @@ public interface KtPsiTypeProviderMixIn : KtAnalysisSessionMixIn {
* *
* If [allowErrorTypes] set to true then erroneous types will be replaced with `error.NonExistentClass` type. * If [allowErrorTypes] set to true then erroneous types will be replaced with `error.NonExistentClass` type.
* *
* [suppressWildcards] indicates whether wild cards in type arguments need to be suppressed or not,
* e.g., according to the annotation on the containing declarations.
* `true` means they should be suppressed;
* `false` means they should appear;
* `null` is no-op by default, i.e., their suppression/appearance is determined by type annotations.
*
* Note: [PsiTypeElement] is JVM conception, so this method will return `null` for non-JVM platforms. * Note: [PsiTypeElement] is JVM conception, so this method will return `null` for non-JVM platforms.
*/ */
public fun KtType.asPsiTypeElement( public fun KtType.asPsiTypeElement(
useSitePosition: PsiElement, useSitePosition: PsiElement,
allowErrorTypes: Boolean, allowErrorTypes: Boolean,
mode: KtTypeMappingMode = KtTypeMappingMode.DEFAULT, mode: KtTypeMappingMode = KtTypeMappingMode.DEFAULT,
isAnnotationMethod: Boolean = false isAnnotationMethod: Boolean = false,
suppressWildcards: Boolean? = null,
): PsiTypeElement? = withValidityAssertion { ): PsiTypeElement? = withValidityAssertion {
analysisSession.psiTypeProvider.asPsiTypeElement(this, useSitePosition, mode, isAnnotationMethod, allowErrorTypes) analysisSession.psiTypeProvider.asPsiTypeElement(
this,
useSitePosition,
mode,
isAnnotationMethod,
suppressWildcards,
allowErrorTypes,
)
} }
/** /**
@@ -70,9 +85,16 @@ public interface KtPsiTypeProviderMixIn : KtAnalysisSessionMixIn {
useSitePosition: PsiElement, useSitePosition: PsiElement,
allowErrorTypes: Boolean, allowErrorTypes: Boolean,
mode: KtTypeMappingMode = KtTypeMappingMode.DEFAULT, mode: KtTypeMappingMode = KtTypeMappingMode.DEFAULT,
isAnnotationMethod: Boolean = false isAnnotationMethod: Boolean = false,
suppressWildcards: Boolean? = null,
): PsiType? = ): PsiType? =
asPsiTypeElement(useSitePosition, allowErrorTypes, mode, isAnnotationMethod)?.type asPsiTypeElement(
useSitePosition,
allowErrorTypes,
mode,
isAnnotationMethod,
suppressWildcards,
)?.type
/** /**
* Converts given [PsiType] to [KtType]. * Converts given [PsiType] to [KtType].
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.name.JvmStandardClassIds.JVM_SUPPRESS_WILDCARDS_ANNO
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
fun TypeMappingMode.updateArgumentModeFromAnnotations( fun TypeMappingMode.updateArgumentModeFromAnnotations(
type: KotlinTypeMarker, typeSystem: TypeSystemCommonBackendContext type: KotlinTypeMarker,
typeSystem: TypeSystemCommonBackendContext,
suppressWildcardsByContainingDeclaration: Boolean? = null,
): TypeMappingMode { ): TypeMappingMode {
type.suppressWildcardsMode(typeSystem)?.let { type.suppressWildcardsMode(typeSystem)?.let {
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode( return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
@@ -34,6 +36,20 @@ fun TypeMappingMode.updateArgumentModeFromAnnotations(
) )
} }
// For example,
// @JvmSuppressWildcards(true)
// fun deepOpen(x: Out<Out<Out<Open>>>) {}
// Instead of the return type, the annotation associated with the declaration indicates that its type signature,
// including return type and parameter types, need to suppress wildcards.
suppressWildcardsByContainingDeclaration?.let {
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = it,
isForAnnotationParameter = isForAnnotationParameter,
needInlineClassWrapping = needInlineClassWrapping,
mapTypeAliases = mapTypeAliases
)
}
return this return this
} }