[FIR] Always run expect actual matching for actual annotation/inline class primary constructor

Previously, we didn't run it when the primary constructor itself didn't
have the actual modifier even though the modifier is optional.

#KT-60120 Fixed
This commit is contained in:
Kirill Rakhman
2023-07-05 14:24:51 +02:00
committed by Space Team
parent 363b336b7a
commit 883102c4c6
6 changed files with 66 additions and 3 deletions
@@ -250,6 +250,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructorDefaultArgsViaActualTypealias.kt");
}
@Test
@TestMetadata("expectAnnotationAndInlineClassWithDefaultValue.kt")
public void testExpectAnnotationAndInlineClassWithDefaultValue() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt");
}
@Test
@TestMetadata("expectedDeclaresDefaultArguments.kt")
public void testExpectedDeclaresDefaultArguments() throws Exception {
@@ -250,6 +250,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructorDefaultArgsViaActualTypealias.kt");
}
@Test
@TestMetadata("expectAnnotationAndInlineClassWithDefaultValue.kt")
public void testExpectAnnotationAndInlineClassWithDefaultValue() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt");
}
@Test
@TestMetadata("expectedDeclaresDefaultArguments.kt")
public void testExpectedDeclaresDefaultArguments() throws Exception {
@@ -6,19 +6,23 @@
package org.jetbrains.kotlin.fir.resolve.transformers.mpp
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.declarations.utils.isActual
import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractTreeTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor
import org.jetbrains.kotlin.fir.visitors.FirTransformer
class FirExpectActualMatcherProcessor(
session: FirSession,
scopeSession: ScopeSession
scopeSession: ScopeSession,
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.EXPECT_ACTUAL_MATCHING) {
private val enabled = session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
@@ -32,7 +36,7 @@ class FirExpectActualMatcherProcessor(
open class FirExpectActualMatcherTransformer(
override val session: FirSession,
private val scopeSession: ScopeSession
private val scopeSession: ScopeSession,
) : FirAbstractTreeTransformer<Nothing?>(FirResolvePhase.EXPECT_ACTUAL_MATCHING) {
// --------------------------- classifiers ---------------------------
@@ -76,7 +80,7 @@ open class FirExpectActualMatcherTransformer(
// ------------------------------------------------------
fun transformMemberDeclaration(memberDeclaration: FirMemberDeclaration) {
if (!memberDeclaration.isActual) return
if (!memberDeclaration.isActual && !memberDeclaration.isImplicitlyActual()) return
val actualSymbol = memberDeclaration.symbol
// Regardless of whether any `expect` symbols are found for `memberDeclaration`, it must be assigned an `expectForActual` map.
@@ -89,4 +93,11 @@ open class FirExpectActualMatcherTransformer(
) ?: mapOf()
memberDeclaration.expectForActual = expectForActualData
}
// TODO KT-60139 Remove special handling when implicitly actual elements have the actual flag set.
private fun FirMemberDeclaration.isImplicitlyActual(): Boolean {
if (this !is FirPrimaryConstructor) return false
val klass = getContainingClass(session) ?: return false
return klass.isActual && (klass.isInline || klass.classKind == ClassKind.ANNOTATION_CLASS)
}
}
@@ -0,0 +1,17 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect annotation class Measurement(val iterations: Int = -1)
expect value class Inline(val value: String = "")
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual annotation class Measurement(actual val iterations: Int)
@JvmInline actual value class Inline(val value: String)
@Measurement()
fun test() {
Inline() // KT-60476 Fixed in K2
}
@@ -0,0 +1,17 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
expect annotation class Measurement(val iterations: Int = -1)
expect value class Inline(val value: String = "")
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual annotation class Measurement(actual val iterations: Int)
@JvmInline actual value class Inline(val value: String)
@Measurement()
fun test() {
Inline<!NO_VALUE_FOR_PARAMETER!>()<!> // KT-60476 Fixed in K2
}
@@ -22777,6 +22777,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructorDefaultArgsViaActualTypealias.kt");
}
@Test
@TestMetadata("expectAnnotationAndInlineClassWithDefaultValue.kt")
public void testExpectAnnotationAndInlineClassWithDefaultValue() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt");
}
@Test
@TestMetadata("expectedDeclaresDefaultArguments.kt")
public void testExpectedDeclaresDefaultArguments() throws Exception {