Refactor KotlinType::asPsiType for ultra-light classes
- Extract HOF that UltraLightSupport::mapType that allows to call arbitrary functions of type mapper - Use it for computing return type of functions - "declaration: KtDeclaration" parameter became unused since it was only used for return types
This commit is contained in:
@@ -388,7 +388,7 @@ public class KotlinTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable JvmSignatureWriter sw) {
|
public Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable JvmSignatureWriter sw) {
|
||||||
KotlinType returnType = descriptor.getReturnType();
|
KotlinType returnType = descriptor.getReturnType();
|
||||||
assert returnType != null : "Function has no return type: " + descriptor;
|
assert returnType != null : "Function has no return type: " + descriptor;
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
|||||||
getDescriptor()?.typeConstructor?.supertypes.orEmpty().asSequence()
|
getDescriptor()?.typeConstructor?.supertypes.orEmpty().asSequence()
|
||||||
|
|
||||||
private fun mapSupertype(supertype: KotlinType) =
|
private fun mapSupertype(supertype: KotlinType) =
|
||||||
supertype.asPsiType(classOrObject, support, TypeMappingMode.SUPER_TYPE, this) as? PsiClassType
|
supertype.asPsiType(support, TypeMappingMode.SUPER_TYPE, this) as? PsiClassType
|
||||||
|
|
||||||
override fun createExtendsList(): PsiReferenceList? =
|
override fun createExtendsList(): PsiReferenceList? =
|
||||||
if (tooComplex) super.createExtendsList()
|
if (tooComplex) super.createExtendsList()
|
||||||
@@ -336,16 +336,19 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun methodReturnType(f: KtDeclaration, wrapper: KtUltraLightMethod): PsiType {
|
private fun methodReturnType(ktDeclaration: KtDeclaration, wrapper: KtUltraLightMethod): PsiType {
|
||||||
val desc = f.resolve()?.let { if (it is PropertyDescriptor) it.getter else it }
|
val desc =
|
||||||
val kotlinType = (desc as? FunctionDescriptor)?.returnType ?: return PsiType.NULL
|
ktDeclaration.resolve()?.getterIfProperty() as? FunctionDescriptor
|
||||||
val mode = when {
|
?: return PsiType.NULL
|
||||||
typeMapper(support).forceBoxedReturnType(desc) -> TypeMappingMode.RETURN_TYPE_BOXED
|
|
||||||
else -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
return support.mapType(wrapper) { typeMapper, signatureWriter ->
|
||||||
|
typeMapper.mapReturnType(desc, signatureWriter)
|
||||||
}
|
}
|
||||||
return kotlinType.asPsiType(f, support, mode, wrapper)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun DeclarationDescriptor.getterIfProperty() =
|
||||||
|
if (this@getterIfProperty is PropertyDescriptor) this@getterIfProperty.getter else this@getterIfProperty
|
||||||
|
|
||||||
private fun lightMethod(name: String, declaration: KtDeclaration, forceStatic: Boolean): LightMethodBuilder {
|
private fun lightMethod(name: String, declaration: KtDeclaration, forceStatic: Boolean): LightMethodBuilder {
|
||||||
val accessedProperty = if (declaration is KtPropertyAccessor) declaration.property else null
|
val accessedProperty = if (declaration is KtPropertyAccessor) declaration.property else null
|
||||||
val outer = accessedProperty ?: declaration
|
val outer = accessedProperty ?: declaration
|
||||||
@@ -535,7 +538,7 @@ private class KtUltraLightField(
|
|||||||
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
|
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
|
||||||
PropertyCodegen.getDelegateTypeForProperty(declaration, it, context)
|
PropertyCodegen.getDelegateTypeForProperty(declaration, it, context)
|
||||||
}
|
}
|
||||||
?.let { it.asPsiType(declaration, support, TypeMappingMode.getOptimalModeForValueParameter(it), this) }
|
?.let { it.asPsiType(support, TypeMappingMode.getOptimalModeForValueParameter(it), this) }
|
||||||
?.let(TypeConversionUtil::erasure)
|
?.let(TypeConversionUtil::erasure)
|
||||||
?: nonExistent()
|
?: nonExistent()
|
||||||
declaration is KtObjectDeclaration ->
|
declaration is KtObjectDeclaration ->
|
||||||
@@ -547,7 +550,7 @@ private class KtUltraLightField(
|
|||||||
(declaration.resolve() as? PropertyDescriptor)?.isVar == true -> TypeMappingMode.getOptimalModeForValueParameter(it)
|
(declaration.resolve() as? PropertyDescriptor)?.isVar == true -> TypeMappingMode.getOptimalModeForValueParameter(it)
|
||||||
else -> TypeMappingMode.getOptimalModeForReturnType(it, false)
|
else -> TypeMappingMode.getOptimalModeForReturnType(it, false)
|
||||||
}
|
}
|
||||||
it.asPsiType(declaration, support, mode, this)
|
it.asPsiType(support, mode, this)
|
||||||
} ?: PsiType.NULL
|
} ?: PsiType.NULL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -654,7 +657,7 @@ internal class KtUltraLightParameter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val _type: PsiType by lazyPub {
|
private val _type: PsiType by lazyPub {
|
||||||
kotlinType?.let { it.asPsiType(kotlinOrigin, support, TypeMappingMode.getOptimalModeForValueParameter(it), this) } ?: PsiType.NULL
|
kotlinType?.let { it.asPsiType(support, TypeMappingMode.getOptimalModeForValueParameter(it), this) } ?: PsiType.NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getType(): PsiType = _type
|
override fun getType(): PsiType = _type
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
|||||||
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
|
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||||
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.JvmTarget
|
||||||
@@ -24,10 +25,8 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
|
||||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.text.StringCharacterIterator
|
import java.text.StringCharacterIterator
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ internal fun buildTypeParameterList(
|
|||||||
KotlinLightReferenceListBuilder(manager, PsiReferenceList.Role.EXTENDS_BOUNDS_LIST)
|
KotlinLightReferenceListBuilder(manager, PsiReferenceList.Role.EXTENDS_BOUNDS_LIST)
|
||||||
if (ktParam.extendsBound != null || declaration.typeConstraints.isNotEmpty()) {
|
if (ktParam.extendsBound != null || declaration.typeConstraints.isNotEmpty()) {
|
||||||
val boundTypes = (ktParam.resolve() as? TypeParameterDescriptor)?.upperBounds.orEmpty()
|
val boundTypes = (ktParam.resolve() as? TypeParameterDescriptor)?.upperBounds.orEmpty()
|
||||||
.mapNotNull { it.asPsiType(ktParam, support, TypeMappingMode.DEFAULT, this) as? PsiClassType }
|
.mapNotNull { it.asPsiType(support, TypeMappingMode.DEFAULT, this) as? PsiClassType }
|
||||||
val hasDefaultBound = boundTypes.size == 1 && boundTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
|
val hasDefaultBound = boundTypes.size == 1 && boundTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
|
||||||
if (!hasDefaultBound) {
|
if (!hasDefaultBound) {
|
||||||
boundTypes.forEach(boundList::addReference)
|
boundTypes.forEach(boundList::addReference)
|
||||||
@@ -75,16 +74,19 @@ internal fun KtDeclaration.resolve() = LightClassGenerationSupport.getInstance(p
|
|||||||
|
|
||||||
// copy-pasted from kotlinInternalUastUtils.kt and post-processed
|
// copy-pasted from kotlinInternalUastUtils.kt and post-processed
|
||||||
internal fun KotlinType.asPsiType(
|
internal fun KotlinType.asPsiType(
|
||||||
declaration: KtDeclaration,
|
|
||||||
support: UltraLightSupport,
|
support: UltraLightSupport,
|
||||||
mode: TypeMappingMode,
|
mode: TypeMappingMode,
|
||||||
psiContext: PsiElement
|
psiContext: PsiElement
|
||||||
): PsiType {
|
): PsiType = support.mapType(psiContext) { typeMapper, signatureWriter ->
|
||||||
val typeFqName = constructor.declarationDescriptor?.fqNameSafe?.asString()
|
typeMapper.mapType(this, signatureWriter, mode)
|
||||||
if (typeFqName == "kotlin.Unit" && declaration is KtFunction) return PsiType.VOID
|
}
|
||||||
|
|
||||||
|
internal fun UltraLightSupport.mapType(
|
||||||
|
psiContext: PsiElement,
|
||||||
|
mapTypeToSignatureWriter: (KotlinTypeMapper, JvmSignatureWriter) -> Unit
|
||||||
|
): PsiType {
|
||||||
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
|
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
|
||||||
typeMapper(support).mapType(this, signatureWriter, mode)
|
mapTypeToSignatureWriter(typeMapper(this), signatureWriter)
|
||||||
val signature = StringCharacterIterator(signatureWriter.toString())
|
val signature = StringCharacterIterator(signatureWriter.toString())
|
||||||
|
|
||||||
val javaType = SignatureParsing.parseTypeString(signature, StubBuildingVisitor.GUESSING_MAPPER)
|
val javaType = SignatureParsing.parseTypeString(signature, StubBuildingVisitor.GUESSING_MAPPER)
|
||||||
|
|||||||
Reference in New Issue
Block a user