KAPT: Fix error types for receivers and property setters in stubs
When using correct error types and there is a property setter or receiver for an unknown type then the parameter type would be `Object` instead of the error type. This fixes KT-46965 and KT-46966
This commit is contained in:
committed by
Alexander Udalov
parent
dd051c1556
commit
3c69a0493e
+93
-29
@@ -1017,39 +1017,103 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
||||
val genericSignature = signatureParser.parseMethodSignature(
|
||||
method.signature, parameters, exceptionTypes, jcReturnType,
|
||||
nonErrorParameterTypeProvider = { index, lazyType ->
|
||||
if (descriptor is PropertySetterDescriptor && valueParametersFromDescriptor.size == 1 && index == 0) {
|
||||
getNonErrorType(descriptor.correspondingProperty.returnType, METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
val setterOrigin = (psiElement as? KtCallableDeclaration)
|
||||
?.takeIf { it !is KtFunction }
|
||||
|
||||
setterOrigin?.typeReference
|
||||
},
|
||||
ifNonError = { lazyType() })
|
||||
} else if (descriptor is FunctionDescriptor && valueParametersFromDescriptor.size == parameters.size) {
|
||||
val parameterDescriptor = valueParametersFromDescriptor[index]
|
||||
val sourceElement = when {
|
||||
psiElement is KtFunction -> psiElement
|
||||
descriptor is ConstructorDescriptor && descriptor.isPrimary -> (psiElement as? KtClassOrObject)?.primaryConstructor
|
||||
else -> null
|
||||
when (descriptor) {
|
||||
is PropertyGetterDescriptor -> {
|
||||
if (valueParametersFromDescriptor.isEmpty() && index == 0) {
|
||||
getNonErrorType(
|
||||
type = descriptor.correspondingProperty.returnType,
|
||||
kind = METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
when (psiElement) {
|
||||
is KtCallableDeclaration -> psiElement.takeIf { it !is KtFunction }?.receiverTypeReference
|
||||
is KtPropertyAccessor -> psiElement.property.receiverTypeReference
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
ifNonError = lazyType
|
||||
)
|
||||
} else {
|
||||
lazyType()
|
||||
}
|
||||
}
|
||||
|
||||
getNonErrorType(
|
||||
parameterDescriptor.type, METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
if (sourceElement == null) return@getNonErrorType null
|
||||
is PropertySetterDescriptor -> when {
|
||||
valueParametersFromDescriptor.size != 1 -> lazyType()
|
||||
|
||||
if (sourceElement.hasDeclaredReturnType() && isContinuationParameter(parameterDescriptor)) {
|
||||
val continuationTypeFqName = StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
val functionReturnType = sourceElement.typeReference!!.text
|
||||
KtPsiFactory(kaptContext.project).createType("$continuationTypeFqName<$functionReturnType>")
|
||||
} else {
|
||||
sourceElement.valueParameters.getOrNull(index)?.typeReference
|
||||
index == 0 && descriptor.extensionReceiverParameter != null -> {
|
||||
getNonErrorType(
|
||||
type = descriptor.extensionReceiverParameter?.type,
|
||||
kind = METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
when (psiElement) {
|
||||
is KtCallableDeclaration -> psiElement.takeIf { it !is KtFunction }?.receiverTypeReference
|
||||
is KtPropertyAccessor -> psiElement.property.receiverTypeReference
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
ifNonError = lazyType
|
||||
)
|
||||
}
|
||||
|
||||
index == (if (descriptor.extensionReceiverParameter == null) 0 else 1) -> {
|
||||
getNonErrorType(
|
||||
type = valueParametersFromDescriptor[0].type,
|
||||
kind = METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
when (psiElement) {
|
||||
is KtCallableDeclaration -> psiElement.takeIf { it !is KtFunction }?.typeReference
|
||||
is KtPropertyAccessor -> psiElement.property.typeReference
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
ifNonError = lazyType
|
||||
)
|
||||
}
|
||||
|
||||
else -> lazyType()
|
||||
}
|
||||
|
||||
is FunctionDescriptor -> {
|
||||
val extensionReceiverParameter = descriptor.extensionReceiverParameter
|
||||
val offset = if (extensionReceiverParameter == null) 0 else 1
|
||||
if (extensionReceiverParameter != null && index == 0) {
|
||||
getNonErrorType(
|
||||
extensionReceiverParameter.type,
|
||||
METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
(psiElement as? KtCallableDeclaration)?.receiverTypeReference
|
||||
},
|
||||
ifNonError = lazyType
|
||||
)
|
||||
} else if (valueParametersFromDescriptor.size + offset == parameters.size) {
|
||||
val parameterDescriptor = valueParametersFromDescriptor[index - offset]
|
||||
val sourceElement = when {
|
||||
psiElement is KtFunction -> psiElement
|
||||
descriptor is ConstructorDescriptor && descriptor.isPrimary -> (psiElement as? KtClassOrObject)?.primaryConstructor
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
ifNonError = { lazyType() })
|
||||
} else {
|
||||
lazyType()
|
||||
getNonErrorType(
|
||||
parameterDescriptor.type,
|
||||
METHOD_PARAMETER_TYPE,
|
||||
ktTypeProvider = {
|
||||
if (sourceElement == null) return@getNonErrorType null
|
||||
|
||||
if (sourceElement.hasDeclaredReturnType() && isContinuationParameter(parameterDescriptor)) {
|
||||
val continuationTypeFqName = StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
val functionReturnType = sourceElement.typeReference!!.text
|
||||
KtPsiFactory(kaptContext.project).createType("$continuationTypeFqName<$functionReturnType>")
|
||||
} else {
|
||||
sourceElement.valueParameters.getOrNull(index)?.typeReference
|
||||
}
|
||||
},
|
||||
ifNonError = lazyType
|
||||
)
|
||||
} else {
|
||||
lazyType()
|
||||
}
|
||||
}
|
||||
|
||||
else -> lazyType()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// CORRECT_ERROR_TYPES
|
||||
|
||||
@Suppress("UNRESOLVED_REFERENCE")
|
||||
class TypeHook {
|
||||
var customProperty: UnknownType
|
||||
get() = UnknownType()
|
||||
set(value) {}
|
||||
|
||||
var UnknownType.receiverProperty: UnknownType
|
||||
get() = UnknownType()
|
||||
set(value) {}
|
||||
|
||||
fun UnknownType.receiverFunction(): UnknownType = UnknownType()
|
||||
|
||||
companion object {
|
||||
var UnknownType.extensionProperty: UnknownType
|
||||
get() = UnknownType()
|
||||
set(value) {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import java.lang.System;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
|
||||
public final class TypeHook {
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public static final TypeHook.Companion Companion = null;
|
||||
|
||||
public TypeHook() {
|
||||
super();
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public final UnknownType getCustomProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void setCustomProperty(@org.jetbrains.annotations.NotNull()
|
||||
UnknownType value) {
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public final UnknownType getReceiverProperty(@org.jetbrains.annotations.NotNull()
|
||||
UnknownType $this$receiverProperty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void setReceiverProperty(@org.jetbrains.annotations.NotNull()
|
||||
UnknownType $this$receiverProperty, @org.jetbrains.annotations.NotNull()
|
||||
UnknownType value) {
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public final UnknownType receiverFunction(@org.jetbrains.annotations.NotNull()
|
||||
UnknownType $this$receiverFunction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kotlin.Metadata()
|
||||
public static final class Companion {
|
||||
|
||||
private Companion() {
|
||||
super();
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public final UnknownType getExtensionProperty(@org.jetbrains.annotations.NotNull()
|
||||
UnknownType $this$extensionProperty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void setExtensionProperty(@org.jetbrains.annotations.NotNull()
|
||||
UnknownType $this$extensionProperty, @org.jetbrains.annotations.NotNull()
|
||||
UnknownType value) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -181,6 +181,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/enums.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorExtensionReceiver.kt")
|
||||
public void testErrorExtensionReceiver() throws Exception {
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/errorExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorLocationMapping.kt")
|
||||
public void testErrorLocationMapping() throws Exception {
|
||||
|
||||
+6
@@ -181,6 +181,12 @@ public class IrClassFileToSourceStubConverterTestGenerated extends AbstractIrCla
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/enums.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorExtensionReceiver.kt")
|
||||
public void testErrorExtensionReceiver() throws Exception {
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/errorExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorLocationMapping.kt")
|
||||
public void testErrorLocationMapping() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user