Use AnnotationSplitter for annotations on extension receiver
Instead of using `@receiver:`-targeted annotations on the receiver type, use normal annotations of the ReceiverParameterDescriptor instance everywhere
This commit is contained in:
@@ -15,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.Bridge;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
@@ -73,7 +72,8 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_GETTER;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_SETTER;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
@@ -532,22 +532,16 @@ public class FunctionCodegen {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper).genAnnotations(
|
||||
iterator.next(),
|
||||
parameterSignature.getAsmType()
|
||||
);
|
||||
}
|
||||
else if (kind == JvmMethodParameterKind.RECEIVER) {
|
||||
ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter();
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
|
||||
Annotated annotated =
|
||||
kind == JvmMethodParameterKind.VALUE
|
||||
? iterator.next()
|
||||
: kind == JvmMethodParameterKind.RECEIVER
|
||||
? JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter()
|
||||
: null;
|
||||
|
||||
if (receiver != null) {
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
|
||||
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType());
|
||||
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER);
|
||||
|
||||
annotationCodegen.genAnnotations(receiver, parameterSignature.getAsmType());
|
||||
}
|
||||
if (annotated != null) {
|
||||
annotationCodegen.genAnnotations(annotated, parameterSignature.getAsmType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-17
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.codegen.annotation
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
|
||||
interface WrappedAnnotated : Annotated {
|
||||
@@ -25,19 +24,3 @@ interface WrappedAnnotated : Annotated {
|
||||
}
|
||||
|
||||
class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, override val annotations: Annotations) : WrappedAnnotated
|
||||
|
||||
class AnnotatedWithOnlyTargetedAnnotations(original: Annotated) : Annotated {
|
||||
override val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
|
||||
|
||||
private class UseSiteTargetedAnnotations(private val additionalAnnotations: Annotations) : Annotations {
|
||||
override fun isEmpty() = true
|
||||
|
||||
override fun getUseSiteTargetedAnnotations() = getAdditionalTargetedAnnotations()
|
||||
|
||||
override fun getAllAnnotations() = getAdditionalTargetedAnnotations()
|
||||
|
||||
override fun iterator() = emptyList<AnnotationDescriptor>().iterator()
|
||||
|
||||
private fun getAdditionalTargetedAnnotations() = additionalAnnotations.getUseSiteTargetedAnnotations()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -939,8 +939,9 @@ public class DescriptorResolver {
|
||||
|
||||
ReceiverParameterDescriptor receiverDescriptor;
|
||||
if (receiverType != null) {
|
||||
AnnotationSplitter splitter = AnnotationSplitter.create(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
|
||||
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||
propertyDescriptor, receiverType, Annotations.Companion.getEMPTY()
|
||||
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.contracts.description.ContractProviderKey
|
||||
import org.jetbrains.kotlin.contracts.description.LazyContractProvider
|
||||
import org.jetbrains.kotlin.contracts.parsing.ContractParsingServices
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
@@ -55,6 +57,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -75,7 +78,8 @@ class FunctionDescriptorResolver(
|
||||
private val overloadChecker: OverloadChecker,
|
||||
private val contractParsingServices: ContractParsingServices,
|
||||
private val expressionTypingServices: ExpressionTypingServices,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val storageManager: StorageManager
|
||||
) {
|
||||
fun resolveFunctionDescriptor(
|
||||
containingDescriptor: DeclarationDescriptor,
|
||||
@@ -209,10 +213,15 @@ class FunctionDescriptorResolver(
|
||||
}
|
||||
}
|
||||
|
||||
val extensionReceiver = receiverType?.let {
|
||||
val splitter = AnnotationSplitter.create(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
|
||||
DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
|
||||
)
|
||||
}
|
||||
|
||||
functionDescriptor.initialize(
|
||||
receiverType?.let {
|
||||
DescriptorFactory.createExtensionReceiverParameterForCallable(functionDescriptor, it, Annotations.EMPTY)
|
||||
},
|
||||
extensionReceiver,
|
||||
getDispatchReceiverParameterIfNeeded(container),
|
||||
typeParameterDescriptors,
|
||||
valueParameterDescriptors,
|
||||
|
||||
+1
-3
@@ -39,9 +39,7 @@ object LateinitIntrinsicApplicabilityChecker : CallChecker {
|
||||
// An optimization
|
||||
if (descriptor.name.asString() != "isInitialized") return
|
||||
|
||||
// TODO: store "@receiver:..." annotations in ReceiverParameterDescriptor
|
||||
val annotations = descriptor.extensionReceiverParameter?.value?.type?.annotations?.getUseSiteTargetedAnnotations() ?: return
|
||||
if (annotations.none { it.annotation.fqName == ACCESSIBLE_LATEINIT_PROPERTY_LITERAL }) return
|
||||
if (descriptor.extensionReceiverParameter?.annotations?.hasAnnotation(ACCESSIBLE_LATEINIT_PROPERTY_LITERAL) != true) return
|
||||
|
||||
val expression = (resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression?.let(KtPsiUtil::safeDeparenthesize)
|
||||
if (expression !is KtCallableReferenceExpression) {
|
||||
|
||||
+3
-16
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
@@ -31,24 +30,12 @@ class AnnotationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitValueParameter(declaration: IrValueParameter) {
|
||||
super.visitValueParameter(declaration)
|
||||
|
||||
declaration.descriptor.type.annotations.getAllAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.RECEIVER }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
private fun generateAnnotationsForDeclaration(declaration: IrDeclaration) {
|
||||
declaration.descriptor.annotations.getAllAnnotations()
|
||||
.filter { isAnnotationTargetMatchingDeclaration(it.target, declaration) }
|
||||
.generateAnnotationConstructorCalls(declaration)
|
||||
}
|
||||
|
||||
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
|
||||
mapTo(declaration.annotations) {
|
||||
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
.mapTo(declaration.annotations) {
|
||||
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean =
|
||||
|
||||
+8
-8
@@ -21,19 +21,19 @@ FILE fqName:<root> fileName:/receiverParameterWithAnnotations.kt
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='A'
|
||||
FUN name:f visibility:public modality:FINAL <> ($this:A, $receiver:@receiver:Ann kotlin.String) returnType:kotlin.String flags:
|
||||
FUN name:f visibility:public modality:FINAL <> ($this:A, $receiver:kotlin.String) returnType:kotlin.String flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:A flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String flags:
|
||||
annotations:
|
||||
CALL 'constructor Ann()' type=Ann origin=null
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='f() on String: String'
|
||||
CONST String type=kotlin.String value=
|
||||
PROPERTY name:p visibility:public modality:FINAL flags:val
|
||||
FUN name:<get-p> visibility:public modality:FINAL <> ($this:A, $receiver:@receiver:Ann kotlin.String?) returnType:kotlin.String flags:
|
||||
FUN name:<get-p> visibility:public modality:FINAL <> ($this:A, $receiver:kotlin.String?) returnType:kotlin.String flags:
|
||||
correspondingProperty: PROPERTY name:p visibility:public modality:FINAL flags:val
|
||||
$this: VALUE_PARAMETER name:<this> type:A flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String? flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String? flags:
|
||||
annotations:
|
||||
CALL 'constructor Ann()' type=Ann origin=null
|
||||
BLOCK_BODY
|
||||
@@ -52,17 +52,17 @@ FILE fqName:<root> fileName:/receiverParameterWithAnnotations.kt
|
||||
overridden:
|
||||
FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||
FUN name:topLevelF visibility:public modality:FINAL <> ($receiver:@receiver:Ann kotlin.String?) returnType:kotlin.String flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String? flags:
|
||||
FUN name:topLevelF visibility:public modality:FINAL <> ($receiver:kotlin.String?) returnType:kotlin.String flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String? flags:
|
||||
annotations:
|
||||
CALL 'constructor Ann()' type=Ann origin=null
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='topLevelF() on String?: String'
|
||||
CONST String type=kotlin.String value=
|
||||
PROPERTY name:topLevelP visibility:public modality:FINAL flags:val
|
||||
FUN name:<get-topLevelP> visibility:public modality:FINAL <> ($receiver:@receiver:Ann kotlin.String) returnType:kotlin.String flags:
|
||||
FUN name:<get-topLevelP> visibility:public modality:FINAL <> ($receiver:kotlin.String) returnType:kotlin.String flags:
|
||||
correspondingProperty: PROPERTY name:topLevelP visibility:public modality:FINAL flags:val
|
||||
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String flags:
|
||||
annotations:
|
||||
CALL 'constructor Ann()' type=Ann origin=null
|
||||
BLOCK_BODY
|
||||
|
||||
Reference in New Issue
Block a user