SLC: force boxed return type when needed
e.g., when overriding a function whose return type is not primitive ^KT-57579 Fixed
This commit is contained in:
committed by
Dmitrii Gridin
parent
19dbe69651
commit
1b3b554084
+1
@@ -62,6 +62,7 @@ internal class KtFe10PsiTypeProvider(
|
||||
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_BOXED -> TypeMappingMode.RETURN_TYPE_BOXED
|
||||
KtTypeMappingMode.RETURN_TYPE ->
|
||||
typeMapper.typeContext.getOptimalModeForReturnType(type.fe10Type, isAnnotationMethod)
|
||||
KtTypeMappingMode.VALUE_PARAMETER ->
|
||||
|
||||
+1
@@ -76,6 +76,7 @@ internal class KtFirPsiTypeProvider(
|
||||
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_BOXED -> TypeMappingMode.RETURN_TYPE_BOXED
|
||||
KtTypeMappingMode.RETURN_TYPE ->
|
||||
rootModuleSession.jvmTypeMapper.typeContext.getOptimalModeForReturnType(type.coneType, isAnnotationMethod)
|
||||
KtTypeMappingMode.VALUE_PARAMETER ->
|
||||
|
||||
@@ -33,6 +33,11 @@ public enum class KtTypeMappingMode {
|
||||
*/
|
||||
SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS,
|
||||
|
||||
/**
|
||||
* When method return type should be boxed (e.g., kotlin.Int to Ljava/lang/Integer;)
|
||||
*/
|
||||
RETURN_TYPE_BOXED,
|
||||
|
||||
/**
|
||||
* Optimal mode to convert the return type of declarations if it's part of signature.
|
||||
*/
|
||||
|
||||
+11
-2
@@ -238,10 +238,19 @@ internal class SymbolLightAccessorMethod private constructor(
|
||||
if (!isGetter) return@lazyPub PsiType.VOID
|
||||
|
||||
containingPropertySymbolPointer.withSymbol(ktModule) { propertySymbol ->
|
||||
propertySymbol.returnType.asPsiType(
|
||||
val ktType = propertySymbol.returnType
|
||||
|
||||
val forceBoxedReturnType = ktType.isPrimitive &&
|
||||
propertySymbol.getAllOverriddenSymbols().any { overriddenSymbol ->
|
||||
!overriddenSymbol.returnType.isPrimitive
|
||||
}
|
||||
|
||||
val typeMappingMode = if (forceBoxedReturnType) KtTypeMappingMode.RETURN_TYPE_BOXED else KtTypeMappingMode.RETURN_TYPE
|
||||
|
||||
ktType.asPsiType(
|
||||
this@SymbolLightAccessorMethod,
|
||||
allowErrorTypes = true,
|
||||
KtTypeMappingMode.RETURN_TYPE,
|
||||
typeMappingMode,
|
||||
containingClass.isAnnotationType,
|
||||
)
|
||||
} ?: nonExistentType()
|
||||
|
||||
+24
-1
@@ -11,6 +11,8 @@ import kotlinx.collections.immutable.mutate
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.hasAnnotation
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
@@ -177,6 +179,25 @@ internal class SymbolLightSimpleMethod(
|
||||
if (isTopLevel) false else withFunctionSymbol { it.isOverride }
|
||||
}
|
||||
|
||||
// Inspired by KotlinTypeMapper#forceBoxedReturnType
|
||||
private fun forceBoxedReturnType(): Boolean {
|
||||
return withFunctionSymbol { functionSymbol ->
|
||||
val returnType = functionSymbol.returnType
|
||||
// 'invoke' methods for lambdas, function literals, and callable references
|
||||
// implicitly override generic 'invoke' from a corresponding base class.
|
||||
if (functionSymbol.isBuiltinFunctionInvoke && returnType.isInlineClassType)
|
||||
return@withFunctionSymbol true
|
||||
|
||||
returnType.isPrimitive &&
|
||||
functionSymbol.getAllOverriddenSymbols().any { overriddenSymbol ->
|
||||
!overriddenSymbol.returnType.isPrimitive
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val KtType.isInlineClassType: Boolean
|
||||
get() = ((this as? KtNonErrorClassType)?.classSymbol as? KtNamedClassOrObjectSymbol)?.isInline == true
|
||||
|
||||
private val KtType.isVoidType: Boolean get() = isUnit && nullabilityType != NullabilityType.Nullable
|
||||
|
||||
private val _returnedType: PsiType by lazyPub {
|
||||
@@ -187,10 +208,12 @@ internal class SymbolLightSimpleMethod(
|
||||
functionSymbol.returnType.takeUnless { it.isVoidType } ?: return@withFunctionSymbol PsiType.VOID
|
||||
}
|
||||
|
||||
val typeMappingMode = if (forceBoxedReturnType()) KtTypeMappingMode.RETURN_TYPE_BOXED else KtTypeMappingMode.RETURN_TYPE
|
||||
|
||||
ktType.asPsiTypeElement(
|
||||
this@SymbolLightSimpleMethod,
|
||||
allowErrorTypes = true,
|
||||
KtTypeMappingMode.RETURN_TYPE,
|
||||
typeMappingMode,
|
||||
this@SymbolLightSimpleMethod.containingClass.isAnnotationType,
|
||||
)?.let {
|
||||
annotateByKtType(it.type, ktType, it, modifierList)
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@ public final class C /* C*/ implements Tr {
|
||||
private final int v;
|
||||
|
||||
@java.lang.Override()
|
||||
public int foo();// foo()
|
||||
public java.lang.Integer foo();// foo()
|
||||
|
||||
@java.lang.Override()
|
||||
public int getV();// getV()
|
||||
public java.lang.Integer getV();// getV()
|
||||
|
||||
public C();// .ctor()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user