Kotlin SAM conversion: tolerate property refs used to implement a SAM interface

This commit is contained in:
Chris Smowton
2022-10-13 17:32:22 +01:00
parent 594812640e
commit 1efcf38a34
5 changed files with 233 additions and 1 deletions

View File

@@ -5036,7 +5036,10 @@ open class KotlinFileExtractor(
return
}
if (!st.isFunctionOrKFunction() && !st.isSuspendFunctionOrKFunction()) {
fun IrSimpleType.isKProperty() =
classFqName?.asString()?.startsWith("kotlin.reflect.KProperty") == true
if (!st.isFunctionOrKFunction() && !st.isSuspendFunctionOrKFunction() && !st.isKProperty()) {
logger.errorElement("Expected to find expression with function type in SAM conversion.", e)
return
}

View File

@@ -6432,6 +6432,120 @@ samConversion.kt:
# 59| -1: [VarAccess] i0
# 59| 0: [IntegerLiteral] 1
# 59| 1: [IntegerLiteral] 2
# 74| 6: [Method] propertyRefsTest
# 74| 3: [TypeAccess] Unit
#-----| 4: (Parameters)
# 74| 0: [Parameter] prt
# 74| 0: [TypeAccess] PropertyRefsTest
# 74| 5: [BlockStmt] { ... }
# 75| 0: [LocalVariableDeclStmt] var ...;
# 75| 1: [LocalVariableDeclExpr] test1
# 75| 0: [CastExpr] (...)...
# 75| 0: [TypeAccess] IntGetter
# 75| 1: [ClassInstanceExpr] new (...)
# 75| -4: [AnonymousClass] new IntGetter(...) { ... }
# 75| 1: [Constructor]
#-----| 4: (Parameters)
# 75| 0: [Parameter] <fn>
# 75| 5: [BlockStmt] { ... }
# 75| 0: [SuperConstructorInvocationStmt] super(...)
# 75| 1: [ExprStmt] <Expr>;
# 75| 0: [AssignExpr] ...=...
# 75| 0: [VarAccess] this.<fn>
# 75| -1: [ThisAccess] this
# 75| 1: [VarAccess] <fn>
# 75| 2: [FieldDeclaration] Function0<Integer> <fn>;
# 75| -1: [TypeAccess] Function0<Integer>
# 75| 0: [TypeAccess] Integer
# 75| 3: [Method] f
# 75| 3: [TypeAccess] int
# 75| 5: [BlockStmt] { ... }
# 75| 0: [ReturnStmt] return ...
# 75| 0: [MethodAccess] invoke(...)
# 75| -1: [VarAccess] <fn>
# 75| -3: [TypeAccess] IntGetter
# 75| 0: [PropertyRefExpr] ...::...
# 75| -4: [AnonymousClass] new KProperty0<Integer>(...) { ... }
# 75| 1: [Constructor]
#-----| 4: (Parameters)
# 75| 0: [Parameter] <dispatchReceiver>
# 75| 5: [BlockStmt] { ... }
# 75| 0: [SuperConstructorInvocationStmt] super(...)
# 75| 1: [ExprStmt] <Expr>;
# 75| 0: [AssignExpr] ...=...
# 75| 0: [VarAccess] this.<dispatchReceiver>
# 75| -1: [ThisAccess] this
# 75| 1: [VarAccess] <dispatchReceiver>
# 75| 2: [FieldDeclaration] PropertyRefsTest <dispatchReceiver>;
# 75| -1: [TypeAccess] PropertyRefsTest
# 75| 3: [Method] get
# 75| 5: [BlockStmt] { ... }
# 75| 0: [ReturnStmt] return ...
# 75| 0: [MethodAccess] getX(...)
# 75| -1: [VarAccess] this.<dispatchReceiver>
# 75| -1: [ThisAccess] this
# 75| 4: [Method] invoke
# 75| 5: [BlockStmt] { ... }
# 75| 0: [ReturnStmt] return ...
# 75| 0: [MethodAccess] get(...)
# 75| -1: [ThisAccess] this
# 75| -3: [TypeAccess] KProperty0<Integer>
# 75| 0: [TypeAccess] Integer
# 75| 0: [VarAccess] prt
# 76| 1: [LocalVariableDeclStmt] var ...;
# 76| 1: [LocalVariableDeclExpr] test2
# 76| 0: [CastExpr] (...)...
# 76| 0: [TypeAccess] PropertyRefsGetter
# 76| 1: [ClassInstanceExpr] new (...)
# 76| -4: [AnonymousClass] new PropertyRefsGetter(...) { ... }
# 76| 1: [Constructor]
#-----| 4: (Parameters)
# 76| 0: [Parameter] <fn>
# 76| 5: [BlockStmt] { ... }
# 76| 0: [SuperConstructorInvocationStmt] super(...)
# 76| 1: [ExprStmt] <Expr>;
# 76| 0: [AssignExpr] ...=...
# 76| 0: [VarAccess] this.<fn>
# 76| -1: [ThisAccess] this
# 76| 1: [VarAccess] <fn>
# 76| 2: [FieldDeclaration] Function1<PropertyRefsTest,Integer> <fn>;
# 76| -1: [TypeAccess] Function1<PropertyRefsTest,Integer>
# 76| 0: [TypeAccess] PropertyRefsTest
# 76| 1: [TypeAccess] Integer
# 76| 3: [Method] f
# 76| 3: [TypeAccess] int
#-----| 4: (Parameters)
# 76| 0: [Parameter] prt
# 76| 0: [TypeAccess] PropertyRefsTest
# 76| 5: [BlockStmt] { ... }
# 76| 0: [ReturnStmt] return ...
# 76| 0: [MethodAccess] invoke(...)
# 76| -1: [VarAccess] <fn>
# 76| 0: [VarAccess] prt
# 76| -3: [TypeAccess] PropertyRefsGetter
# 76| 0: [PropertyRefExpr] ...::...
# 76| -4: [AnonymousClass] new KProperty1<PropertyRefsTest,Integer>(...) { ... }
# 76| 1: [Constructor]
# 76| 5: [BlockStmt] { ... }
# 76| 0: [SuperConstructorInvocationStmt] super(...)
# 76| 2: [Method] get
#-----| 4: (Parameters)
# 76| 0: [Parameter] a0
# 76| 5: [BlockStmt] { ... }
# 76| 0: [ReturnStmt] return ...
# 76| 0: [MethodAccess] getX(...)
# 76| -1: [VarAccess] a0
# 76| 3: [Method] invoke
#-----| 4: (Parameters)
# 76| 0: [Parameter] a0
# 76| 5: [BlockStmt] { ... }
# 76| 0: [ReturnStmt] return ...
# 76| 0: [MethodAccess] get(...)
# 76| -1: [ThisAccess] this
# 76| 0: [VarAccess] a0
# 76| -3: [TypeAccess] KProperty1<PropertyRefsTest,Integer>
# 76| 0: [TypeAccess] PropertyRefsTest
# 76| 1: [TypeAccess] Integer
# 16| 2: [Interface] IntPredicate
# 17| 1: [Method] accept
# 17| 3: [TypeAccess] boolean
@@ -6520,6 +6634,32 @@ samConversion.kt:
# 54| 0: [TypeAccess] int
# 54| 1: [Parameter] j
# 54| 0: [TypeAccess] int
# 62| 8: [Class] PropertyRefsTest
# 62| 1: [Constructor] PropertyRefsTest
# 62| 5: [BlockStmt] { ... }
# 62| 0: [SuperConstructorInvocationStmt] super(...)
# 62| 1: [BlockStmt] { ... }
# 63| 0: [ExprStmt] <Expr>;
# 63| 0: [KtInitializerAssignExpr] ...=...
# 63| 0: [VarAccess] x
# 63| 2: [Method] getX
# 63| 3: [TypeAccess] int
# 63| 5: [BlockStmt] { ... }
# 63| 0: [ReturnStmt] return ...
# 63| 0: [VarAccess] this.x
# 63| -1: [ThisAccess] this
# 63| 3: [FieldDeclaration] int x;
# 63| -1: [TypeAccess] int
# 63| 0: [IntegerLiteral] 1
# 66| 9: [Interface] PropertyRefsGetter
# 67| 1: [Method] f
# 67| 3: [TypeAccess] int
#-----| 4: (Parameters)
# 67| 0: [Parameter] prt
# 67| 0: [TypeAccess] PropertyRefsTest
# 70| 10: [Interface] IntGetter
# 71| 1: [Method] f
# 71| 3: [TypeAccess] int
whenExpr.kt:
# 0| [CompilationUnit] whenExpr
# 0| 1: [Class] WhenExprKt

View File

@@ -4028,6 +4028,72 @@
| samConversion.kt:59:8:59:15 | fn1(...) | samConversion.kt:57:9:60:1 | test | MethodAccess |
| samConversion.kt:59:12:59:12 | 1 | samConversion.kt:57:9:60:1 | test | IntegerLiteral |
| samConversion.kt:59:14:59:14 | 2 | samConversion.kt:57:9:60:1 | test | IntegerLiteral |
| samConversion.kt:63:5:63:13 | ...=... | samConversion.kt:62:1:64:1 | PropertyRefsTest | KtInitializerAssignExpr |
| samConversion.kt:63:5:63:13 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:63:5:63:13 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:63:5:63:13 | this | samConversion.kt:63:5:63:13 | getX | ThisAccess |
| samConversion.kt:63:5:63:13 | this.x | samConversion.kt:63:5:63:13 | getX | VarAccess |
| samConversion.kt:63:5:63:13 | x | samConversion.kt:62:1:64:1 | PropertyRefsTest | VarAccess |
| samConversion.kt:63:13:63:13 | 1 | samConversion.kt:62:1:64:1 | PropertyRefsTest | IntegerLiteral |
| samConversion.kt:67:5:67:37 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:67:11:67:31 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:71:5:71:16 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:74:1:77:1 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:74:22:74:42 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:5:75:33 | test1 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr |
| samConversion.kt:75:17:75:33 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr |
| samConversion.kt:75:17:75:33 | ...=... | samConversion.kt:75:17:75:33 | | AssignExpr |
| samConversion.kt:75:17:75:33 | <fn> | samConversion.kt:75:17:75:33 | | VarAccess |
| samConversion.kt:75:17:75:33 | <fn> | samConversion.kt:75:17:75:33 | f | VarAccess |
| samConversion.kt:75:17:75:33 | Function0<Integer> | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:17:75:33 | IntGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:17:75:33 | IntGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:17:75:33 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:17:75:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:17:75:33 | invoke(...) | samConversion.kt:75:17:75:33 | f | MethodAccess |
| samConversion.kt:75:17:75:33 | new (...) | samConversion.kt:74:1:77:1 | propertyRefsTest | ClassInstanceExpr |
| samConversion.kt:75:17:75:33 | this | samConversion.kt:75:17:75:33 | | ThisAccess |
| samConversion.kt:75:17:75:33 | this.<fn> | samConversion.kt:75:17:75:33 | | VarAccess |
| samConversion.kt:75:27:75:29 | prt | samConversion.kt:74:1:77:1 | propertyRefsTest | VarAccess |
| samConversion.kt:75:27:75:32 | ...::... | samConversion.kt:74:1:77:1 | propertyRefsTest | PropertyRefExpr |
| samConversion.kt:75:27:75:32 | ...=... | samConversion.kt:75:27:75:32 | | AssignExpr |
| samConversion.kt:75:27:75:32 | <dispatchReceiver> | samConversion.kt:75:27:75:32 | | VarAccess |
| samConversion.kt:75:27:75:32 | Integer | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:27:75:32 | KProperty0<Integer> | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:27:75:32 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:27:75:32 | get(...) | samConversion.kt:75:27:75:32 | invoke | MethodAccess |
| samConversion.kt:75:27:75:32 | getX(...) | samConversion.kt:75:27:75:32 | get | MethodAccess |
| samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | | ThisAccess |
| samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | get | ThisAccess |
| samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | invoke | ThisAccess |
| samConversion.kt:75:27:75:32 | this.<dispatchReceiver> | samConversion.kt:75:27:75:32 | | VarAccess |
| samConversion.kt:75:27:75:32 | this.<dispatchReceiver> | samConversion.kt:75:27:75:32 | get | VarAccess |
| samConversion.kt:76:5:76:55 | test2 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr |
| samConversion.kt:76:17:76:55 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr |
| samConversion.kt:76:17:76:55 | ...=... | samConversion.kt:76:17:76:55 | | AssignExpr |
| samConversion.kt:76:17:76:55 | <fn> | samConversion.kt:76:17:76:55 | | VarAccess |
| samConversion.kt:76:17:76:55 | <fn> | samConversion.kt:76:17:76:55 | f | VarAccess |
| samConversion.kt:76:17:76:55 | Function1<PropertyRefsTest,Integer> | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | invoke(...) | samConversion.kt:76:17:76:55 | f | MethodAccess |
| samConversion.kt:76:17:76:55 | new (...) | samConversion.kt:74:1:77:1 | propertyRefsTest | ClassInstanceExpr |
| samConversion.kt:76:17:76:55 | prt | samConversion.kt:76:17:76:55 | f | VarAccess |
| samConversion.kt:76:17:76:55 | this | samConversion.kt:76:17:76:55 | | ThisAccess |
| samConversion.kt:76:17:76:55 | this.<fn> | samConversion.kt:76:17:76:55 | | VarAccess |
| samConversion.kt:76:36:76:54 | ...::... | samConversion.kt:74:1:77:1 | propertyRefsTest | PropertyRefExpr |
| samConversion.kt:76:36:76:54 | Integer | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:36:76:54 | KProperty1<PropertyRefsTest,Integer> | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:36:76:54 | PropertyRefsTest | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:36:76:54 | a0 | samConversion.kt:76:36:76:54 | get | VarAccess |
| samConversion.kt:76:36:76:54 | a0 | samConversion.kt:76:36:76:54 | invoke | VarAccess |
| samConversion.kt:76:36:76:54 | get(...) | samConversion.kt:76:36:76:54 | invoke | MethodAccess |
| samConversion.kt:76:36:76:54 | getX(...) | samConversion.kt:76:36:76:54 | get | MethodAccess |
| samConversion.kt:76:36:76:54 | this | samConversion.kt:76:36:76:54 | invoke | ThisAccess |
| whenExpr.kt:1:1:9:1 | int | file://:0:0:0:0 | <none> | TypeAccess |
| whenExpr.kt:1:14:1:19 | int | file://:0:0:0:0 | <none> | TypeAccess |
| whenExpr.kt:2:10:8:3 | <Stmt> | whenExpr.kt:1:1:9:1 | testWhen | StmtExpr |

View File

@@ -241,6 +241,12 @@ anon_class_member_modifiers
| samConversion.kt:46:32:46:44 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public |
| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | override, public, suspend |
| samConversion.kt:58:30:58:45 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend |
| samConversion.kt:75:17:75:33 | new IntGetter(...) { ... } | samConversion.kt:75:17:75:33 | f | override, public |
| samConversion.kt:75:27:75:32 | new KProperty0<Integer>(...) { ... } | samConversion.kt:75:27:75:32 | get | override, public |
| samConversion.kt:75:27:75:32 | new KProperty0<Integer>(...) { ... } | samConversion.kt:75:27:75:32 | invoke | override, public |
| samConversion.kt:76:17:76:55 | new PropertyRefsGetter(...) { ... } | samConversion.kt:76:17:76:55 | f | override, public |
| samConversion.kt:76:36:76:54 | new KProperty1<PropertyRefsTest,Integer>(...) { ... } | samConversion.kt:76:36:76:54 | get | override, public |
| samConversion.kt:76:36:76:54 | new KProperty1<PropertyRefsTest,Integer>(...) { ... } | samConversion.kt:76:36:76:54 | invoke | override, public |
nonOverrideInvoke
| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | 23 |
| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | 23 |

View File

@@ -58,3 +58,20 @@ suspend fun test() {
val i0 = InterfaceFn1Sus { a, b -> Unit }
i0.fn1(1,2)
}
class PropertyRefsTest {
val x = 1
}
fun interface PropertyRefsGetter {
fun f(prt: PropertyRefsTest): Int
}
fun interface IntGetter {
fun f(): Int
}
fun propertyRefsTest(prt: PropertyRefsTest) {
val test1 = IntGetter(prt::x)
val test2 = PropertyRefsGetter(PropertyRefsTest::x)
}