Support inline functions inside inline classes
This commit is contained in:
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberWithJvmDefaultAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
@@ -446,11 +447,14 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
}
|
||||
is ClassDescriptor -> {
|
||||
val kind =
|
||||
if (DescriptorUtils.isInterface(descriptor) &&
|
||||
innerDescriptor !is ClassDescriptor && !innerDescriptor.isCallableMemberWithJvmDefaultAnnotation()
|
||||
)
|
||||
OwnerKind.DEFAULT_IMPLS
|
||||
else OwnerKind.IMPLEMENTATION
|
||||
when {
|
||||
DescriptorUtils.isInterface(descriptor) && innerDescriptor !is ClassDescriptor &&
|
||||
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation() -> OwnerKind.DEFAULT_IMPLS
|
||||
|
||||
descriptor.isInlineClass() -> OwnerKind.ERASED_INLINE_CLASS
|
||||
|
||||
else -> OwnerKind.IMPLEMENTATION
|
||||
}
|
||||
|
||||
additionalInners.addIfNotNull(
|
||||
InnerClassConsumer.classForInnerClassRecord(descriptor, kind == OwnerKind.DEFAULT_IMPLS)
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class Foo(val x: Int) {
|
||||
inline fun inc(): Foo = Foo(x + 1)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = Foo(0)
|
||||
val b = a.inc().inc()
|
||||
|
||||
if (b.x != 2) return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
inline class A(val x: Int) {
|
||||
inline fun inc(): A = A(this.x + 1)
|
||||
|
||||
inline fun result(other: A): String = if (other.x == x) "OK" else "fail"
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box() : String {
|
||||
val a = A(0)
|
||||
val b = a.inc().inc()
|
||||
val result = b.result(A(2))
|
||||
|
||||
return result
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class Foo(val x: Int) {
|
||||
inline fun inlineInc(): Foo = Foo(x + 1) // one actual call inside wrapper class Foo
|
||||
fun notInlineInc(): Foo = Foo(x + 1)
|
||||
|
||||
fun foo() {
|
||||
inlineInc()
|
||||
}
|
||||
}
|
||||
|
||||
fun test(f: Foo) {
|
||||
f.inlineInc().inlineInc().inlineInc()
|
||||
f.notInlineInc() // one here, one inside wrapper class Foo
|
||||
}
|
||||
|
||||
// 1 INVOKESTATIC Foo\$Erased.inlineInc
|
||||
// 2 INVOKESTATIC Foo\$Erased.notInlineInc
|
||||
Generated
+5
@@ -11088,6 +11088,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineClassAsLastExpressionInInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClass.kt")
|
||||
public void testInlineFunctionInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineFunctionInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||
|
||||
+18
@@ -1586,6 +1586,24 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/inlineClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineClasses extends AbstractIrBlackBoxInlineCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClassesBox.kt")
|
||||
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+18
@@ -1586,6 +1586,24 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/inlineClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineClasses extends AbstractIrCompileKotlinAgainstInlineKotlinTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClassesBox.kt")
|
||||
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+5
@@ -11088,6 +11088,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineClassAsLastExpressionInInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClass.kt")
|
||||
public void testInlineFunctionInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineFunctionInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||
|
||||
+18
@@ -1586,6 +1586,24 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/inlineClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineClasses extends AbstractBlackBoxInlineCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClassesBox.kt")
|
||||
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -2073,6 +2073,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/isCheckForInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noActualCallsOfInlineFunctionsOfInlineClass.kt")
|
||||
public void testNoActualCallsOfInlineFunctionsOfInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noActualCallsOfInlineFunctionsOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noAssertionsForInlineClassesBasedOnNullableTypes.kt")
|
||||
public void testNoAssertionsForInlineClassesBasedOnNullableTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noAssertionsForInlineClassesBasedOnNullableTypes.kt");
|
||||
|
||||
Generated
+18
@@ -1586,6 +1586,24 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/inlineClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineClasses extends AbstractCompileKotlinAgainstInlineKotlinTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClassesBox.kt")
|
||||
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+5
@@ -11088,6 +11088,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineClassAsLastExpressionInInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClass.kt")
|
||||
public void testInlineFunctionInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineFunctionInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||
|
||||
+5
@@ -9645,6 +9645,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineClassAsLastExpressionInInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInsideInlineClass.kt")
|
||||
public void testInlineFunctionInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineFunctionInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||
|
||||
Reference in New Issue
Block a user