Take ReceiverParameterDescriptor in FunctionDescriptorImpl.initialize

Instead of just KotlinType. This will allow to pass annotations on the
receiver at call sites
This commit is contained in:
Alexander Udalov
2018-08-08 16:35:21 +02:00
parent 6fb39785ff
commit 34c033bcaf
39 changed files with 200 additions and 107 deletions
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -56,7 +55,7 @@ class AccessorForConstructorDescriptor(
init {
initialize(
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
calleeDescriptor.extensionReceiverParameter?.copy(this),
calleeDescriptor.dispatchReceiverParameter,
copyTypeParameters(calleeDescriptor),
copyValueParameters(calleeDescriptor),
@@ -16,14 +16,12 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.coroutines.*
import org.jetbrains.kotlin.codegen.coroutines.INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import java.util.LinkedHashMap
import java.util.*
class AccessorForFunctionDescriptor(
override val calleeDescriptor: FunctionDescriptor,
@@ -36,7 +34,7 @@ class AccessorForFunctionDescriptor(
init {
initialize(
DescriptorUtils.getReceiverParameterType(calleeDescriptor.extensionReceiverParameter),
calleeDescriptor.extensionReceiverParameter?.copy(this),
if (calleeDescriptor is ConstructorDescriptor || calleeDescriptor.isJvmStaticInObjectOrClassOrInterface())
null
else
@@ -185,7 +185,7 @@ class CoroutineCodegenForLambda private constructor(
funDescriptor.source
).also {
it.initialize(
funDescriptor.extensionReceiverParameter?.type,
funDescriptor.extensionReceiverParameter?.copy(it),
funDescriptor.dispatchReceiverParameter,
funDescriptor.typeParameters,
funDescriptor.valueParameters,
@@ -22,7 +22,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
@@ -90,7 +91,7 @@ public class SignaturesPropagationData {
SourceElement.NO_SOURCE
);
autoMethodDescriptor.initialize(
/* receiverParameterType = */ null,
null,
containingClass.getThisAsReceiverParameter(),
autoTypeParameters,
autoValueParameters,
@@ -930,8 +930,15 @@ public class DescriptorResolver {
}
}
ReceiverParameterDescriptor receiverDescriptor =
DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
ReceiverParameterDescriptor receiverDescriptor;
if (receiverType != null) {
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
propertyDescriptor, receiverType, Annotations.Companion.getEMPTY()
);
}
else {
receiverDescriptor = null;
}
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
KotlinType propertyType = propertyInfo.getVariableType();
@@ -210,7 +210,9 @@ class FunctionDescriptorResolver(
}
functionDescriptor.initialize(
receiverType,
receiverType?.let {
DescriptorFactory.createExtensionReceiverParameterForCallable(functionDescriptor, it, Annotations.EMPTY)
},
getDispatchReceiverParameterIfNeeded(container),
typeParameterDescriptors,
valueParameterDescriptors,
@@ -138,7 +138,7 @@ class DynamicCallableDescriptors(storageManager: StorageManager, builtIns: Kotli
}
private fun createDynamicDispatchReceiverParameter(owner: CallableDescriptor): ReceiverParameterDescriptorImpl {
return ReceiverParameterDescriptorImpl(owner, TransientReceiver(dynamicType))
return ReceiverParameterDescriptorImpl(owner, TransientReceiver(dynamicType), Annotations.EMPTY)
}
private fun createTypeParameters(owner: DeclarationDescriptor, call: Call): List<TypeParameterDescriptor> =
@@ -159,19 +159,19 @@ class ResolvedAtomCompleter(
trace.recordType(ktArgumentExpression, substitutedFunctionalType)
// Mainly this is needed for builder-like inference, when we have type `SomeType<K, V>.() -> Unit` and now we want to update those K, V
val extensionReceiverParameter = functionDescriptor.extensionReceiverParameter
if (extensionReceiverParameter != null) {
require(extensionReceiverParameter is ReceiverParameterDescriptorImpl) {
"Extension receiver for anonymous function ($extensionReceiverParameter) should be ReceiverParameterDescriptorImpl"
val receiver = functionDescriptor.extensionReceiverParameter
if (receiver != null) {
require(receiver is ReceiverParameterDescriptorImpl) {
"Extension receiver for anonymous function ($receiver) should be ReceiverParameterDescriptorImpl"
}
val valueType = extensionReceiverParameter.value.type.unwrap()
val valueType = receiver.value.type.unwrap()
val newValueType = resultSubstitutor.substituteKeepAnnotations(valueType)
val newReceiverValue = extensionReceiverParameter.value.replaceType(newValueType)
val newReceiverValue = receiver.value.replaceType(newValueType)
functionDescriptor.setExtensionReceiverParameter(
ReceiverParameterDescriptorImpl(extensionReceiverParameter.containingDeclaration, newReceiverValue)
ReceiverParameterDescriptorImpl(receiver.containingDeclaration, newReceiverValue, receiver.annotations)
)
}
}
@@ -396,7 +396,7 @@ private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext):
} + syntheticParameters
descriptor.initialize(
/* receiverParameterType = */ extensionReceiverParameter?.type,
/* receiverParameterType = */ extensionReceiverParameter,
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
/* typeParameters = */ typeParameters.map {
TypeParameterDescriptorImpl.createForFurtherModification(
@@ -520,7 +520,7 @@ class LocalDeclarationsLowering(
val newValueParameters = createTransformedValueParameters(localFunctionContext, capturedValues)
newDescriptor.initialize(
oldDescriptor.extensionReceiverParameter?.type,
oldDescriptor.extensionReceiverParameter?.copy(newDescriptor),
newDispatchReceiverParameter,
newTypeParameters,
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
@@ -123,7 +123,7 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass {
)
bridgeDescriptorForIrFunction.initialize(
bridge.descriptor.extensionReceiverParameter?.returnType, containingClass.thisAsReceiverParameter,
bridge.descriptor.extensionReceiverParameter?.copy(bridge.descriptor), containingClass.thisAsReceiverParameter,
bridge.descriptor.typeParameters,
bridge.descriptor.valueParameters.map { it.copy(bridgeDescriptorForIrFunction, it.name, it.index) },
bridge.descriptor.returnType, bridge.descriptor.modality, function.visibility
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -315,11 +316,11 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
val newDispatchReceiverParameter = oldDispatchReceiverParameter?.let { descriptorSubstituteMap.getOrDefault(it, it) as ReceiverParameterDescriptor }
val newTypeParameters = oldDescriptor.typeParameters // TODO substitute types
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, this)
val newReceiverParameterType = substituteTypeAndTryGetCopied(oldDescriptor.extensionReceiverParameter?.type)
val newReceiverParameter = copyReceiverParameter(oldDescriptor.extensionReceiverParameter, this)
val newReturnType = substituteTypeAndTryGetCopied(oldDescriptor.returnType)
initialize(
/* receiverParameterType = */ newReceiverParameterType,
/* extensionReceiverParameter = */ newReceiverParameter,
/* dispatchReceiverParameter = */ newDispatchReceiverParameter,
/* typeParameters = */ newTypeParameters,
/* unsubstitutedValueParameters = */ newValueParameters,
@@ -338,11 +339,11 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
(descriptorSubstituteMap[oldDescriptor] as ClassConstructorDescriptorImpl).apply {
val newTypeParameters = oldDescriptor.typeParameters
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, this)
val receiverParameterType = substituteTypeAndTryGetCopied(oldDescriptor.dispatchReceiverParameter?.type)
val newReceiverParameter = copyReceiverParameter(oldDescriptor.dispatchReceiverParameter, this)
val returnType = substituteTypeAndTryGetCopied(oldDescriptor.returnType)
initialize(
/* receiverParameterType = */ receiverParameterType,
/* extensionReceiverParameter = */ newReceiverParameter,
/* dispatchReceiverParameter = */ null, // For constructor there is no explicit dispatch receiver.
/* typeParameters = */ newTypeParameters,
/* unsubstitutedValueParameters = */ newValueParameters,
@@ -431,6 +432,18 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
newDescriptor
}
private fun copyReceiverParameter(
oldReceiverParameter: ReceiverParameterDescriptor?, containingDeclaration: CallableDescriptor
): ReceiverParameterDescriptor? {
if (oldReceiverParameter == null) return null
val substituteTypeAndTryGetCopied = substituteTypeAndTryGetCopied(oldReceiverParameter.type) ?: return null
return ReceiverParameterDescriptorImpl(
containingDeclaration,
ExtensionReceiver(containingDeclaration, substituteTypeAndTryGetCopied, oldReceiverParameter.value),
oldReceiverParameter.annotations
)
}
private fun substituteTypeAndTryGetCopied(type: KotlinType?): KotlinType? {
val substitutedType = substituteType(type) ?: return null
val oldClassDescriptor = TypeUtils.getClassDescriptor(substitutedType) ?: return substitutedType
@@ -84,7 +84,7 @@ object JsSymbolBuilder {
fun IrSimpleFunctionSymbol.initialize(
receiverParameterType: IrType? = null,
extensionReceiverParameter: ReceiverParameterDescriptor? = null,
dispatchParameterDescriptor: ReceiverParameterDescriptor? = null,
typeParameters: List<TypeParameterDescriptor> = emptyList(),
valueParameters: List<ValueParameterDescriptor> = emptyList(),
@@ -93,7 +93,7 @@ fun IrSimpleFunctionSymbol.initialize(
visibility: Visibility = Visibilities.LOCAL
) = this.apply {
(descriptor as FunctionDescriptorImpl).initialize(
receiverParameterType?.toKotlinType(),
extensionReceiverParameter,
dispatchParameterDescriptor,
typeParameters,
valueParameters,
@@ -101,4 +101,4 @@ fun IrSimpleFunctionSymbol.initialize(
modality,
visibility
)
}
}
@@ -95,7 +95,7 @@ class JvmDescriptorsFactory(
// Call the long version of `initialize()`, because otherwise default implementation inserts
// an unwanted `dispatchReceiverParameter`
newDescriptor.initialize(
oldDescriptor.extensionReceiverParameter?.type,
oldDescriptor.extensionReceiverParameter?.copy(newDescriptor),
null,
oldDescriptor.typeParameters,
newValueParameters,
@@ -197,7 +197,8 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
)
bridgeDescriptorForIrFunction.initialize(
bridge.descriptor.extensionReceiverParameter?.returnType, containingClass.thisAsReceiverParameter, emptyList(),
bridge.descriptor.extensionReceiverParameter?.copy(bridgeDescriptorForIrFunction),
containingClass.thisAsReceiverParameter, emptyList(),
bridge.descriptor.valueParameters.map { it.copy(bridgeDescriptorForIrFunction, it.name, it.index) },
bridge.descriptor.returnType, Modality.OPEN, descriptor.visibility
)
@@ -329,7 +330,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
)
delegationDescriptor.initialize(
descriptor.extensionReceiverParameter?.returnType, containingClass.thisAsReceiverParameter, emptyList(),
descriptor.extensionReceiverParameter?.copy(delegationDescriptor), containingClass.thisAsReceiverParameter, emptyList(),
descriptor.valueParameters.map { it.copy(delegationDescriptor, it.name, it.index) },
descriptor.returnType, Modality.OPEN, descriptor.visibility
)
@@ -8,11 +8,17 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.addMember
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
@@ -148,7 +154,7 @@ class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : ClassLowe
// Call the long version of `initialize()`, because otherwise default implementation inserts
// an unwanted `dispatchReceiverParameter`.
result.initialize(
extensionReceiverParameter?.type,
extensionReceiverParameter?.copy(result),
dispatchReceiverParameter,
typeParameters,
generateNewValueParameters(this, numDefaultParametersToExpect),
@@ -18,8 +18,6 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
@@ -30,7 +28,11 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.org.objectweb.asm.Opcodes
/*
@@ -227,7 +229,7 @@ private fun makeJvmStaticFunctionSymbol(
)
proxyDescriptorForIrFunction.initialize(
oldFunctionSymbol.descriptor.extensionReceiverParameter?.type,
oldFunctionSymbol.descriptor.extensionReceiverParameter?.copy(proxyDescriptorForIrFunction),
null,
oldFunctionSymbol.descriptor.typeParameters,
oldFunctionSymbol.descriptor.valueParameters.map { it.copy(proxyDescriptorForIrFunction, it.name, it.index) },
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.usesDefaultArguments
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType
interface StubContext {
@@ -315,7 +314,7 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
private fun AccessorForConstructorDescriptor.constructorDescriptorWithMarker(marker: KotlinType) =
ClassConstructorDescriptorImpl.createSynthesized(containingDeclaration, annotations, false, source).also {
it.initialize(
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
extensionReceiverParameter?.copy(this),
dispatchReceiverParameter,
emptyList()/*TODO*/,
calleeDescriptor.valueParameters.map {
@@ -22,7 +22,9 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -66,7 +68,11 @@ fun createSynthesizedInvokes(functions: Collection<FunctionDescriptor>): Collect
private fun createSynthesizedFunctionWithFirstParameterAsReceiver(descriptor: FunctionDescriptor) =
descriptor.original.newCopyBuilder().apply {
setExtensionReceiverType(descriptor.original.valueParameters.first().type)
setExtensionReceiverParameter(
DescriptorFactory.createExtensionReceiverParameterForCallable(
descriptor.original, descriptor.original.valueParameters.first().type, Annotations.EMPTY
)
)
setValueParameters(
descriptor.original.valueParameters
.drop(1)
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.analyzer.AnalysisResult;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl;
import org.jetbrains.kotlin.psi.KtExpression;
@@ -544,7 +545,8 @@ public class KotlinTypeCheckerTest extends KotlinTestWithEnvironment {
KotlinType thisType = makeType(contextType);
ReceiverParameterDescriptorImpl receiverParameterDescriptor = new ReceiverParameterDescriptorImpl(
scopeWithImports.getOwnerDescriptor(),
new TransientReceiver(thisType)
new TransientReceiver(thisType),
Annotations.Companion.getEMPTY()
);
LexicalScope scope = new LexicalScopeImpl(scopeWithImports, scopeWithImports.getOwnerDescriptor(), false,