From 595279887a0e629833455a4c6f2f8738a95e7a18 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Fri, 19 May 2023 12:15:46 +0200 Subject: [PATCH] [LL FIR] add correct isResolved check to expect-actual phase transformer --- .../LLFirExpectActualMatcherLazyResolver.kt | 27 +++++++++++-------- .../api/fir/util/firCheckResolvedUtils.kt | 12 +++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt index 79ea0f81197..8e7406f36e4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.LLFirPhaseUpdater +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkExpectForActualIsResolved import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkPhase import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirSession @@ -35,7 +36,10 @@ internal object LLFirExpectActualMatcherLazyResolver : LLFirLazyResolver(FirReso override fun checkIsResolved(target: FirElementWithResolveState) { target.checkPhase(resolverPhase) - // TODO check if expect-actual matching is present + if (target is FirMemberDeclaration && target.canHaveExpectCounterPart()) { + checkExpectForActualIsResolved(target) + } + checkNestedDeclarationsAreResolved(target) } } @@ -68,13 +72,14 @@ private class LLFirExpectActualMatchingTargetResolver( transformer.transformMemberDeclaration(target) } - private fun FirMemberDeclaration.canHaveExpectCounterPart(): Boolean = when (this) { - is FirEnumEntry -> true - is FirProperty -> true - is FirConstructor -> true - is FirSimpleFunction -> true - is FirRegularClass -> true - is FirTypeAlias -> true - else -> false - } -} \ No newline at end of file +} + +private fun FirMemberDeclaration.canHaveExpectCounterPart(): Boolean = when (this) { + is FirEnumEntry -> true + is FirProperty -> true + is FirConstructor -> true + is FirSimpleFunction -> true + is FirRegularClass -> true + is FirTypeAlias -> true + else -> false +} diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt index 015cfec7ed6..daef8f5e003 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isActual import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList @@ -52,6 +53,17 @@ internal fun checkBodyIsResolved(function: FirFunction) { } } +internal fun checkExpectForActualIsResolved(memberDeclaration: FirMemberDeclaration) { + if (!memberDeclaration.isActual) return + + checkWithAttachmentBuilder( + condition = memberDeclaration.expectForActual != null, + message = { "Expect for actual matching is missing" } + ) { + withFirEntry("declaration", memberDeclaration) + } +} + internal fun checkDelegatedConstructorIsResolved(constructor: FirConstructor) { val delegatedConstructorCall = constructor.delegatedConstructor ?: return val calleeReference = delegatedConstructorCall.calleeReference