SLC: add nullity annotation when force-boxing return type

^KT-57579 Fixed
This commit is contained in:
Jinseong Jeon
2023-06-15 13:45:33 -07:00
committed by Space Team
parent 487847bedc
commit 37876313c9
3 changed files with 45 additions and 25 deletions
@@ -211,7 +211,11 @@ internal class SymbolLightAccessorMethod private constructor(
if (nullabilityApplicable) { if (nullabilityApplicable) {
withPropertySymbol { propertySymbol -> withPropertySymbol { propertySymbol ->
if (propertySymbol.isLateInit) NullabilityType.NotNull else getTypeNullability(propertySymbol.returnType) when {
propertySymbol.isLateInit -> NullabilityType.NotNull
forceBoxedReturnType(propertySymbol) -> NullabilityType.NotNull
else -> getTypeNullability(propertySymbol.returnType)
}
} }
} else { } else {
NullabilityType.Unknown NullabilityType.Unknown
@@ -238,18 +242,24 @@ internal class SymbolLightAccessorMethod private constructor(
override fun getNameIdentifier(): PsiIdentifier = KtLightIdentifier(this, containingPropertyDeclaration) override fun getNameIdentifier(): PsiIdentifier = KtLightIdentifier(this, containingPropertyDeclaration)
context(KtAnalysisSession)
private fun forceBoxedReturnType(propertySymbol: KtPropertySymbol): Boolean {
return propertySymbol.returnType.isPrimitive &&
propertySymbol.getAllOverriddenSymbols().any { overriddenSymbol ->
!overriddenSymbol.returnType.isPrimitive
}
}
private val _returnedType: PsiType by lazyPub { private val _returnedType: PsiType by lazyPub {
if (!isGetter) return@lazyPub PsiType.VOID if (!isGetter) return@lazyPub PsiType.VOID
withPropertySymbol { propertySymbol -> withPropertySymbol { propertySymbol ->
val ktType = propertySymbol.returnType val ktType = propertySymbol.returnType
val forceBoxedReturnType = ktType.isPrimitive && val typeMappingMode = if (forceBoxedReturnType(propertySymbol))
propertySymbol.getAllOverriddenSymbols().any { overriddenSymbol -> KtTypeMappingMode.RETURN_TYPE_BOXED
!overriddenSymbol.returnType.isPrimitive else
} KtTypeMappingMode.RETURN_TYPE
val typeMappingMode = if (forceBoxedReturnType) KtTypeMappingMode.RETURN_TYPE_BOXED else KtTypeMappingMode.RETURN_TYPE
ktType.asPsiType( ktType.asPsiType(
this@SymbolLightAccessorMethod, this@SymbolLightAccessorMethod,
@@ -154,11 +154,17 @@ internal class SymbolLightSimpleMethod(
NullabilityType.Unknown NullabilityType.Unknown
} else { } else {
withFunctionSymbol { functionSymbol -> withFunctionSymbol { functionSymbol ->
if (functionSymbol.isSuspend) { // Any? when {
NullabilityType.Nullable functionSymbol.isSuspend -> { // Any?
} else { NullabilityType.Nullable
val returnType = functionSymbol.returnType }
if (returnType.isVoidType) NullabilityType.Unknown else getTypeNullability(returnType) forceBoxedReturnType(functionSymbol) -> {
NullabilityType.NotNull
}
else -> {
val returnType = functionSymbol.returnType
if (returnType.isVoidType) NullabilityType.Unknown else getTypeNullability(returnType)
}
} }
} }
} }
@@ -180,19 +186,18 @@ internal class SymbolLightSimpleMethod(
} }
// Inspired by KotlinTypeMapper#forceBoxedReturnType // Inspired by KotlinTypeMapper#forceBoxedReturnType
private fun forceBoxedReturnType(): Boolean { context(KtAnalysisSession)
return withFunctionSymbol { functionSymbol -> private fun forceBoxedReturnType(functionSymbol: KtFunctionSymbol): Boolean {
val returnType = functionSymbol.returnType val returnType = functionSymbol.returnType
// 'invoke' methods for lambdas, function literals, and callable references // 'invoke' methods for lambdas, function literals, and callable references
// implicitly override generic 'invoke' from a corresponding base class. // implicitly override generic 'invoke' from a corresponding base class.
if (functionSymbol.isBuiltinFunctionInvoke && returnType.isInlineClassType) if (functionSymbol.isBuiltinFunctionInvoke && returnType.isInlineClassType)
return@withFunctionSymbol true return true
returnType.isPrimitive && return returnType.isPrimitive &&
functionSymbol.getAllOverriddenSymbols().any { overriddenSymbol -> functionSymbol.getAllOverriddenSymbols().any { overriddenSymbol ->
!overriddenSymbol.returnType.isPrimitive !overriddenSymbol.returnType.isPrimitive
} }
}
} }
private val KtType.isInlineClassType: Boolean private val KtType.isInlineClassType: Boolean
@@ -208,7 +213,10 @@ internal class SymbolLightSimpleMethod(
functionSymbol.returnType.takeUnless { it.isVoidType } ?: return@withFunctionSymbol PsiType.VOID functionSymbol.returnType.takeUnless { it.isVoidType } ?: return@withFunctionSymbol PsiType.VOID
} }
val typeMappingMode = if (forceBoxedReturnType()) KtTypeMappingMode.RETURN_TYPE_BOXED else KtTypeMappingMode.RETURN_TYPE val typeMappingMode = if (forceBoxedReturnType(functionSymbol))
KtTypeMappingMode.RETURN_TYPE_BOXED
else
KtTypeMappingMode.RETURN_TYPE
ktType.asPsiTypeElement( ktType.asPsiTypeElement(
this@SymbolLightSimpleMethod, this@SymbolLightSimpleMethod,
@@ -2,9 +2,11 @@ public final class C /* C*/ implements Tr {
private final int v; private final int v;
@java.lang.Override() @java.lang.Override()
@org.jetbrains.annotations.NotNull()
public java.lang.Integer foo();// foo() public java.lang.Integer foo();// foo()
@java.lang.Override() @java.lang.Override()
@org.jetbrains.annotations.NotNull()
public java.lang.Integer getV();// getV() public java.lang.Integer getV();// getV()
public C();// .ctor() public C();// .ctor()