diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedExpectActualMatcherTransformer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedExpectActualMatcherTransformer.kt index a05ab0b7a69..a85dc6c0d22 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedExpectActualMatcherTransformer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedExpectActualMatcherTransformer.kt @@ -39,7 +39,7 @@ internal class LLFirDesignatedExpectActualMatcherTransformer( override fun transformDeclaration(phaseRunner: LLFirPhaseRunner) { if (designation.target.resolvePhase >= FirResolvePhase.EXPECT_ACTUAL_MATCHING) return - designation.target.checkPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) + designation.target.checkPhase(FirResolvePhase.STATUS) FirLazyBodiesCalculator.calculateLazyBodiesInside(designation) phaseRunner.runPhaseWithCustomResolve(FirResolvePhase.EXPECT_ACTUAL_MATCHING) { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt index 88302588f28..a115659ba4c 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LazyTransformerFactory.kt @@ -40,6 +40,11 @@ internal object LazyTransformerFactory { designation.firFile.moduleData.session, scopeSession, ) + FirResolvePhase.EXPECT_ACTUAL_MATCHING -> LLFirDesignatedExpectActualMatcherTransformer( + designation, + designation.firFile.moduleData.session, + scopeSession + ) FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS -> LLFirDesignatedAnnotationsResolveTransformed( designation, designation.firFile.moduleData.session, @@ -72,11 +77,6 @@ internal object LazyTransformerFactory { scopeSession, towerDataContextCollector ) - FirResolvePhase.EXPECT_ACTUAL_MATCHING -> LLFirDesignatedExpectActualMatcherTransformer( - designation, - designation.firFile.moduleData.session, - scopeSession - ) FirResolvePhase.RAW_FIR -> error("Non-lazy phase $phase") FirResolvePhase.IMPORTS -> error("Non-lazy phase $phase") } diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt index b00f8c83478..c4e3d5ed7f1 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt @@ -265,6 +265,45 @@ FILE: annotationParameters.kt } +EXPECT_ACTUAL_MATCHING: +FILE: annotationParameters.kt + public? final? [RAW_FIR] enum class X : R|kotlin/Enum| { + private [RAW_FIR] [ContainingClassKey=X] constructor(): R|X| { + LAZY_super|> + } + + public final static [RAW_FIR] [ContainingClassKey=X] enum entry A: R|X| + public final static [RAW_FIR] [ContainingClassKey=X] fun values(): R|kotlin/Array| { + } + + public final static [RAW_FIR] [ContainingClassKey=X] fun valueOf([RAW_FIR] value: R|kotlin/String|): R|X| { + } + + public final static [RAW_FIR] [ContainingClassKey=X] val entries: R|kotlin/enums/EnumEntries| + public [RAW_FIR] get(): R|kotlin/enums/EnumEntries| + + } + public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { + public? [RAW_FIR] [ContainingClassKey=Anno] constructor([RAW_FIR] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { + LAZY_super + } + + public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| + public? [RAW_FIR] [ContainingClassKey=Anno] get(): A.X + + } + public final [SUPER_TYPES] class B : R|kotlin/Any| { + public [TYPES] [ContainingClassKey=B] constructor(): R|B| { + LAZY_super + } + + @R|Anno|(X#.A#) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + } + + @R|Anno|(LAZY_EXPRESSION) public final [TYPES] fun foo(): R|kotlin/Unit| { LAZY_BLOCK } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: annotationParameters.kt public final [STATUS] enum class X : R|kotlin/Enum| { @@ -297,7 +336,8 @@ FILE: annotationParameters.kt LAZY_super } - @R|Anno|(Q|X|.R|/X.A|) public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + @R|Anno|(Q|X|.R|/X.A|) public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + } @R|Anno|(LAZY_EXPRESSION) public final [STATUS] fun foo(): R|kotlin/Unit| { LAZY_BLOCK } @@ -420,45 +460,6 @@ FILE: annotationParameters.kt } -EXPECT_ACTUAL_MATCHING: -FILE: annotationParameters.kt - public final [STATUS] enum class X : R|kotlin/Enum| { - private [STATUS] [ContainingClassKey=X] constructor(): R|X| { - LAZY_super|> - } - - public final static [STATUS] [ContainingClassKey=X] enum entry A: R|X| - public final static [STATUS] [ContainingClassKey=X] fun values(): R|kotlin/Array| { - } - - public final static [STATUS] [ContainingClassKey=X] fun valueOf([STATUS] value: R|kotlin/String|): R|X| { - } - - public final static [STATUS] [ContainingClassKey=X] val entries: R|kotlin/enums/EnumEntries| - public [STATUS] get(): R|kotlin/enums/EnumEntries| - - } - public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| { - public [STATUS] [ContainingClassKey=Anno] constructor([STATUS] [CorrespondingProperty=/Anno.args] args: ): R|Anno| { - LAZY_super - } - - public final [TYPES] [IsFromPrimaryConstructor=true] val args: = R|/args| - public [TYPES] [ContainingClassKey=Anno] get(): - - } - public final [STATUS] class B : R|kotlin/Any| { - public [STATUS] [ContainingClassKey=B] constructor(): R|B| { - LAZY_super - } - - @R|Anno|(args = Q|X|.R|/X.A|) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - } - - @R|Anno|(X#.A#) public final [STATUS] fun foo(): R|kotlin/Unit| { LAZY_BLOCK } - - } - BODY_RESOLVE: FILE: annotationParameters.kt public final [STATUS] enum class X : R|kotlin/Enum| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/annotations.txt b/analysis/low-level-api-fir/testdata/lazyResolve/annotations.txt index 69d442b9a5e..45b91614828 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/annotations.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/annotations.txt @@ -34,10 +34,17 @@ FILE: annotations.kt @FILE:Suppress(LAZY_EXPRESSION) @R|kotlin/Suppress|(LAZY_EXPRESSION) public final [STATUS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: annotations.kt + @FILE:Suppress(LAZY_EXPRESSION) + @R|kotlin/Suppress|(String(2)) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + } + ARGUMENTS_OF_ANNOTATIONS: FILE: annotations.kt @FILE:Suppress(LAZY_EXPRESSION) - @R|kotlin/Suppress|(String(2)) public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + @R|kotlin/Suppress|(String(2)) public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + } CONTRACTS: FILE: annotations.kt @@ -57,12 +64,6 @@ FILE: annotations.kt @R|kotlin/Suppress|(names = vararg(String(2))) public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun resolveMe(): R|kotlin/Unit| { } -EXPECT_ACTUAL_MATCHING: -FILE: annotations.kt - @FILE:Suppress(String(1)) - @R|kotlin/Suppress|(names = vararg(String(2))) public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - } - BODY_RESOLVE: FILE: annotations.kt @FILE:Suppress(String(1)) diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/classMembers.txt b/analysis/low-level-api-fir/testdata/lazyResolve/classMembers.txt index ba8ffd53b76..2239cc90cdd 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/classMembers.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/classMembers.txt @@ -125,6 +125,26 @@ FILE: classMembers.kt } +EXPECT_ACTUAL_MATCHING: +FILE: classMembers.kt + public final [SUPER_TYPES] class A : R|kotlin/Any| { + public [TYPES] [ContainingClassKey=A] constructor(): R|A| { + LAZY_super + } + + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } + + public final [TYPES] val x: R|kotlin/Int| = LAZY_EXPRESSION + public [TYPES] [ContainingClassKey=A] get(): R|kotlin/Int| { LAZY_BLOCK } + + public final [TYPES] fun receive([TYPES] value: R|kotlin/String|): R|kotlin/Unit| { LAZY_BLOCK } + + public final [TYPES] fun functionWithLazyBody(): R|kotlin/String| { LAZY_BLOCK } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: classMembers.kt public final [STATUS] class A : R|kotlin/Any| { @@ -132,7 +152,9 @@ FILE: classMembers.kt LAZY_super } - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } public final [STATUS] val x: R|kotlin/Int| = LAZY_EXPRESSION public [STATUS] [ContainingClassKey=A] get(): R|kotlin/Int| { LAZY_BLOCK } @@ -203,26 +225,6 @@ FILE: classMembers.kt } -EXPECT_ACTUAL_MATCHING: -FILE: classMembers.kt - public final [STATUS] class A : R|kotlin/Any| { - public [STATUS] [ContainingClassKey=A] constructor(): R|A| { - LAZY_super - } - - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(functionWithLazyBody#()) - } - - public final [STATUS] val x: R|kotlin/Int| = LAZY_EXPRESSION - public [STATUS] [ContainingClassKey=A] get(): R|kotlin/Int| { LAZY_BLOCK } - - public final [STATUS] fun receive([STATUS] value: R|kotlin/String|): R|kotlin/Unit| { LAZY_BLOCK } - - public final [STATUS] fun functionWithLazyBody(): R|kotlin/String| { LAZY_BLOCK } - - } - BODY_RESOLVE: FILE: classMembers.kt public final [STATUS] class A : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt index 3b60177061a..99a8303132b 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt @@ -62,11 +62,20 @@ FILE: classWithTypeParameters.kt } +EXPECT_ACTUAL_MATCHING: +FILE: classWithTypeParameters.kt + public final [EXPECT_ACTUAL_MATCHING] class ResolveMe<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> : R|kotlin/Any| { + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=ResolveMe] constructor<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K>(): R|ResolveMe| { + super() + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: classWithTypeParameters.kt public final [ARGUMENTS_OF_ANNOTATIONS] class ResolveMe<[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K> : R|kotlin/Any| { public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=ResolveMe] constructor<[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K>(): R|ResolveMe| { - LAZY_super + super() } } @@ -98,15 +107,6 @@ FILE: classWithTypeParameters.kt } -EXPECT_ACTUAL_MATCHING: -FILE: classWithTypeParameters.kt - public final [EXPECT_ACTUAL_MATCHING] class ResolveMe<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> : R|kotlin/Any| { - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=ResolveMe] constructor<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K>(): R|ResolveMe| { - super() - } - - } - BODY_RESOLVE: FILE: classWithTypeParameters.kt public final [BODY_RESOLVE] class ResolveMe<[BODY_RESOLVE] T : R|kotlin/Int|, [BODY_RESOLVE] K> : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt b/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt index 1cfe70f93b8..571027a08df 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt @@ -97,6 +97,21 @@ FILE: functionInValueClass.kt } +EXPECT_ACTUAL_MATCHING: +FILE: functionInValueClass.kt + @R|kotlin/jvm/JvmInline|() public final inline [SUPER_TYPES] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { + public [TYPES] [ContainingClassKey=Value] constructor([TYPES] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { + LAZY_super + } + + public final [TYPES] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| + public [TYPES] [ContainingClassKey=Value] get(): R|kotlin/Int| + + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { @@ -107,7 +122,8 @@ FILE: functionInValueClass.kt public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| public [STATUS] [ContainingClassKey=Value] get(): R|kotlin/Int| - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + } } @@ -156,21 +172,6 @@ FILE: functionInValueClass.kt } -EXPECT_ACTUAL_MATCHING: -FILE: functionInValueClass.kt - @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { - public [STATUS] [ContainingClassKey=Value] constructor([STATUS] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - LAZY_super - } - - public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| - public [STATUS] [ContainingClassKey=Value] get(): R|kotlin/Int| - - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - } - - } - BODY_RESOLVE: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/classes/nestedClassWithPropertiesOverrides.txt b/analysis/low-level-api-fir/testdata/lazyResolve/classes/nestedClassWithPropertiesOverrides.txt index 7f87697443b..616fc58649e 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/classes/nestedClassWithPropertiesOverrides.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/classes/nestedClassWithPropertiesOverrides.txt @@ -167,6 +167,30 @@ FILE: nestedClassWithPropertiesOverrides.kt } +EXPECT_ACTUAL_MATCHING: +FILE: nestedClassWithPropertiesOverrides.kt + public abstract [SUPER_TYPES] interface OV : R|kotlin/Any| { + public abstract [TYPES] val originalExpressions: R|A| + public [TYPES] [ContainingClassKey=OV] get(): R|A| + + public final [EXPECT_ACTUAL_MATCHING] class ResolveMe : R|OV| { + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=ResolveMe] constructor(): R|OV.ResolveMe| { + super<>() + } + + public open override [EXPECT_ACTUAL_MATCHING] val originalExpressions: R|A| + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=ResolveMe] get(): R|A| + + } + + } + public? final? [RAW_FIR] class A : R|kotlin/Any| { + public? [RAW_FIR] [ContainingClassKey=A] constructor(): R|A| { + LAZY_super + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: nestedClassWithPropertiesOverrides.kt public abstract [STATUS] interface OV : R|kotlin/Any| { @@ -175,7 +199,7 @@ FILE: nestedClassWithPropertiesOverrides.kt public final [ARGUMENTS_OF_ANNOTATIONS] class ResolveMe : R|OV| { public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=ResolveMe] constructor(): R|OV.ResolveMe| { - LAZY_super<> + super<>() } public open override [ARGUMENTS_OF_ANNOTATIONS] val originalExpressions: R|A| @@ -263,30 +287,6 @@ FILE: nestedClassWithPropertiesOverrides.kt } -EXPECT_ACTUAL_MATCHING: -FILE: nestedClassWithPropertiesOverrides.kt - public abstract [STATUS] interface OV : R|kotlin/Any| { - public abstract [STATUS] val originalExpressions: R|A| - public [STATUS] [ContainingClassKey=OV] get(): R|A| - - public final [EXPECT_ACTUAL_MATCHING] class ResolveMe : R|OV| { - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=ResolveMe] constructor(): R|OV.ResolveMe| { - super<>() - } - - public open override [EXPECT_ACTUAL_MATCHING] val originalExpressions: R|A| - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=ResolveMe] get(): R|A| - - } - - } - public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor(): R|A| { - LAZY_super - } - - } - BODY_RESOLVE: FILE: nestedClassWithPropertiesOverrides.kt public abstract [STATUS] interface OV : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/delegates.txt b/analysis/low-level-api-fir/testdata/lazyResolve/delegates.txt index 7f04c74b4a8..98d12d38287 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/delegates.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/delegates.txt @@ -202,9 +202,48 @@ FILE: delegates.kt D|/variableWithImplicitType|.setValue#(Null(null), ::R|/variableWithImplicitType|, R|/variableWithImplicitType|) } +EXPECT_ACTUAL_MATCHING: +FILE: delegates.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(valueWithExplicitType#) + receive#(valueWithImplicitType#) + variableWithExplicitType# = IntegerLiteral(10) + variableWithImplicitType# = IntegerLiteral(10) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] val delegate: = LAZY_EXPRESSION + public? [RAW_FIR] get(): + public? final? [RAW_FIR] val valueWithExplicitType: Intby LAZY_EXPRESSION + public? [RAW_FIR] get(): { + ^ D|/valueWithExplicitType|.getValue#(Null(null), ::R|/valueWithExplicitType|) + } + public? final? [RAW_FIR] val valueWithImplicitType: by LAZY_EXPRESSION + public? [RAW_FIR] get(): { + ^ D|/valueWithImplicitType|.getValue#(Null(null), ::R|/valueWithImplicitType|) + } + public? final? [RAW_FIR] var variableWithExplicitType: Intby LAZY_EXPRESSION + public? [RAW_FIR] get(): { + ^ D|/variableWithExplicitType|.getValue#(Null(null), ::R|/variableWithExplicitType|) + } + public? [RAW_FIR] set([RAW_FIR] : ): R|kotlin/Unit| { + D|/variableWithExplicitType|.setValue#(Null(null), ::R|/variableWithExplicitType|, R|/variableWithExplicitType|) + } + public? final? [RAW_FIR] var variableWithImplicitType: by LAZY_EXPRESSION + public? [RAW_FIR] get(): { + ^ D|/variableWithImplicitType|.getValue#(Null(null), ::R|/variableWithImplicitType|) + } + public? [RAW_FIR] set([RAW_FIR] : ): R|kotlin/Unit| { + D|/variableWithImplicitType|.setValue#(Null(null), ::R|/variableWithImplicitType|, R|/variableWithImplicitType|) + } + ARGUMENTS_OF_ANNOTATIONS: FILE: delegates.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(valueWithExplicitType#) + receive#(valueWithImplicitType#) + variableWithExplicitType# = IntegerLiteral(10) + variableWithImplicitType# = IntegerLiteral(10) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] val delegate: = LAZY_EXPRESSION public? [RAW_FIR] get(): @@ -333,40 +372,6 @@ FILE: delegates.kt D|/variableWithImplicitType|.setValue#(Null(null), ::R|/variableWithImplicitType|, R|/variableWithImplicitType|) } -EXPECT_ACTUAL_MATCHING: -FILE: delegates.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(valueWithExplicitType#) - receive#(valueWithImplicitType#) - variableWithExplicitType# = IntegerLiteral(10) - variableWithImplicitType# = IntegerLiteral(10) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] val delegate: = LAZY_EXPRESSION - public? [RAW_FIR] get(): - public? final? [RAW_FIR] val valueWithExplicitType: Intby LAZY_EXPRESSION - public? [RAW_FIR] get(): { - ^ D|/valueWithExplicitType|.getValue#(Null(null), ::R|/valueWithExplicitType|) - } - public? final? [RAW_FIR] val valueWithImplicitType: by LAZY_EXPRESSION - public? [RAW_FIR] get(): { - ^ D|/valueWithImplicitType|.getValue#(Null(null), ::R|/valueWithImplicitType|) - } - public? final? [RAW_FIR] var variableWithExplicitType: Intby LAZY_EXPRESSION - public? [RAW_FIR] get(): { - ^ D|/variableWithExplicitType|.getValue#(Null(null), ::R|/variableWithExplicitType|) - } - public? [RAW_FIR] set([RAW_FIR] : ): R|kotlin/Unit| { - D|/variableWithExplicitType|.setValue#(Null(null), ::R|/variableWithExplicitType|, R|/variableWithExplicitType|) - } - public? final? [RAW_FIR] var variableWithImplicitType: by LAZY_EXPRESSION - public? [RAW_FIR] get(): { - ^ D|/variableWithImplicitType|.getValue#(Null(null), ::R|/variableWithImplicitType|) - } - public? [RAW_FIR] set([RAW_FIR] : ): R|kotlin/Unit| { - D|/variableWithImplicitType|.setValue#(Null(null), ::R|/variableWithImplicitType|, R|/variableWithImplicitType|) - } - BODY_RESOLVE: FILE: delegates.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/enumEntry.txt b/analysis/low-level-api-fir/testdata/lazyResolve/enumEntry.txt index 35230d8340a..16e60204b4f 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/enumEntry.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/enumEntry.txt @@ -174,6 +174,37 @@ FILE: enumEntry.kt } +EXPECT_ACTUAL_MATCHING: +FILE: enumEntry.kt + public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { + public? [RAW_FIR] [ContainingClassKey=Anno] constructor(): R|Anno| { + LAZY_super + } + + } + public final [SUPER_TYPES] enum class Foo : R|kotlin/Enum| { + private [TYPES] [ContainingClassKey=Foo] constructor(): R|Foo| { + LAZY_super|> + } + + @R|Anno|() public final static [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=Foo] enum entry ResolveMe: R|Foo| = object : R|Foo| { + private [RAW_FIR] [ContainingClassKey=] constructor(): R|| { + super() + } + + } + + public final static [TYPES] [ContainingClassKey=Foo] fun values(): R|kotlin/Array| { + } + + public final static [TYPES] [ContainingClassKey=Foo] fun valueOf([TYPES] value: R|kotlin/String|): R|Foo| { + } + + public final static [TYPES] [ContainingClassKey=Foo] val entries: R|kotlin/enums/EnumEntries| + public [TYPES] get(): R|kotlin/enums/EnumEntries| + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: enumEntry.kt public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { @@ -187,7 +218,13 @@ FILE: enumEntry.kt LAZY_super|> } - @R|Anno|() public final static [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=Foo] enum entry ResolveMe: R|Foo| = LAZY_EXPRESSION + @R|Anno|() public final static [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=Foo] enum entry ResolveMe: R|Foo| = object : R|Foo| { + private [RAW_FIR] [ContainingClassKey=] constructor(): R|| { + super() + } + + } + public final static [STATUS] [ContainingClassKey=Foo] fun values(): R|kotlin/Array| { } @@ -292,37 +329,6 @@ FILE: enumEntry.kt } -EXPECT_ACTUAL_MATCHING: -FILE: enumEntry.kt - public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| { - public [STATUS] [ContainingClassKey=Anno] constructor(): R|Anno| { - LAZY_super - } - - } - public final [STATUS] enum class Foo : R|kotlin/Enum| { - private [STATUS] [ContainingClassKey=Foo] constructor(): R|Foo| { - LAZY_super|> - } - - @R|Anno|() public final static [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=Foo] enum entry ResolveMe: R|Foo| = object : R|Foo| { - private [RAW_FIR] [ContainingClassKey=] constructor(): R|| { - super() - } - - } - - public final static [STATUS] [ContainingClassKey=Foo] fun values(): R|kotlin/Array| { - } - - public final static [STATUS] [ContainingClassKey=Foo] fun valueOf([STATUS] value: R|kotlin/String|): R|Foo| { - } - - public final static [STATUS] [ContainingClassKey=Foo] val entries: R|kotlin/enums/EnumEntries| - public [STATUS] get(): R|kotlin/enums/EnumEntries| - - } - BODY_RESOLVE: FILE: enumEntry.kt public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/errors/anonymousObjectInInvalidPosition.txt b/analysis/low-level-api-fir/testdata/lazyResolve/errors/anonymousObjectInInvalidPosition.txt index 6f72e1b9802..91fdc6b459b 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/errors/anonymousObjectInInvalidPosition.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/errors/anonymousObjectInInvalidPosition.txt @@ -62,9 +62,36 @@ FILE: anonymousObjectInInvalidPosition.kt } +EXPECT_ACTUAL_MATCHING: +FILE: anonymousObjectInInvalidPosition.kt + private final [EXPECT_ACTUAL_MATCHING] val resolveMe: = ERROR_EXPR(Should have initializer)Null(null) = object : A { + private [RAW_FIR] [ContainingClassKey=] constructor(): R|| { + super<>() + } + + public? open? override [RAW_FIR] fun x(): R|kotlin/Unit| { + } + + } + + private [EXPECT_ACTUAL_MATCHING] get(): + public? final? [RAW_FIR] interface A<[RAW_FIR] T> : R|kotlin/Any| { + public? final? [RAW_FIR] fun x(): R|kotlin/Unit| + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: anonymousObjectInInvalidPosition.kt - private final [ARGUMENTS_OF_ANNOTATIONS] val resolveMe: = LAZY_EXPRESSION + private final [ARGUMENTS_OF_ANNOTATIONS] val resolveMe: = ERROR_EXPR(Should have initializer)Null(null) = object : A { + private [RAW_FIR] [ContainingClassKey=] constructor(): R|| { + super<>() + } + + public? open? override [RAW_FIR] fun x(): R|kotlin/Unit| { + } + + } + private [ARGUMENTS_OF_ANNOTATIONS] get(): public? final? [RAW_FIR] interface A<[RAW_FIR] T> : R|kotlin/Any| { public? final? [RAW_FIR] fun x(): R|kotlin/Unit| @@ -125,24 +152,6 @@ FILE: anonymousObjectInInvalidPosition.kt } -EXPECT_ACTUAL_MATCHING: -FILE: anonymousObjectInInvalidPosition.kt - private final [EXPECT_ACTUAL_MATCHING] val resolveMe: = ERROR_EXPR(Should have initializer)Null(null) = object : A { - private [RAW_FIR] [ContainingClassKey=] constructor(): R|| { - super<>() - } - - public? open? override [RAW_FIR] fun x(): R|kotlin/Unit| { - } - - } - - private [EXPECT_ACTUAL_MATCHING] get(): - public? final? [RAW_FIR] interface A<[RAW_FIR] T> : R|kotlin/Any| { - public? final? [RAW_FIR] fun x(): R|kotlin/Unit| - - } - BODY_RESOLVE: FILE: anonymousObjectInInvalidPosition.kt private final [BODY_RESOLVE] val resolveMe: = ERROR_EXPR(Should have initializer)Null(null) = object : R|A| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/functionWithParameter.txt b/analysis/low-level-api-fir/testdata/lazyResolve/functionWithParameter.txt index e033da30add..665b7e8554b 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/functionWithParameter.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/functionWithParameter.txt @@ -41,11 +41,21 @@ FILE: functionWithParameter.kt } public final [STATUS] fun resolveMe([STATUS] param: R|I|): { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: functionWithParameter.kt + public? final? [RAW_FIR] interface I : R|kotlin/Any| { + } + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe([EXPECT_ACTUAL_MATCHING] param: R|I|): { + ^resolveMe Unit# + } + ARGUMENTS_OF_ANNOTATIONS: FILE: functionWithParameter.kt public? final? [RAW_FIR] interface I : R|kotlin/Any| { } - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe([ARGUMENTS_OF_ANNOTATIONS] param: R|I|): { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe([ARGUMENTS_OF_ANNOTATIONS] param: R|I|): { + ^resolveMe Unit# + } CONTRACTS: FILE: functionWithParameter.kt @@ -71,14 +81,6 @@ FILE: functionWithParameter.kt ^resolveMe Q|kotlin/Unit| } -EXPECT_ACTUAL_MATCHING: -FILE: functionWithParameter.kt - public? final? [RAW_FIR] interface I : R|kotlin/Any| { - } - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe([EXPECT_ACTUAL_MATCHING] param: R|I|): R|kotlin/Unit| { - ^resolveMe Q|kotlin/Unit| - } - BODY_RESOLVE: FILE: functionWithParameter.kt public? final? [RAW_FIR] interface I : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionCallWithGenericResult.txt b/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionCallWithGenericResult.txt index 97f2b9b3553..3ab4d2e05e7 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionCallWithGenericResult.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionCallWithGenericResult.txt @@ -76,6 +76,19 @@ FILE: functionCallWithGenericResult.kt public? final? [RAW_FIR] fun bar(): Foo? { LAZY_BLOCK } public final [STATUS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: functionCallWithGenericResult.kt + public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { + public? [RAW_FIR] [ContainingClassKey=Foo] constructor<[RAW_FIR] T : CharSequence>(): R|Foo| { + LAZY_super + } + + } + public? final? [RAW_FIR] fun bar(): Foo? { LAZY_BLOCK } + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + [RAW_FIR] lval x: = bar#() + } + ARGUMENTS_OF_ANNOTATIONS: FILE: functionCallWithGenericResult.kt public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { @@ -85,7 +98,9 @@ FILE: functionCallWithGenericResult.kt } public? final? [RAW_FIR] fun bar(): Foo? { LAZY_BLOCK } - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + [RAW_FIR] lval x: = bar#() + } CONTRACTS: FILE: functionCallWithGenericResult.kt @@ -126,19 +141,6 @@ FILE: functionCallWithGenericResult.kt [RAW_FIR] lval x: = bar#() } -EXPECT_ACTUAL_MATCHING: -FILE: functionCallWithGenericResult.kt - public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=Foo] constructor<[RAW_FIR] T : CharSequence>(): R|Foo| { - LAZY_super - } - - } - public? final? [RAW_FIR] fun bar(): Foo? { LAZY_BLOCK } - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - [RAW_FIR] lval x: = bar#() - } - BODY_RESOLVE: FILE: functionCallWithGenericResult.kt public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithGenericExpectedTypeInside.txt b/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithGenericExpectedTypeInside.txt index 6e14d7e9de6..dba606ccb3f 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithGenericExpectedTypeInside.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithGenericExpectedTypeInside.txt @@ -118,6 +118,25 @@ FILE: functionWithGenericExpectedTypeInside.kt public? final? [RAW_FIR] fun bar(): { LAZY_BLOCK } public final [STATUS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: functionWithGenericExpectedTypeInside.kt + public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { + public? [RAW_FIR] [ContainingClassKey=Foo] constructor<[RAW_FIR] T : CharSequence>(): R|Foo| { + LAZY_super + } + + } + public? final? [RAW_FIR] class Bar : Foo { + public? [RAW_FIR] [ContainingClassKey=Bar] constructor(): R|Bar| { + LAZY_super<> + } + + } + public? final? [RAW_FIR] fun bar(): { LAZY_BLOCK } + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + [RAW_FIR] lval x: Foo = bar#() + } + ARGUMENTS_OF_ANNOTATIONS: FILE: functionWithGenericExpectedTypeInside.kt public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { @@ -133,7 +152,9 @@ FILE: functionWithGenericExpectedTypeInside.kt } public? final? [RAW_FIR] fun bar(): { LAZY_BLOCK } - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + [RAW_FIR] lval x: Foo = bar#() + } CONTRACTS: FILE: functionWithGenericExpectedTypeInside.kt @@ -192,25 +213,6 @@ FILE: functionWithGenericExpectedTypeInside.kt [RAW_FIR] lval x: Foo = bar#() } -EXPECT_ACTUAL_MATCHING: -FILE: functionWithGenericExpectedTypeInside.kt - public? open [RAW_FIR] class Foo<[RAW_FIR] T : CharSequence> : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=Foo] constructor<[RAW_FIR] T : CharSequence>(): R|Foo| { - LAZY_super - } - - } - public? final? [RAW_FIR] class Bar : Foo { - public? [RAW_FIR] [ContainingClassKey=Bar] constructor(): R|Bar| { - LAZY_super<> - } - - } - public? final? [RAW_FIR] fun bar(): { LAZY_BLOCK } - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - [RAW_FIR] lval x: Foo = bar#() - } - BODY_RESOLVE: FILE: functionWithGenericExpectedTypeInside.kt public open [TYPES] class Foo<[TYPES] T : R|kotlin/CharSequence|> : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithTypeParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithTypeParameters.txt index 6137113a800..3b79d03eeb7 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithTypeParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/functions/functionWithTypeParameters.txt @@ -27,9 +27,15 @@ STATUS: FILE: functionWithTypeParameters.kt public final [STATUS] fun <[STATUS] T : R|kotlin/Int|, [STATUS] K> resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: functionWithTypeParameters.kt + public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> resolveMe(): R|kotlin/Unit| { + } + ARGUMENTS_OF_ANNOTATIONS: FILE: functionWithTypeParameters.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun <[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K> resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun <[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K> resolveMe(): R|kotlin/Unit| { + } CONTRACTS: FILE: functionWithTypeParameters.kt @@ -46,11 +52,6 @@ FILE: functionWithTypeParameters.kt public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun <[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K> resolveMe(): R|kotlin/Unit| { } -EXPECT_ACTUAL_MATCHING: -FILE: functionWithTypeParameters.kt - public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> resolveMe(): R|kotlin/Unit| { - } - BODY_RESOLVE: FILE: functionWithTypeParameters.kt public final [BODY_RESOLVE] fun <[BODY_RESOLVE] T : R|kotlin/Int|, [BODY_RESOLVE] K> resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/lambdaAsSAMInterface.txt b/analysis/low-level-api-fir/testdata/lazyResolve/lambdaAsSAMInterface.txt index 042f0815619..e2434880149 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/lambdaAsSAMInterface.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/lambdaAsSAMInterface.txt @@ -104,6 +104,26 @@ FILE: lambdaAsSAMInterface.kt public? final? [RAW_FIR] fun testMe([RAW_FIR] f: Foo): R|kotlin/Unit| { LAZY_BLOCK } public final [STATUS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: lambdaAsSAMInterface.kt + public? final? [RAW_FIR] class Arg : R|kotlin/Any| { + public? [RAW_FIR] [ContainingClassKey=Arg] constructor(): R|foo/Arg| { + LAZY_super + } + + } + public? final? fun [RAW_FIR] interface Foo : R|kotlin/Any| { + public? final? [RAW_FIR] fun foo([RAW_FIR] a: Arg): Arg + + } + public? final? [RAW_FIR] fun testMe([RAW_FIR] f: Foo): R|kotlin/Unit| { LAZY_BLOCK } + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + testMe#( = [STATUS] testMe@fun .([RAW_FIR] b: ): { + b# + } + ) + } + ARGUMENTS_OF_ANNOTATIONS: FILE: lambdaAsSAMInterface.kt public? final? [RAW_FIR] class Arg : R|kotlin/Any| { @@ -117,7 +137,12 @@ FILE: lambdaAsSAMInterface.kt } public? final? [RAW_FIR] fun testMe([RAW_FIR] f: Foo): R|kotlin/Unit| { LAZY_BLOCK } - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + testMe#( = [STATUS] testMe@fun .([RAW_FIR] b: ): { + b# + } + ) + } CONTRACTS: FILE: lambdaAsSAMInterface.kt @@ -179,26 +204,6 @@ FILE: lambdaAsSAMInterface.kt ) } -EXPECT_ACTUAL_MATCHING: -FILE: lambdaAsSAMInterface.kt - public? final? [RAW_FIR] class Arg : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=Arg] constructor(): R|foo/Arg| { - LAZY_super - } - - } - public? final? fun [RAW_FIR] interface Foo : R|kotlin/Any| { - public? final? [RAW_FIR] fun foo([RAW_FIR] a: Arg): Arg - - } - public? final? [RAW_FIR] fun testMe([RAW_FIR] f: Foo): R|kotlin/Unit| { LAZY_BLOCK } - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - testMe#( = [STATUS] testMe@fun .([RAW_FIR] b: ): { - b# - } - ) - } - BODY_RESOLVE: FILE: lambdaAsSAMInterface.kt public? final? [RAW_FIR] class Arg : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/parameterOfNonLocalSetter.txt b/analysis/low-level-api-fir/testdata/lazyResolve/parameterOfNonLocalSetter.txt index a9eab68ca74..3f381fce79e 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/parameterOfNonLocalSetter.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/parameterOfNonLocalSetter.txt @@ -90,6 +90,21 @@ FILE: parameterOfNonLocalSetter.kt } +EXPECT_ACTUAL_MATCHING: +FILE: parameterOfNonLocalSetter.kt + public final [SUPER_TYPES] class X : R|kotlin/Any| { + public [TYPES] [ContainingClassKey=X] constructor(): R|X| { + LAZY_super + } + + public final [EXPECT_ACTUAL_MATCHING] var x: R|kotlin/Int| = IntegerLiteral(2) + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=X] get(): R|kotlin/Int| + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=X] set([EXPECT_ACTUAL_MATCHING] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { + ^ Unit# + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: parameterOfNonLocalSetter.kt public final [STATUS] class X : R|kotlin/Any| { @@ -97,9 +112,11 @@ FILE: parameterOfNonLocalSetter.kt LAZY_super } - public final [ARGUMENTS_OF_ANNOTATIONS] var x: R|kotlin/Int| = LAZY_EXPRESSION + public final [ARGUMENTS_OF_ANNOTATIONS] var x: R|kotlin/Int| = IntegerLiteral(2) public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=X] get(): R|kotlin/Int| - public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=X] set([ARGUMENTS_OF_ANNOTATIONS] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { LAZY_BLOCK } + public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=X] set([ARGUMENTS_OF_ANNOTATIONS] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { + ^ Unit# + } } @@ -148,21 +165,6 @@ FILE: parameterOfNonLocalSetter.kt } -EXPECT_ACTUAL_MATCHING: -FILE: parameterOfNonLocalSetter.kt - public final [STATUS] class X : R|kotlin/Any| { - public [STATUS] [ContainingClassKey=X] constructor(): R|X| { - LAZY_super - } - - public final [EXPECT_ACTUAL_MATCHING] var x: R|kotlin/Int| = IntegerLiteral(2) - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=X] get(): R|kotlin/Int| - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=X] set([EXPECT_ACTUAL_MATCHING] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { - ^ Unit# - } - - } - BODY_RESOLVE: FILE: parameterOfNonLocalSetter.kt public final [STATUS] class X : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/properties/propertyWithTypeParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/properties/propertyWithTypeParameters.txt index 7c31c9f4229..da9d5afeb3e 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/properties/propertyWithTypeParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/properties/propertyWithTypeParameters.txt @@ -34,10 +34,19 @@ FILE: propertyWithTypeParameters.kt public final [STATUS] val <[STATUS] T : R|kotlin/Int|, [STATUS] K> R|T|.resolveMe: R|K| public [STATUS] get(): R|K| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: propertyWithTypeParameters.kt + public final [EXPECT_ACTUAL_MATCHING] val <[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> R|T|.resolveMe: R|K| + public [EXPECT_ACTUAL_MATCHING] get(): R|K| { + ^ TODO#() + } + ARGUMENTS_OF_ANNOTATIONS: FILE: propertyWithTypeParameters.kt public final [ARGUMENTS_OF_ANNOTATIONS] val <[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K> R|T|.resolveMe: R|K| - public [ARGUMENTS_OF_ANNOTATIONS] get(): R|K| { LAZY_BLOCK } + public [ARGUMENTS_OF_ANNOTATIONS] get(): R|K| { + ^ TODO#() + } CONTRACTS: FILE: propertyWithTypeParameters.kt @@ -60,13 +69,6 @@ FILE: propertyWithTypeParameters.kt ^ TODO#() } -EXPECT_ACTUAL_MATCHING: -FILE: propertyWithTypeParameters.kt - public final [EXPECT_ACTUAL_MATCHING] val <[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> R|T|.resolveMe: R|K| - public [EXPECT_ACTUAL_MATCHING] get(): R|K| { - ^ TODO#() - } - BODY_RESOLVE: FILE: propertyWithTypeParameters.kt public final [BODY_RESOLVE] val <[BODY_RESOLVE] T : R|kotlin/Int|, [BODY_RESOLVE] K> R|T|.resolveMe: R|K| diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetter.txt b/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetter.txt index 5af72baa931..376604bece0 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetter.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetter.txt @@ -48,9 +48,20 @@ FILE: propertyWithGetter.kt public? final? [RAW_FIR] val withGetter: Int public? [RAW_FIR] get(): Int { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: propertyWithGetter.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(withGetter#) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] val withGetter: Int + public? [RAW_FIR] get(): Int { LAZY_BLOCK } + ARGUMENTS_OF_ANNOTATIONS: FILE: propertyWithGetter.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(withGetter#) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] val withGetter: Int public? [RAW_FIR] get(): Int { LAZY_BLOCK } @@ -82,15 +93,6 @@ FILE: propertyWithGetter.kt public? final? [RAW_FIR] val withGetter: Int public? [RAW_FIR] get(): Int { LAZY_BLOCK } -EXPECT_ACTUAL_MATCHING: -FILE: propertyWithGetter.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(withGetter#) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] val withGetter: Int - public? [RAW_FIR] get(): Int { LAZY_BLOCK } - BODY_RESOLVE: FILE: propertyWithGetter.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetterAndSetter.txt b/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetterAndSetter.txt index 08eb8ccb2fa..c6a3e56126a 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetterAndSetter.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithGetterAndSetter.txt @@ -55,9 +55,23 @@ FILE: propertyWithGetterAndSetter.kt public? [RAW_FIR] get(): Int { LAZY_BLOCK } public? [RAW_FIR] set([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: propertyWithGetterAndSetter.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(withGetterAndSetter#) + withGetterAndSetter# = IntegerLiteral(123) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] var withGetterAndSetter: Int = LAZY_EXPRESSION + public? [RAW_FIR] get(): Int { LAZY_BLOCK } + public? [RAW_FIR] set([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } + ARGUMENTS_OF_ANNOTATIONS: FILE: propertyWithGetterAndSetter.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(withGetterAndSetter#) + withGetterAndSetter# = IntegerLiteral(123) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] var withGetterAndSetter: Int = LAZY_EXPRESSION public? [RAW_FIR] get(): Int { LAZY_BLOCK } @@ -96,17 +110,6 @@ FILE: propertyWithGetterAndSetter.kt public? [RAW_FIR] get(): Int { LAZY_BLOCK } public? [RAW_FIR] set([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } -EXPECT_ACTUAL_MATCHING: -FILE: propertyWithGetterAndSetter.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(withGetterAndSetter#) - withGetterAndSetter# = IntegerLiteral(123) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] var withGetterAndSetter: Int = LAZY_EXPRESSION - public? [RAW_FIR] get(): Int { LAZY_BLOCK } - public? [RAW_FIR] set([RAW_FIR] value: Int): R|kotlin/Unit| { LAZY_BLOCK } - BODY_RESOLVE: FILE: propertyWithGetterAndSetter.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithInitializer.txt b/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithInitializer.txt index a107c71fb09..a24ddbc6ee4 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithInitializer.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/propertyWithInitializer.txt @@ -41,9 +41,19 @@ FILE: propertyWithInitializer.kt public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION public? [RAW_FIR] get(): Int +EXPECT_ACTUAL_MATCHING: +FILE: propertyWithInitializer.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(property#) + } + public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION + public? [RAW_FIR] get(): Int + ARGUMENTS_OF_ANNOTATIONS: FILE: propertyWithInitializer.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(property#) + } public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION public? [RAW_FIR] get(): Int @@ -71,14 +81,6 @@ FILE: propertyWithInitializer.kt public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION public? [RAW_FIR] get(): Int -EXPECT_ACTUAL_MATCHING: -FILE: propertyWithInitializer.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(property#) - } - public? final? [RAW_FIR] val property: Int = LAZY_EXPRESSION - public? [RAW_FIR] get(): Int - BODY_RESOLVE: FILE: propertyWithInitializer.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt b/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt index 3d5a7c5c9b0..f6d7b9def6f 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt @@ -62,9 +62,22 @@ FILE: secondaryConstructor.kt } +EXPECT_ACTUAL_MATCHING: +FILE: secondaryConstructor.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(A#(IntegerLiteral(42))) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] class A : R|kotlin/Any| { + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: secondaryConstructor.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(A#(IntegerLiteral(42))) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } @@ -104,17 +117,6 @@ FILE: secondaryConstructor.kt } -EXPECT_ACTUAL_MATCHING: -FILE: secondaryConstructor.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(A#(IntegerLiteral(42))) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } - - } - BODY_RESOLVE: FILE: secondaryConstructor.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/superTypes.txt b/analysis/low-level-api-fir/testdata/lazyResolve/superTypes.txt index 1c31d88953e..8c3a3c31c30 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/superTypes.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/superTypes.txt @@ -146,6 +146,27 @@ FILE: superTypes.kt } +EXPECT_ACTUAL_MATCHING: +FILE: superTypes.kt + public open [TYPES] class A : R|kotlin/Any| { + public [TYPES] [ContainingClassKey=A] constructor(): R|A| { + LAZY_super + } + + } + public? open [RAW_FIR] class B : A { + public? [RAW_FIR] [ContainingClassKey=B] constructor(): R|B| { + LAZY_super + } + + } + public open [EXPECT_ACTUAL_MATCHING] class resolveMe : R|A| { + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| { + super() + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: superTypes.kt public open [TYPES] class A : R|kotlin/Any| { @@ -162,7 +183,7 @@ FILE: superTypes.kt } public open [ARGUMENTS_OF_ANNOTATIONS] class resolveMe : R|A| { public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| { - LAZY_super + super() } } @@ -230,27 +251,6 @@ FILE: superTypes.kt } -EXPECT_ACTUAL_MATCHING: -FILE: superTypes.kt - public open [TYPES] class A : R|kotlin/Any| { - public [TYPES] [ContainingClassKey=A] constructor(): R|A| { - LAZY_super - } - - } - public? open [RAW_FIR] class B : A { - public? [RAW_FIR] [ContainingClassKey=B] constructor(): R|B| { - LAZY_super - } - - } - public open [EXPECT_ACTUAL_MATCHING] class resolveMe : R|A| { - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| { - super() - } - - } - BODY_RESOLVE: FILE: superTypes.kt public open [STATUS] class A : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/superTypesLoop.txt b/analysis/low-level-api-fir/testdata/lazyResolve/superTypesLoop.txt index fde503bc384..fd63ea1a6b4 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/superTypesLoop.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/superTypesLoop.txt @@ -188,11 +188,38 @@ FILE: superTypesLoop.kt } +EXPECT_ACTUAL_MATCHING: +FILE: superTypesLoop.kt + public open [EXPECT_ACTUAL_MATCHING] class resolveMe : R|C| { + public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| { + super() + } + + } + public? open [RAW_FIR] class A : /B> { + public? [RAW_FIR] [ContainingClassKey=A] constructor(): R|A| { + LAZY_super + } + + } + public? open [RAW_FIR] class B : /C> { + public? [RAW_FIR] [ContainingClassKey=B] constructor(): R|B| { + LAZY_super + } + + } + public open [TYPES] class C : /A> { + public [TYPES] [ContainingClassKey=C] constructor(): R|C| { + LAZY_super + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: superTypesLoop.kt public open [ARGUMENTS_OF_ANNOTATIONS] class resolveMe : R|C| { public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| { - LAZY_super + super() } } @@ -296,33 +323,6 @@ FILE: superTypesLoop.kt } -EXPECT_ACTUAL_MATCHING: -FILE: superTypesLoop.kt - public open [EXPECT_ACTUAL_MATCHING] class resolveMe : R|C| { - public [EXPECT_ACTUAL_MATCHING] [ContainingClassKey=resolveMe] constructor(): R|resolveMe| { - super() - } - - } - public? open [RAW_FIR] class A : /B> { - public? [RAW_FIR] [ContainingClassKey=A] constructor(): R|A| { - LAZY_super - } - - } - public? open [RAW_FIR] class B : /C> { - public? [RAW_FIR] [ContainingClassKey=B] constructor(): R|B| { - LAZY_super - } - - } - public open [TYPES] class C : /A> { - public [TYPES] [ContainingClassKey=C] constructor(): R|C| { - LAZY_super - } - - } - BODY_RESOLVE: FILE: superTypesLoop.kt public open [BODY_RESOLVE] class resolveMe : R|C| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctions.txt b/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctions.txt index 02b03939c5c..0da8c5b0c4f 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctions.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctions.txt @@ -41,9 +41,19 @@ FILE: topLevelFunctions.kt public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: topLevelFunctions.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } + ARGUMENTS_OF_ANNOTATIONS: FILE: topLevelFunctions.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } @@ -71,14 +81,6 @@ FILE: topLevelFunctions.kt public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } -EXPECT_ACTUAL_MATCHING: -FILE: topLevelFunctions.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(functionWithLazyBody#()) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } - BODY_RESOLVE: FILE: topLevelFunctions.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithExpressionBodyAndExplicitType.txt b/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithExpressionBodyAndExplicitType.txt index 27ea44e34ba..53b92840e30 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithExpressionBodyAndExplicitType.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithExpressionBodyAndExplicitType.txt @@ -41,9 +41,19 @@ FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } + ARGUMENTS_OF_ANNOTATIONS: FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } @@ -71,14 +81,6 @@ FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } -EXPECT_ACTUAL_MATCHING: -FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(functionWithLazyBody#()) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] fun functionWithLazyBody(): String { LAZY_BLOCK } - BODY_RESOLVE: FILE: topLevelFunctionsWithExpressionBodyAndExplicitType.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithImplicitType.txt b/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithImplicitType.txt index e33feff1072..f118db13118 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithImplicitType.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/topLevelFunctionsWithImplicitType.txt @@ -41,9 +41,19 @@ FILE: topLevelFunctionsWithImplicitType.kt public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: topLevelFunctionsWithImplicitType.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } + public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } + public? final? [RAW_FIR] fun functionWithLazyBody(): { LAZY_BLOCK } + ARGUMENTS_OF_ANNOTATIONS: FILE: topLevelFunctionsWithImplicitType.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { + receive#(functionWithLazyBody#()) + } public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): { LAZY_BLOCK } @@ -71,14 +81,6 @@ FILE: topLevelFunctionsWithImplicitType.kt public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun functionWithLazyBody(): { LAZY_BLOCK } -EXPECT_ACTUAL_MATCHING: -FILE: topLevelFunctionsWithImplicitType.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe(): R|kotlin/Unit| { - receive#(functionWithLazyBody#()) - } - public? final? [RAW_FIR] fun receive([RAW_FIR] value: String): R|kotlin/Unit| { LAZY_BLOCK } - public? final? [RAW_FIR] fun functionWithLazyBody(): { LAZY_BLOCK } - BODY_RESOLVE: FILE: topLevelFunctionsWithImplicitType.kt public final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/typeAliases/typeAliasWithTypeParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/typeAliases/typeAliasWithTypeParameters.txt index cc058be70ac..3e2c296ee3d 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/typeAliases/typeAliasWithTypeParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/typeAliases/typeAliasWithTypeParameters.txt @@ -27,6 +27,10 @@ STATUS: FILE: typeAliasWithTypeParameters.kt public final [STATUS] typealias ResolveMe<[STATUS] T : R|kotlin/Int|, [STATUS] K> = R|kotlin/collections/Map| +EXPECT_ACTUAL_MATCHING: +FILE: typeAliasWithTypeParameters.kt + public final [EXPECT_ACTUAL_MATCHING] typealias ResolveMe<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> = R|kotlin/collections/Map| + ARGUMENTS_OF_ANNOTATIONS: FILE: typeAliasWithTypeParameters.kt public final [ARGUMENTS_OF_ANNOTATIONS] typealias ResolveMe<[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K> = R|kotlin/collections/Map| @@ -43,10 +47,6 @@ ANNOTATIONS_ARGUMENTS_MAPPING: FILE: typeAliasWithTypeParameters.kt public final [ANNOTATIONS_ARGUMENTS_MAPPING] typealias ResolveMe<[ANNOTATIONS_ARGUMENTS_MAPPING] T : R|kotlin/Int|, [ANNOTATIONS_ARGUMENTS_MAPPING] K> = R|kotlin/collections/Map| -EXPECT_ACTUAL_MATCHING: -FILE: typeAliasWithTypeParameters.kt - public final [EXPECT_ACTUAL_MATCHING] typealias ResolveMe<[EXPECT_ACTUAL_MATCHING] T : R|kotlin/Int|, [EXPECT_ACTUAL_MATCHING] K> = R|kotlin/collections/Map| - BODY_RESOLVE: FILE: typeAliasWithTypeParameters.kt public final [BODY_RESOLVE] typealias ResolveMe<[BODY_RESOLVE] T : R|kotlin/Int|, [BODY_RESOLVE] K> = R|kotlin/collections/Map| diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterBounds.txt b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterBounds.txt index d8fcb85a887..f263e0c8dbd 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterBounds.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterBounds.txt @@ -62,9 +62,22 @@ FILE: typeParameterBounds.kt } public? final? [RAW_FIR] fun <[RAW_FIR] F : Foo, [RAW_FIR] B : Bar> F.util(): B { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: typeParameterBounds.kt + public final [EXPECT_ACTUAL_MATCHING] fun resolveMe([EXPECT_ACTUAL_MATCHING] foo: R|Foo|): R|kotlin/Unit| { + foo#.util#() + } + public? final? [RAW_FIR] interface Foo : R|kotlin/Any| { + } + public? final? [RAW_FIR] interface Bar<[RAW_FIR] T : Foo> : R|kotlin/Any| { + } + public? final? [RAW_FIR] fun <[RAW_FIR] F : Foo, [RAW_FIR] B : Bar> F.util(): B { LAZY_BLOCK } + ARGUMENTS_OF_ANNOTATIONS: FILE: typeParameterBounds.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe([ARGUMENTS_OF_ANNOTATIONS] foo: R|Foo|): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe([ARGUMENTS_OF_ANNOTATIONS] foo: R|Foo|): R|kotlin/Unit| { + foo#.util#() + } public? final? [RAW_FIR] interface Foo : R|kotlin/Any| { } public? final? [RAW_FIR] interface Bar<[RAW_FIR] T : Foo> : R|kotlin/Any| { @@ -104,17 +117,6 @@ FILE: typeParameterBounds.kt } public? final? [RAW_FIR] fun <[RAW_FIR] F : Foo, [RAW_FIR] B : Bar> F.util(): B { LAZY_BLOCK } -EXPECT_ACTUAL_MATCHING: -FILE: typeParameterBounds.kt - public final [EXPECT_ACTUAL_MATCHING] fun resolveMe([EXPECT_ACTUAL_MATCHING] foo: R|Foo|): R|kotlin/Unit| { - foo#.util#() - } - public? final? [RAW_FIR] interface Foo : R|kotlin/Any| { - } - public? final? [RAW_FIR] interface Bar<[RAW_FIR] T : Foo> : R|kotlin/Any| { - } - public? final? [RAW_FIR] fun <[RAW_FIR] F : Foo, [RAW_FIR] B : Bar> F.util(): B { LAZY_BLOCK } - BODY_RESOLVE: FILE: typeParameterBounds.kt public final [BODY_RESOLVE] fun resolveMe([BODY_RESOLVE] foo: R|Foo|): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfNonLocalFunction.txt b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfNonLocalFunction.txt index 7d504056e90..d28a6436af2 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfNonLocalFunction.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfNonLocalFunction.txt @@ -76,6 +76,18 @@ FILE: typeParameterOfNonLocalFunction.kt } +EXPECT_ACTUAL_MATCHING: +FILE: typeParameterOfNonLocalFunction.kt + public final [SUPER_TYPES] class X : R|kotlin/Any| { + public [TYPES] [ContainingClassKey=X] constructor(): R|X| { + LAZY_super + } + + public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] resolveMe> ddd(): R|kotlin/Unit| { + } + + } + ARGUMENTS_OF_ANNOTATIONS: FILE: typeParameterOfNonLocalFunction.kt public final [STATUS] class X : R|kotlin/Any| { @@ -83,7 +95,8 @@ FILE: typeParameterOfNonLocalFunction.kt LAZY_super } - public final [ARGUMENTS_OF_ANNOTATIONS] fun <[ARGUMENTS_OF_ANNOTATIONS] resolveMe> ddd(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun <[ARGUMENTS_OF_ANNOTATIONS] resolveMe> ddd(): R|kotlin/Unit| { + } } @@ -123,18 +136,6 @@ FILE: typeParameterOfNonLocalFunction.kt } -EXPECT_ACTUAL_MATCHING: -FILE: typeParameterOfNonLocalFunction.kt - public final [STATUS] class X : R|kotlin/Any| { - public [STATUS] [ContainingClassKey=X] constructor(): R|X| { - LAZY_super - } - - public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] resolveMe> ddd(): R|kotlin/Unit| { - } - - } - BODY_RESOLVE: FILE: typeParameterOfNonLocalFunction.kt public final [STATUS] class X : R|kotlin/Any| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopFunction.txt b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopFunction.txt index 511e8d477bc..fe0f804e21c 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopFunction.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopFunction.txt @@ -27,9 +27,15 @@ STATUS: FILE: typeParameterOfTopFunction.kt public final [STATUS] fun <[STATUS] resolveMe> ddd(): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: typeParameterOfTopFunction.kt + public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] resolveMe> ddd(): R|kotlin/Unit| { + } + ARGUMENTS_OF_ANNOTATIONS: FILE: typeParameterOfTopFunction.kt - public final [ARGUMENTS_OF_ANNOTATIONS] fun <[ARGUMENTS_OF_ANNOTATIONS] resolveMe> ddd(): R|kotlin/Unit| { LAZY_BLOCK } + public final [ARGUMENTS_OF_ANNOTATIONS] fun <[ARGUMENTS_OF_ANNOTATIONS] resolveMe> ddd(): R|kotlin/Unit| { + } CONTRACTS: FILE: typeParameterOfTopFunction.kt @@ -46,11 +52,6 @@ FILE: typeParameterOfTopFunction.kt public final [ANNOTATIONS_ARGUMENTS_MAPPING] fun <[ANNOTATIONS_ARGUMENTS_MAPPING] resolveMe> ddd(): R|kotlin/Unit| { } -EXPECT_ACTUAL_MATCHING: -FILE: typeParameterOfTopFunction.kt - public final [EXPECT_ACTUAL_MATCHING] fun <[EXPECT_ACTUAL_MATCHING] resolveMe> ddd(): R|kotlin/Unit| { - } - BODY_RESOLVE: FILE: typeParameterOfTopFunction.kt public final [BODY_RESOLVE] fun <[BODY_RESOLVE] resolveMe> ddd(): R|kotlin/Unit| { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopSetter.txt b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopSetter.txt index b89281cef75..c176fb2f2f7 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopSetter.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/typeParameterOfTopSetter.txt @@ -41,11 +41,21 @@ FILE: typeParameterOfTopSetter.kt public [STATUS] get(): R|kotlin/Int| public [STATUS] set([STATUS] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { LAZY_BLOCK } +EXPECT_ACTUAL_MATCHING: +FILE: typeParameterOfTopSetter.kt + public final [EXPECT_ACTUAL_MATCHING] var x: R|kotlin/Int| = IntegerLiteral(2) + public [EXPECT_ACTUAL_MATCHING] get(): R|kotlin/Int| + public [EXPECT_ACTUAL_MATCHING] set([EXPECT_ACTUAL_MATCHING] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { + ^ Unit# + } + ARGUMENTS_OF_ANNOTATIONS: FILE: typeParameterOfTopSetter.kt - public final [ARGUMENTS_OF_ANNOTATIONS] var x: R|kotlin/Int| = LAZY_EXPRESSION + public final [ARGUMENTS_OF_ANNOTATIONS] var x: R|kotlin/Int| = IntegerLiteral(2) public [ARGUMENTS_OF_ANNOTATIONS] get(): R|kotlin/Int| - public [ARGUMENTS_OF_ANNOTATIONS] set([ARGUMENTS_OF_ANNOTATIONS] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { LAZY_BLOCK } + public [ARGUMENTS_OF_ANNOTATIONS] set([ARGUMENTS_OF_ANNOTATIONS] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { + ^ Unit# + } CONTRACTS: FILE: typeParameterOfTopSetter.kt @@ -71,14 +81,6 @@ FILE: typeParameterOfTopSetter.kt ^ Unit# } -EXPECT_ACTUAL_MATCHING: -FILE: typeParameterOfTopSetter.kt - public final [EXPECT_ACTUAL_MATCHING] var x: R|kotlin/Int| = IntegerLiteral(2) - public [EXPECT_ACTUAL_MATCHING] get(): R|kotlin/Int| - public [EXPECT_ACTUAL_MATCHING] set([EXPECT_ACTUAL_MATCHING] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { - ^ Unit# - } - BODY_RESOLVE: FILE: typeParameterOfTopSetter.kt public final [BODY_RESOLVE] var x: R|kotlin/Int| = Int(2) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 2454e1da86f..07c7970a122 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -32,6 +32,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirAnnotationChecker, FirPublishedApiChecker, FirOptInMarkedDeclarationChecker, + FirActualDeclarationChecker, ) override val callableDeclarationCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualCallableDeclarationChecker.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt new file mode 100644 index 00000000000..4b2a2640455 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isActual +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility + +object FirActualDeclarationChecker : FirBasicDeclarationChecker() { + override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration !is FirMemberDeclaration || !declaration.isActual) return + + if (declaration is FirCallableDeclaration) { + val actualFunctionSymbol = declaration.symbol + val expectFunctionSymbol = actualFunctionSymbol.getSingleCompatibleExpectForActualOrNull() as? FirCallableSymbol ?: return + + val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session) + ?.typeParameterSymbols.orEmpty() + val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty() + val parentSubstitutor = + createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualClassTypeParameters, context.session) + + val substitutor = createExpectActualTypeParameterSubstitutor( + expectFunctionSymbol.typeParameterSymbols, + actualFunctionSymbol.typeParameterSymbols, + context.session, + parentSubstitutor + ) + + if (!areCompatibleExpectActualTypes( + substitutor.substituteOrSelf(expectFunctionSymbol.resolvedReturnType.type), + actualFunctionSymbol.resolvedReturnType.type, + expectFunctionSymbol.moduleData.session, + context.session + ) + ) { + @Suppress("UNCHECKED_CAST") + reporter.reportOn( + declaration.source, + FirErrors.ACTUAL_WITHOUT_EXPECT, + actualFunctionSymbol, + actualFunctionSymbol.expectForActual as Map>, Collection>>, + context + ) + } + } + } +} \ No newline at end of file diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt new file mode 100644 index 00000000000..281f344ffea --- /dev/null +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ExpectActualUtils.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.types + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap +import org.jetbrains.kotlin.fir.resolve.substitution.chain +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.types.AbstractTypeChecker + +fun createExpectActualTypeParameterSubstitutor( + expectedTypeParameters: List, + actualTypeParameters: List, + useSiteSession: FirSession, + parentSubstitutor: ConeSubstitutor? = null +): ConeSubstitutor { + val substitution = expectedTypeParameters.zip(actualTypeParameters).associate { (expectedParameterSymbol, actualParameterSymbol) -> + expectedParameterSymbol to actualParameterSymbol.toLookupTag().constructType(emptyArray(), isNullable = false) + } + val substitutor = ConeSubstitutorByMap( + substitution, + useSiteSession + ) + if (parentSubstitutor == null) { + return substitutor + } + return substitutor.chain(parentSubstitutor) +} + +fun areCompatibleExpectActualTypes( + expectedType: ConeKotlinType?, + actualType: ConeKotlinType?, + actualSession: FirSession +): Boolean { + if (expectedType == null) return actualType == null + if (actualType == null) return false + + return AbstractTypeChecker.equalTypes( + actualSession.typeContext, + expectedType, + actualType + ) +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt index 03b230c4a1a..edad2d0b80f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt @@ -7,12 +7,11 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSessionComponent -import org.jetbrains.kotlin.fir.declarations.FirFunction -import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction -import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol class FirDefaultParametersResolver : FirSessionComponent { fun declaresDefaultValue( @@ -23,7 +22,9 @@ class FirDefaultParametersResolver : FirSessionComponent { originScope: FirScope?, index: Int, ): Boolean { - if (valueParameter.defaultValue != null) return true + if (valueParameter.defaultValue != null || containsDefaultValue(function.symbol.getSingleCompatibleExpectForActualOrNull(), index)) { + return true + } if (function !is FirSimpleFunction) return false val symbol = function.symbol val typeScope = when (originScope) { @@ -43,7 +44,11 @@ class FirDefaultParametersResolver : FirSessionComponent { var result = false typeScope.processOverriddenFunctions(symbol) { overridden -> - if (overridden.fir.valueParameters[index].defaultValue != null) { + if (containsDefaultValue(overridden, index) || containsDefaultValue( + overridden.getSingleCompatibleExpectForActualOrNull(), + index + ) + ) { result = true return@processOverriddenFunctions ProcessorAction.STOP } @@ -53,6 +58,11 @@ class FirDefaultParametersResolver : FirSessionComponent { return result } + + private fun containsDefaultValue(functionSymbol: FirFunctionSymbol<*>?, index: Int): Boolean { + if (functionSymbol == null) return false + return functionSymbol.fir.valueParameters[index].defaultValue != null + } } internal val FirSession.defaultParameterResolver: FirDefaultParametersResolver by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt index ef5432b30cb..9b80ff5ab54 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt @@ -16,18 +16,13 @@ import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap -import org.jetbrains.kotlin.fir.resolve.substitution.chain import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope -import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility -import org.jetbrains.kotlin.types.AbstractTypeChecker -import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.enumMapOf @@ -60,7 +55,7 @@ object FirExpectActualResolver { val actualTypeParameters = actualContainingClass ?.typeParameterSymbols .orEmpty() - parentSubstitutor = createTypeParameterSubstitutor(expectTypeParameters, actualTypeParameters, useSiteSession) + parentSubstitutor = createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualTypeParameters, useSiteSession) when (actualSymbol) { is FirConstructorSymbol -> expectContainingClass?.getConstructors(scopeSession) else -> expectContainingClass?.getMembers(callableId.callableName, scopeSession) @@ -137,10 +132,9 @@ object FirExpectActualResolver { return ExpectActualCompatibility.Incompatible.Visibility } - val substitutor = createTypeParameterSubstitutor(expectTypeParameterSymbols, actualTypeParameterSymbols, actualSession) + val substitutor = createExpectActualTypeParameterSubstitutor(expectTypeParameterSymbols, actualTypeParameterSymbols, actualSession) - val expectSession = expectClassSymbol.moduleData.session - areCompatibleTypeParameters(expectTypeParameterSymbols, actualTypeParameterSymbols, actualSession, expectSession, substitutor).let { + areCompatibleTypeParameters(expectTypeParameterSymbols, actualTypeParameterSymbols, actualSession, substitutor).let { if (it != ExpectActualCompatibility.Compatible) { return it } @@ -153,7 +147,7 @@ object FirExpectActualResolver { if ( expectSupertypes.map(substitutor::substituteOrSelf).any { expectSupertype -> actualSupertypes.none { actualSupertype -> - areCompatibleTypes(expectSupertype, actualSupertype, expectSession, actualSession) + areCompatibleExpectActualTypes(expectSupertype, actualSupertype, actualSession) } } ) { @@ -258,8 +252,6 @@ object FirExpectActualResolver { "This function should be invoked only for declarations in the same kind of container (both members or both top level): $expectDeclaration, $actualDeclaration" } - val expectSession = expectDeclaration.moduleData.session - if ( expectDeclaration is FirConstructorSymbol && actualDeclaration is FirConstructorSymbol && @@ -291,34 +283,22 @@ object FirExpectActualResolver { return ExpectActualCompatibility.Incompatible.TypeParameterCount } - val substitutor = createTypeParameterSubstitutor(expectedTypeParameters, actualTypeParameters, actualSession, parentSubstitutor) + val substitutor = createExpectActualTypeParameterSubstitutor(expectedTypeParameters, actualTypeParameters, actualSession, parentSubstitutor) if ( !areCompatibleTypeLists( expectedValueParameters.toTypeList(substitutor), actualValueParameters.toTypeList(ConeSubstitutor.Empty), - expectSession, actualSession ) || - !areCompatibleTypes( + !areCompatibleExpectActualTypes( expectedReceiverType?.coneType?.let { substitutor.substituteOrSelf(it) }, actualReceiverType?.coneType, - expectSession, actualSession ) ) { return ExpectActualCompatibility.Incompatible.ParameterTypes } - if ( - !areCompatibleTypes( - substitutor.substituteOrSelf(expectDeclaration.resolvedReturnTypeRef.coneType), - actualDeclaration.resolvedReturnTypeRef.coneType, - expectSession, - actualSession - ) - ) { - return ExpectActualCompatibility.Incompatible.ReturnType - } // TODO: implement hasStableParameterNames calculation // if (actualDeclaration.hasStableParameterNames() && !equalsBy(expectedValueParameters, actualValueParameters, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames @@ -344,7 +324,7 @@ object FirExpectActualResolver { return ExpectActualCompatibility.Incompatible.Visibility } - areCompatibleTypeParameters(expectedTypeParameters, actualTypeParameters, actualSession, expectSession, substitutor).let { + areCompatibleTypeParameters(expectedTypeParameters, actualTypeParameters, actualSession, substitutor).let { if (it != ExpectActualCompatibility.Compatible) { return it } @@ -386,25 +366,6 @@ object FirExpectActualResolver { return ExpectActualCompatibility.Compatible } - private fun createTypeParameterSubstitutor( - expectedTypeParameters: List, - actualTypeParameters: List, - useSiteSession: FirSession, - parentSubstitutor: ConeSubstitutor? = null - ): ConeSubstitutor { - val substitution = expectedTypeParameters.zip(actualTypeParameters).associate { (expectedParameterSymbol, actualParameterSymbol) -> - expectedParameterSymbol to actualParameterSymbol.toLookupTag().constructType(emptyArray(), isNullable = false) - } - val substitutor = ConeSubstitutorByMap( - substitution, - useSiteSession - ) - if (parentSubstitutor == null) { - return substitutor - } - return substitutor.chain(parentSubstitutor) - } - private fun valueParametersCountCompatible( expectDeclaration: FirCallableSymbol<*>, actualDeclaration: FirCallableSymbol<*>, @@ -426,37 +387,16 @@ object FirExpectActualResolver { private fun areCompatibleTypeLists( expectedTypes: List, actualTypes: List, - expectSession: FirSession, actualSession: FirSession ): Boolean { for (i in expectedTypes.indices) { - if (!areCompatibleTypes(expectedTypes[i], actualTypes[i], expectSession, actualSession)) { + if (!areCompatibleExpectActualTypes(expectedTypes[i], actualTypes[i], actualSession)) { return false } } return true } - private fun areCompatibleTypes( - expectedType: ConeKotlinType?, - actualType: ConeKotlinType?, - expectSession: FirSession, - actualSession: FirSession - ): Boolean { - if (expectedType == null) return actualType == null - if (actualType == null) return false - - val typeCheckerContext = ConeInferenceContextForExpectActual(expectSession, actualSession).newTypeCheckerState( - errorTypesEqualToAnything = false, - stubTypesEqualToAnything = true - ) - return AbstractTypeChecker.equalTypes( - typeCheckerContext, - expectedType, - actualType - ) - } - private fun areCompatibleModalities( expectModality: Modality?, actualModality: Modality?, @@ -508,7 +448,6 @@ object FirExpectActualResolver { expectTypeParameterSymbols: List, actualTypeParameterSymbols: List, actualSession: FirSession, - expectSession: FirSession, substitutor: ConeSubstitutor ): ExpectActualCompatibility> { for (i in expectTypeParameterSymbols.indices) { @@ -516,7 +455,7 @@ object FirExpectActualResolver { val actualBounds = actualTypeParameterSymbols[i].resolvedBounds.map { it.coneType } if ( expectBounds.size != actualBounds.size || - !areCompatibleTypeLists(expectBounds.map(substitutor::substituteOrSelf), actualBounds, expectSession, actualSession) + !areCompatibleTypeLists(expectBounds.map(substitutor::substituteOrSelf), actualBounds, actualSession) ) { return ExpectActualCompatibility.Incompatible.TypeParameterUpperBounds } @@ -573,44 +512,6 @@ object FirExpectActualResolver { // ---------------------------------------- Utils ---------------------------------------- - private class ConeInferenceContextForExpectActual(val expectSession: FirSession, val actualSession: FirSession) : ConeInferenceContext { - override val session: FirSession - get() = actualSession - - override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean { - if (c1 !is ConeClassifierLookupTag || c2 !is ConeClassifierLookupTag) { - return c1 == c2 - } - return isExpectedClassAndActualTypeAlias(c1, c2) || - isExpectedClassAndActualTypeAlias(c2, c1) || - c1 == c2 - } - - // For example, expectedTypeConstructor may be the expected class kotlin.text.StringBuilder, while actualTypeConstructor - // is java.lang.StringBuilder. For the purposes of type compatibility checking, we must consider these types equal here. - // Note that the case of an "actual class" works as expected though, because the actual class by definition has the same FQ name - // as the corresponding expected class, so their type constructors are equal as per AbstractClassTypeConstructor#equals - private fun isExpectedClassAndActualTypeAlias( - expectLookupTag: ConeClassifierLookupTag, - actualLookupTag: ConeClassifierLookupTag - ): Boolean { - val expectDeclaration = expectLookupTag.toClassLikeDeclaration(expectSession) ?: return false - val actualDeclaration = actualLookupTag.toClassLikeDeclaration(actualSession) ?: return false - - if (!expectDeclaration.isExpect) return false - val expectClassId = when (expectDeclaration) { - is FirRegularClassSymbol -> expectDeclaration.classId - is FirTypeAliasSymbol -> expectDeclaration.resolvedExpandedTypeRef.coneType.classId - else -> null - } ?: return false - return expectClassId == actualDeclaration.classId - } - - private fun ConeClassifierLookupTag.toClassLikeDeclaration(session: FirSession): FirClassLikeSymbol<*>? { - return this.toSymbol(session) as? FirClassLikeSymbol<*> - } - } - private fun List.toTypeList(substitutor: ConeSubstitutor): List { return this.map { substitutor.substituteOrSelf(it.resolvedReturnTypeRef.coneType) } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/ExpectActualAttributes.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/ExpectActualAttributes.kt index dbb1c2ca53d..433c22a3c43 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/ExpectActualAttributes.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/ExpectActualAttributes.kt @@ -8,8 +8,10 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility +import org.jetbrains.kotlin.resolve.multiplatform.compatible import java.util.* private object ExpectForActualAttributeKey : FirDeclarationDataKey() @@ -21,6 +23,24 @@ typealias ExpectForActualData = Map> var FirDeclaration.expectForActual: ExpectForActualData? by FirDeclarationDataRegistry.data(ExpectForActualAttributeKey) private var FirDeclaration.actualForExpectMap: WeakHashMap>? by FirDeclarationDataRegistry.data(ActualForExpectAttributeKey) +fun FirFunctionSymbol<*>.getSingleCompatibleExpectForActualOrNull() = + (this as FirBasedSymbol<*>).getSingleCompatibleExpectForActualOrNull() as? FirFunctionSymbol<*> + +fun FirBasedSymbol<*>.getSingleCompatibleExpectForActualOrNull(): FirBasedSymbol<*>? { + val expectForActual = expectForActual ?: return null + var compatibleActuals: List>? = null + for ((key, item) in expectForActual) { + if (key.compatible) { + if (compatibleActuals == null) { + compatibleActuals = item + } else { + return null // Exit if there are more than one list with compatible actuals + } + } + } + return compatibleActuals?.singleOrNull() +} + val FirBasedSymbol<*>.expectForActual: ExpectForActualData? get() { lazyResolveToPhase(FirResolvePhase.EXPECT_ACTUAL_MATCHING) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt index c70887906ff..edc379e3daa 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt @@ -14,11 +14,11 @@ enum class FirResolvePhase(val noProcessor: Boolean = false) { SEALED_CLASS_INHERITORS, TYPES, STATUS, + EXPECT_ACTUAL_MATCHING, ARGUMENTS_OF_ANNOTATIONS, CONTRACTS, IMPLICIT_TYPES_BODY_RESOLVE, ANNOTATIONS_ARGUMENTS_MAPPING, - EXPECT_ACTUAL_MATCHING, BODY_RESOLVE; val requiredToLaunch: FirResolvePhase diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt index 6a918dbe2f2..c534d23984d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/ExpectActualCollector.kt @@ -173,13 +173,13 @@ private class CallablesLinkCollector( private fun addLink(declaration: IrDeclarationBase) { if (!declaration.isExpect) return - val member = actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)] - if (member != null) { - expectActualMap[declaration.symbol] = member.symbol + val actualMember = actualMembers[generateIrElementFullName(declaration, expectActualMap, typeAliasMap)] + if (actualMember != null) { + expectActualMap[declaration.symbol] = actualMember.symbol if (declaration is IrProperty) { - member as IrProperty - declaration.getter?.symbol?.let { expectActualMap[it] = member.getter!!.symbol } - declaration.setter?.symbol?.let { expectActualMap[it] = member.setter!!.symbol } + val actualProperty = actualMember as IrProperty + declaration.getter?.symbol?.let { expectActualMap[it] = actualProperty.getter!!.symbol } + declaration.setter?.symbol?.let { expectActualMap[it] = actualProperty.setter!!.symbol } } } else { reportMissingActual(declaration) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/FunctionDefaultParametersActualizer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/FunctionDefaultParametersActualizer.kt new file mode 100644 index 00000000000..1748cd70ee2 --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/FunctionDefaultParametersActualizer.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.common.actualizer + +import org.jetbrains.kotlin.backend.common.lower.copyAndActualizeDefaultValue +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbol + +class FunctionDefaultParametersActualizer(private val expectActualMap: Map) { + fun actualize() { + for ((expect, actual) in expectActualMap) { + if (expect is IrFunctionSymbol) { + actualize(expect.owner, (actual as IrFunctionSymbol).owner) + } + } + } + + private fun actualize(expectFunction: IrFunction, actualFunction: IrFunction) { + expectFunction.valueParameters.zip(actualFunction.valueParameters).forEach { (expectParameter, actualParameter) -> + val expectDefaultValue = expectParameter.defaultValue + if (actualParameter.defaultValue == null && expectDefaultValue != null) { + actualParameter.defaultValue = expectDefaultValue.copyAndActualizeDefaultValue( + actualFunction, + actualParameter, + mapOf(), + classActualizer = { (expectActualMap[it.symbol] as IrClassSymbol).owner }, + functionActualizer = { (expectActualMap[it.symbol] as IrFunctionSymbol).owner } + ) + } + } + } +} \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt index e591ef89b58..83324ee8b81 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrActualizer.kt @@ -6,20 +6,21 @@ package org.jetbrains.kotlin.backend.common.actualizer import org.jetbrains.kotlin.backend.common.ir.isProperExpect -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.name.FqName object IrActualizer { fun actualize(mainFragment: IrModuleFragment, dependentFragments: List) { val (expectActualMap, typeAliasMap) = ExpectActualCollector(mainFragment, dependentFragments).collect() - removeExpectDeclaration(dependentFragments) // TODO: consider removing this call. See ExpectDeclarationRemover.kt + FunctionDefaultParametersActualizer(expectActualMap).actualize() + removeExpectDeclarations(dependentFragments) addMissingFakeOverrides(expectActualMap, dependentFragments, typeAliasMap) linkExpectToActual(expectActualMap, dependentFragments) mergeIrFragments(mainFragment, dependentFragments) } - private fun removeExpectDeclaration(dependentFragments: List) { + private fun removeExpectDeclarations(dependentFragments: List) { for (fragment in dependentFragments) { for (file in fragment.files) { file.declarations.removeAll { it.isProperExpect } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt index e71a22ad04a..f00c41db1ee 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt @@ -12,13 +12,9 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrGetValue -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.extractTypeParameters import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil import org.jetbrains.kotlin.resolve.multiplatform.findCompatibleActualsForExpected @@ -153,16 +149,13 @@ open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, priva } defaultValue.let { originalDefault -> - declaration.defaultValue = declaration.factory.createExpressionBody(originalDefault.startOffset, originalDefault.endOffset) { - expression = originalDefault.expression - .deepCopyWithSymbols(function) { symbolRemapper, _ -> - DeepCopyIrTreeWithSymbols( - symbolRemapper, - IrTypeParameterRemapper(typeParameterSubstitutionMap.getValue(expectToActual)) - ) - } - .remapExpectValueSymbols() - } + declaration.defaultValue = originalDefault.copyAndActualizeDefaultValue( + function, + declaration, + typeParameterSubstitutionMap.getValue(expectToActual), + classActualizer = { symbolTable.referenceClass(it.descriptor.findActualForExpect() as ClassDescriptor).owner }, + functionActualizer = { symbolTable.referenceFunction(it.descriptor.findActualForExpect() as FunctionDescriptor).owner } + ) } } @@ -170,55 +163,4 @@ open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, priva if (!isActual) error(this) return findCompatibleExpectsForActual().singleOrNull() } - - private fun IrExpression.remapExpectValueSymbols(): IrExpression { - return this.transform(object : IrElementTransformerVoid() { - - override fun visitGetValue(expression: IrGetValue): IrExpression { - expression.transformChildrenVoid() - val newValue = remapExpectValue(expression.symbol) - ?: return expression - - return IrGetValueImpl( - expression.startOffset, - expression.endOffset, - newValue.type, - newValue.symbol, - expression.origin - ) - } - }, data = null) - } - - private fun remapExpectValue(symbol: IrValueSymbol): IrValueParameter? { - if (symbol !is IrValueParameterSymbol) { - return null - } - - val parameter = symbol.owner - - return when (val parent = parameter.parent) { - is IrClass -> { - assert(parameter == parent.thisReceiver) - symbolTable.referenceClass(parent.descriptor.findActualForExpect() as ClassDescriptor).owner.thisReceiver!! - } - - is IrFunction -> { - val actualFunction = - symbolTable.referenceFunction(parent.descriptor.findActualForExpect() as FunctionDescriptor).owner - when (parameter) { - parent.dispatchReceiverParameter -> - actualFunction.dispatchReceiverParameter!! - parent.extensionReceiverParameter -> - actualFunction.extensionReceiverParameter!! - else -> { - assert(parent.valueParameters[parameter.index] == parameter) - actualFunction.valueParameters[parameter.index] - } - } - } - - else -> error(parent) - } - } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt index 37792ee7888..e44af59681f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt @@ -17,9 +17,14 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol +import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrFail +import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols +import org.jetbrains.kotlin.ir.util.IrTypeParameterRemapper +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -215,3 +220,61 @@ fun ParameterDescriptor.copyAsValueParameter(newOwner: CallableDescriptor, index ) else -> throw Error("Unexpected parameter descriptor: $this") } + +fun IrExpressionBody.copyAndActualizeDefaultValue( + actualFunction: IrFunction, + actualValueParameter: IrValueParameter, + expectActualTypeParametersMap: Map, + classActualizer: (IrClass) -> IrClass, + functionActualizer: (IrFunction) -> IrFunction +) = actualValueParameter.factory.createExpressionBody(startOffset, endOffset) { + expression = this@copyAndActualizeDefaultValue.expression + .deepCopyWithSymbols(actualFunction) { symbolRemapper, _ -> + DeepCopyIrTreeWithSymbols(symbolRemapper, IrTypeParameterRemapper(expectActualTypeParametersMap)) + } + .transform(object : IrElementTransformerVoid() { + override fun visitGetValue(expression: IrGetValue): IrExpression { + expression.transformChildrenVoid() + val newValue = remapExpectValue(expression.symbol) ?: return expression + + return IrGetValueImpl( + expression.startOffset, + expression.endOffset, + newValue.type, + newValue.symbol, + expression.origin + ) + } + + private fun remapExpectValue(symbol: IrValueSymbol): IrValueParameter? { + if (symbol !is IrValueParameterSymbol) { + return null + } + + val parameter = symbol.owner + + return when (val parent = parameter.parent) { + is IrClass -> { + assert(parameter == parent.thisReceiver) + classActualizer(parent).thisReceiver!! + } + + is IrFunction -> { + val function = functionActualizer(parent) + when (parameter) { + parent.dispatchReceiverParameter -> function.dispatchReceiverParameter!! + parent.extensionReceiverParameter -> function.extensionReceiverParameter!! + else -> { + assert(parent.valueParameters[parameter.index] == parameter) + function.valueParameters[parameter.index] + } + } + } + + else -> error(parent) + } + } + }, data = null) +} + + diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt index a6d18f5f0b4..0560c5f210c 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects // IGNORE_BACKEND_K2: JVM_IR, JS_IR -// FIR status: default argument mapping in MPP isn't designed yet // TARGET_BACKEND: JVM // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt index d30f7921e25..23b3cb3b601 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/delegatedExpectedInterface.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/delegatedExpectedInterface.kt index 7c49ff74ccc..369b5353185 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/delegatedExpectedInterface.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/delegatedExpectedInterface.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // FILE: lib.kt expect interface I { diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt index df703ab58ef..26e86cfb137 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/function.kt @@ -1,5 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE +// IGNORE_BACKEND_K2: NATIVE // FIR status: default argument mapping in MPP isn't designed yet // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt index d51298b3225..5402f4947ff 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedClass.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt index 239433741be..7362356f9b1 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedInterface.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // FILE: lib.kt expect interface I { diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedMethod.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedMethod.kt index 43aaefa5fc5..c7eca8852ec 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedMethod.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedFromExpectedMethod.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedInExpectedDeclarations.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedInExpectedDeclarations.kt index f505c7ff801..471697f0f3c 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedInExpectedDeclarations.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedInExpectedDeclarations.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedViaAnotherInterfaceIndirectly.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedViaAnotherInterfaceIndirectly.kt index 0940e51ad29..804d06bfa87 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedViaAnotherInterfaceIndirectly.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inheritedViaAnotherInterfaceIndirectly.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // FILE: lib.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt index e6e26bdaccb..d7c25e5a82b 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/inlineFunctionWithDefaultLambda.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/jvmOverloads.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/jvmOverloads.kt index d6067e580ac..d1f6157a25a 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/jvmOverloads.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/jvmOverloads.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +MultiPlatformProjects // IGNORE_BACKEND_K2: JVM_IR, JS_IR -// FIR status: default argument mapping in MPP isn't designed yet +// FIR status: outdated code (expect/actual in the same module) // TARGET_BACKEND: JVM // WITH_STDLIB // FILE: J.java diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23239.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23239.kt index e7d05d0d34b..33f13490961 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23239.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23239.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23739.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23739.kt index 87fd725cb80..3be22a3ed63 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23739.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/kt23739.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE + // FILE: common.kt // A LOT OF LINES diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/parametersInArgumentValues.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/parametersInArgumentValues.kt index 2ca0f2368b5..a450b2f52bf 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/parametersInArgumentValues.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/parametersInArgumentValues.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // FILE: common.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/superCall.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/superCall.kt index dfad9539dbf..d4fce99bfed 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/superCall.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/superCall.kt @@ -3,8 +3,6 @@ // !LANGUAGE: +MultiPlatformProjects // IGNORE_BACKEND: NATIVE // IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND_K2: JS_IR -// FIR status: not supported in JVM // IGNORE_BACKEND: JVM // FILE: lib.kt diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/suspend.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/suspend.kt index ff051b867b3..93af4a70397 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/suspend.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/suspend.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +MultiPlatformProjects -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// IGNORE_BACKEND_K2: NATIVE // WITH_STDLIB // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt index ba54f9ed238..cc0cb5f6e71 100644 --- a/compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt @@ -1,7 +1,7 @@ // !LANGUAGE: +MultiPlatformProjects // IGNORE_BACKEND: WASM // IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE -// FIR status: default argument mapping in MPP isn't designed yet +// FIR status: outdated code (expect/actual in the same module) // WITH_STDLIB // MODULE: lib // FILE: common.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.fir.kt deleted file mode 100644 index f03d431301a..00000000000 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -// MODULE: m1-common -// FILE: common.kt - -expect fun ok(x: Int, y: String = "") - -// MODULE: m2-jvm()()(m1-common) -// FILE: jvm.kt - -actual fun ok(x: Int, y: String) {} - -fun ok(x: Int, y: Long = 1L) {} - -fun test() { - ok(1) -} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.kt index 70bedb5187d..2701c357b70 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedVsNonExpectedWithDefaults.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER // MODULE: m1-common // FILE: common.kt