provide correct context for method return type
to fix generics in
class A<E> {
fun foo(): E = null!!
}
public class B {
public static void main(String[] args) {
A<String> a = new A<>();
a.foo().length(); // Unresolved length, because it thinks that `a.foo()` returns E
}
}
This commit is contained in:
@@ -63,7 +63,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
|||||||
|
|
||||||
private fun allSuperTypes() =
|
private fun allSuperTypes() =
|
||||||
getDescriptor()?.typeConstructor?.supertypes?.mapNotNull {
|
getDescriptor()?.typeConstructor?.supertypes?.mapNotNull {
|
||||||
it.asPsiType(classOrObject, support, TypeMappingMode.SUPER_TYPE) as? PsiClassType
|
it.asPsiType(classOrObject, support, TypeMappingMode.SUPER_TYPE, this) as? PsiClassType
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
override fun createExtendsList(): PsiReferenceList? =
|
override fun createExtendsList(): PsiReferenceList? =
|
||||||
@@ -290,7 +290,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
|||||||
}
|
}
|
||||||
val returnType: PsiType? by lazyPub {
|
val returnType: PsiType? by lazyPub {
|
||||||
if (isConstructor) null
|
if (isConstructor) null
|
||||||
else methodReturnType(f)
|
else methodReturnType(f, wrapper)
|
||||||
}
|
}
|
||||||
method.setMethodReturnType { returnType }
|
method.setMethodReturnType { returnType }
|
||||||
return wrapper
|
return wrapper
|
||||||
@@ -303,14 +303,14 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun methodReturnType(f: KtDeclaration): PsiType {
|
private fun methodReturnType(f: KtDeclaration, wrapper: KtUltraLightMethod): PsiType {
|
||||||
val desc = f.resolve()?.let { if (it is PropertyDescriptor) it.getter else it }
|
val desc = f.resolve()?.let { if (it is PropertyDescriptor) it.getter else it }
|
||||||
val kotlinType = (desc as? FunctionDescriptor)?.returnType ?: return PsiType.NULL
|
val kotlinType = (desc as? FunctionDescriptor)?.returnType ?: return PsiType.NULL
|
||||||
val mode = when {
|
val mode = when {
|
||||||
typeMapper(support).forceBoxedReturnType(desc) -> TypeMappingMode.RETURN_TYPE_BOXED
|
typeMapper(support).forceBoxedReturnType(desc) -> TypeMappingMode.RETURN_TYPE_BOXED
|
||||||
else -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
else -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
||||||
}
|
}
|
||||||
return kotlinType.asPsiType(f, support, mode)
|
return kotlinType.asPsiType(f, support, mode, wrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lightMethod(name: String, declaration: KtDeclaration, forceStatic: Boolean): LightMethodBuilder {
|
private fun lightMethod(name: String, declaration: KtDeclaration, forceStatic: Boolean): LightMethodBuilder {
|
||||||
@@ -413,10 +413,10 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
|||||||
|
|
||||||
if (needsAccessor(ktGetter)) {
|
if (needsAccessor(ktGetter)) {
|
||||||
val getterName = mangleIfNeeded(listOfNotNull(ktGetter, declaration), JvmAbi.getterName(propertyName))
|
val getterName = mangleIfNeeded(listOfNotNull(ktGetter, declaration), JvmAbi.getterName(propertyName))
|
||||||
val getterType: PsiType by lazyPub { methodReturnType(declaration) }
|
|
||||||
val getterPrototype = lightMethod(getterName, ktGetter ?: declaration, onlyJvmStatic)
|
val getterPrototype = lightMethod(getterName, ktGetter ?: declaration, onlyJvmStatic)
|
||||||
.setMethodReturnType { getterType }
|
|
||||||
val getterWrapper = KtUltraLightMethod(getterPrototype, declaration, support, this)
|
val getterWrapper = KtUltraLightMethod(getterPrototype, declaration, support, this)
|
||||||
|
val getterType: PsiType by lazyPub { methodReturnType(declaration, getterWrapper) }
|
||||||
|
getterPrototype.setMethodReturnType { getterType }
|
||||||
addReceiverParameter(declaration, getterWrapper)
|
addReceiverParameter(declaration, getterWrapper)
|
||||||
result.add(getterWrapper)
|
result.add(getterWrapper)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ internal fun KotlinType.asPsiType(
|
|||||||
declaration: KtDeclaration,
|
declaration: KtDeclaration,
|
||||||
support: UltraLightSupport,
|
support: UltraLightSupport,
|
||||||
mode: TypeMappingMode,
|
mode: TypeMappingMode,
|
||||||
psiContext: PsiElement = declaration
|
psiContext: PsiElement
|
||||||
): PsiType {
|
): PsiType {
|
||||||
val typeFqName = constructor.declarationDescriptor?.fqNameSafe?.asString()
|
val typeFqName = constructor.declarationDescriptor?.fqNameSafe?.asString()
|
||||||
if (typeFqName == "kotlin.Unit" && declaration is KtFunction) return PsiType.VOID
|
if (typeFqName == "kotlin.Unit" && declaration is KtFunction) return PsiType.VOID
|
||||||
|
|||||||
Reference in New Issue
Block a user