[MPP] Introduce allModulesProviding(Expects|Actuals)For filters
This new filters will also take care of filtering out descriptors that are provided by 'regular' dependencies instead of 'dependsOn' dependencies. ^KT-50120
This commit is contained in:
committed by
Space
parent
d1ce7ae870
commit
2e55b82ba3
Generated
+1
@@ -1,6 +1,7 @@
|
|||||||
<component name="ProjectDictionaryState">
|
<component name="ProjectDictionaryState">
|
||||||
<dictionary name="sebastiansellmair">
|
<dictionary name="sebastiansellmair">
|
||||||
<words>
|
<words>
|
||||||
|
<w>actuals</w>
|
||||||
<w>cinterops</w>
|
<w>cinterops</w>
|
||||||
<w>instantiator</w>
|
<w>instantiator</w>
|
||||||
<w>interops</w>
|
<w>interops</w>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
import org.jetbrains.kotlin.resolve.multiplatform.findCompatibleExpectsForActual
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.onlyFromThisModule
|
import org.jetbrains.kotlin.resolve.multiplatform.onlyFromThisModule
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.util.getExceptionMessage
|
import org.jetbrains.kotlin.util.getExceptionMessage
|
||||||
@@ -182,9 +182,7 @@ object CodegenUtil {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun findExpectedFunctionForActual(descriptor: FunctionDescriptor): FunctionDescriptor? {
|
fun findExpectedFunctionForActual(descriptor: FunctionDescriptor): FunctionDescriptor? {
|
||||||
val compatibleExpectedFunctions = with(ExpectedActualResolver) {
|
val compatibleExpectedFunctions = descriptor.findCompatibleExpectsForActual(onlyFromThisModule(descriptor.module))
|
||||||
descriptor.findCompatibleExpectedForActual(onlyFromThisModule(descriptor.module))
|
|
||||||
}
|
|
||||||
return compatibleExpectedFunctions.firstOrNull() as FunctionDescriptor?
|
return compatibleExpectedFunctions.firstOrNull() as FunctionDescriptor?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
import org.jetbrains.kotlin.resolve.multiplatform.findCompatibleActualsForExpected
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,9 +29,7 @@ class FrameMapWithExpectActualSupport(private val module: ModuleDescriptor) : Fr
|
|||||||
// in ExpressionCodegen.generateThisOrOuterFromContext by comparing classes by type constructor equality.
|
// in ExpressionCodegen.generateThisOrOuterFromContext by comparing classes by type constructor equality.
|
||||||
if (parameter !is ReceiverParameterDescriptor || parameter.value !is ExtensionReceiver) return null
|
if (parameter !is ReceiverParameterDescriptor || parameter.value !is ExtensionReceiver) return null
|
||||||
|
|
||||||
val actual = with(ExpectedActualResolver) {
|
val actual = container.findCompatibleActualsForExpected(module).firstOrNull()
|
||||||
container.findCompatibleActualForExpected(module).firstOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (actual as? CallableDescriptor)?.extensionReceiverParameter
|
return (actual as? CallableDescriptor)?.extensionReceiverParameter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver;
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolverKt;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
@@ -532,7 +532,7 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
parentEnumOrSealed.add(currentDescriptor.getTypeConstructor());
|
parentEnumOrSealed.add(currentDescriptor.getTypeConstructor());
|
||||||
if (currentDescriptor.isExpect()) {
|
if (currentDescriptor.isExpect()) {
|
||||||
List<MemberDescriptor> actualDescriptors = ExpectedActualResolver.INSTANCE.findCompatibleActualForExpected(
|
List<MemberDescriptor> actualDescriptors = ExpectedActualResolverKt.findCompatibleActualsForExpected(
|
||||||
currentDescriptor, DescriptorUtilsKt.getModule( currentDescriptor)
|
currentDescriptor, DescriptorUtilsKt.getModule( currentDescriptor)
|
||||||
);
|
);
|
||||||
for (MemberDescriptor actualDescriptor: actualDescriptors) {
|
for (MemberDescriptor actualDescriptor: actualDescriptors) {
|
||||||
|
|||||||
+4
-9
@@ -23,9 +23,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
import org.jetbrains.kotlin.resolve.multiplatform.*
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.onlyFromThisModule
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
// `doRemove` means should expect-declaration be removed from IR
|
// `doRemove` means should expect-declaration be removed from IR
|
||||||
@@ -136,16 +134,13 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
|
|||||||
|
|
||||||
private fun MemberDescriptor.findActualForExpect(): MemberDescriptor? {
|
private fun MemberDescriptor.findActualForExpect(): MemberDescriptor? {
|
||||||
if (!isExpect) error(this)
|
if (!isExpect) error(this)
|
||||||
return with(ExpectedActualResolver) {
|
return findCompatibleActualsForExpected(module).singleOrNull()
|
||||||
findCompatibleActualForExpected(this@findActualForExpect.module).singleOrNull()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MemberDescriptor.findExpectForActual(): MemberDescriptor? {
|
private fun MemberDescriptor.findExpectForActual(): MemberDescriptor? {
|
||||||
if (!isActual) error(this)
|
if (!isActual) error(this)
|
||||||
return with(ExpectedActualResolver) {
|
return findCompatibleExpectsForActual().singleOrNull()
|
||||||
findCompatibleExpectedForActual(onlyFromThisModule(this@findExpectForActual.module)).singleOrNull()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.remapExpectValueSymbols(): IrExpression {
|
private fun IrExpression.remapExpectValueSymbols(): IrExpression {
|
||||||
|
|||||||
+3
-6
@@ -26,8 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.model.CollectionLiteralKotlinCallArgum
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ALL_MODULES
|
import org.jetbrains.kotlin.resolve.multiplatform.findCompatibleExpectsForActual
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
||||||
@@ -112,10 +111,8 @@ fun ValueParameterDescriptor.hasDefaultValue(): Boolean {
|
|||||||
private fun ValueParameterDescriptor.checkExpectedParameter(checker: (ValueParameterDescriptor) -> Boolean): Boolean {
|
private fun ValueParameterDescriptor.checkExpectedParameter(checker: (ValueParameterDescriptor) -> Boolean): Boolean {
|
||||||
val function = containingDeclaration
|
val function = containingDeclaration
|
||||||
if (function is FunctionDescriptor && function.isActual) {
|
if (function is FunctionDescriptor && function.isActual) {
|
||||||
with(ExpectedActualResolver) {
|
val expected = function.findCompatibleExpectsForActual().firstOrNull()
|
||||||
val expected = function.findCompatibleExpectedForActual(ALL_MODULES).firstOrNull()
|
return expected is FunctionDescriptor && checker(expected.valueParameters[index])
|
||||||
return expected is FunctionDescriptor && checker(expected.valueParameters[index])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-26
@@ -24,24 +24,11 @@ import org.jetbrains.kotlin.utils.SmartList
|
|||||||
import org.jetbrains.kotlin.utils.keysToMap
|
import org.jetbrains.kotlin.utils.keysToMap
|
||||||
|
|
||||||
object ExpectedActualResolver {
|
object ExpectedActualResolver {
|
||||||
// FIXME(dsavvinov): review clients, as they won't work properly in HMPP projects
|
|
||||||
fun MemberDescriptor.findCompatibleActualForExpected(platformModule: ModuleDescriptor): List<MemberDescriptor> =
|
|
||||||
findActualForExpected(this, platformModule, onlyFromThisModule(platformModule))?.get(Compatible).orEmpty()
|
|
||||||
|
|
||||||
fun MemberDescriptor.findAnyActualForExpected(platformModule: ModuleDescriptor): List<MemberDescriptor> {
|
|
||||||
val actualsGroupedByCompatibility = findActualForExpected(this, platformModule, onlyFromThisModule(platformModule))
|
|
||||||
return actualsGroupedByCompatibility?.get(Compatible)
|
|
||||||
?: actualsGroupedByCompatibility?.values?.flatten()
|
|
||||||
?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun MemberDescriptor.findCompatibleExpectedForActual(moduleFilter: ModuleFilter): List<MemberDescriptor> =
|
|
||||||
findExpectedForActual(this, moduleFilter)?.get(Compatible).orEmpty()
|
|
||||||
|
|
||||||
fun findActualForExpected(
|
fun findActualForExpected(
|
||||||
expected: MemberDescriptor,
|
expected: MemberDescriptor,
|
||||||
platformModule: ModuleDescriptor,
|
platformModule: ModuleDescriptor,
|
||||||
moduleVisibilityFilter: ModuleFilter,
|
moduleVisibilityFilter: ModuleFilter = allModulesProvidingActualsFor(expected.module),
|
||||||
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? {
|
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? {
|
||||||
return when (expected) {
|
return when (expected) {
|
||||||
is CallableMemberDescriptor -> {
|
is CallableMemberDescriptor -> {
|
||||||
@@ -69,7 +56,7 @@ object ExpectedActualResolver {
|
|||||||
|
|
||||||
fun findExpectedForActual(
|
fun findExpectedForActual(
|
||||||
actual: MemberDescriptor,
|
actual: MemberDescriptor,
|
||||||
moduleFilter: (ModuleDescriptor) -> Boolean
|
moduleFilter: (ModuleDescriptor) -> Boolean = allModulesProvidingExpectsFor(actual.module)
|
||||||
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? {
|
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? {
|
||||||
return when (actual) {
|
return when (actual) {
|
||||||
is CallableMemberDescriptor -> {
|
is CallableMemberDescriptor -> {
|
||||||
@@ -533,19 +520,39 @@ object ExpectedActualResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DeclarationDescriptor.findExpects(): List<MemberDescriptor> {
|
// FIXME(dsavvinov): review clients, as they won't work properly in HMPP projects
|
||||||
return ExpectedActualResolver.findExpectedForActual(
|
@JvmOverloads
|
||||||
this as MemberDescriptor, ALL_MODULES
|
fun MemberDescriptor.findCompatibleActualsForExpected(
|
||||||
)?.get(Compatible).orEmpty()
|
platformModule: ModuleDescriptor, moduleFilter: ModuleFilter = allModulesProvidingActualsFor(module)
|
||||||
|
): List<MemberDescriptor> =
|
||||||
|
ExpectedActualResolver.findActualForExpected(this, platformModule, moduleFilter)?.get(Compatible).orEmpty()
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun MemberDescriptor.findAnyActualsForExpected(
|
||||||
|
platformModule: ModuleDescriptor, moduleFilter: ModuleFilter = allModulesProvidingActualsFor(module)
|
||||||
|
): List<MemberDescriptor> {
|
||||||
|
val actualsGroupedByCompatibility = ExpectedActualResolver.findActualForExpected(this, platformModule, moduleFilter)
|
||||||
|
return actualsGroupedByCompatibility?.get(Compatible)
|
||||||
|
?: actualsGroupedByCompatibility?.values?.flatten()
|
||||||
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DeclarationDescriptor.findActuals(inModule: ModuleDescriptor = this.module): List<MemberDescriptor> {
|
fun MemberDescriptor.findCompatibleExpectsForActual(
|
||||||
return ExpectedActualResolver.findActualForExpected(
|
moduleFilter: ModuleFilter = allModulesProvidingExpectsFor(module)
|
||||||
(this as MemberDescriptor), inModule, ALL_MODULES
|
): List<MemberDescriptor> =
|
||||||
)?.get(Compatible).orEmpty()
|
ExpectedActualResolver.findExpectedForActual(this, moduleFilter)?.get(Compatible).orEmpty()
|
||||||
|
|
||||||
|
fun DeclarationDescriptor.findExpects(): List<MemberDescriptor> {
|
||||||
|
if(this !is MemberDescriptor) return emptyList()
|
||||||
|
return this.findCompatibleExpectsForActual()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeclarationDescriptor.findActuals(inModule: ModuleDescriptor): List<MemberDescriptor> {
|
||||||
|
if(this !is MemberDescriptor) return emptyList()
|
||||||
|
return this.findCompatibleActualsForExpected(inModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Klibs still need to better handle source in deserialized descriptors.
|
// TODO: Klibs still need to better handle source in deserialized descriptors.
|
||||||
val DeclarationDescriptorWithSource.couldHaveASource: Boolean get() =
|
val DeclarationDescriptorWithSource.couldHaveASource: Boolean
|
||||||
this.source.containingFile != SourceFile.NO_SOURCE_FILE ||
|
get() = this.source.containingFile != SourceFile.NO_SOURCE_FILE ||
|
||||||
this is DeserializedDescriptor
|
this is DeserializedDescriptor
|
||||||
|
|||||||
+1
-3
@@ -19,9 +19,7 @@ object OptionalAnnotationUtil {
|
|||||||
assert(descriptor.isExpect) { "Not an expected class: $descriptor" }
|
assert(descriptor.isExpect) { "Not an expected class: $descriptor" }
|
||||||
|
|
||||||
if (isOptionalAnnotationClass(descriptor)) {
|
if (isOptionalAnnotationClass(descriptor)) {
|
||||||
with(ExpectedActualResolver) {
|
return descriptor.findCompatibleActualsForExpected(descriptor.module).isEmpty()
|
||||||
return descriptor.findCompatibleActualForExpected(descriptor.module).isEmpty()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
+8
@@ -15,4 +15,12 @@ fun onlyFromThisModule(module: ModuleDescriptor): ModuleFilter = { it == module
|
|||||||
|
|
||||||
val ALL_MODULES: ModuleFilter = { true }
|
val ALL_MODULES: ModuleFilter = { true }
|
||||||
|
|
||||||
|
fun allModulesProvidingExpectsFor(platformModule: ModuleDescriptor): ModuleFilter = {
|
||||||
|
it == platformModule || it in platformModule.allExpectedByModules
|
||||||
|
}
|
||||||
|
|
||||||
|
fun allModulesProvidingActualsFor(commonModule: ModuleDescriptor): ModuleFilter = {
|
||||||
|
it == commonModule || commonModule in it.allExpectedByModules
|
||||||
|
}
|
||||||
|
|
||||||
fun <T : DeclarationDescriptor> Iterable<T>.applyFilter(filter: ModuleFilter): List<T> = filter { filter(it.module) }
|
fun <T : DeclarationDescriptor> Iterable<T>.applyFilter(filter: ModuleFilter): List<T> = filter { filter(it.module) }
|
||||||
|
|||||||
Reference in New Issue
Block a user