Tolerate nullable references to anonymous classes

This also adds a test case illustrating when this can arise
This commit is contained in:
Chris Smowton
2022-03-17 17:54:31 +00:00
committed by Ian Lynagh
parent 8d6ae50d21
commit c0f3988aaa
9 changed files with 74 additions and 19 deletions

View File

@@ -363,19 +363,14 @@ open class KotlinUsesExtractor(
classLabelResult.shortName)
}
fun useAnonymousClass(c: IrClass): TypeResults {
var res = tw.lm.anonymousTypeMapping[c]
if (res == null) {
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
res = TypeResults(javaResult, kotlinResult)
tw.lm.anonymousTypeMapping[c] = res
fun useAnonymousClass(c: IrClass) =
tw.lm.anonymousTypeMapping.getOrPut(c) {
TypeResults(
TypeResult(tw.getFreshIdLabel<DbClass>(), "", ""),
TypeResult(fakeKotlinType(), "TODO", "TODO")
)
}
return res
}
fun fakeKotlinType(): Label<out DbKt_type> {
val fakeKotlinPackageId: Label<DbPackage> = tw.getLabelFor("@\"FakeKotlinPackage\"", {
tw.writePackages(it, "fake.kotlin")
@@ -396,9 +391,6 @@ open class KotlinUsesExtractor(
if (args?.isNotEmpty() == true) {
logger.error("Anonymous class with unexpected type arguments")
}
if (hasQuestionMark) {
logger.error("Unexpected nullable anonymous class")
}
return useAnonymousClass(c)
}

View File

@@ -528,6 +528,56 @@ local_anonymous.kt:
# 26| 0: [TypeAccess] Unit
# 26| 1: [ClassInstanceExpr] new LocalClass(...)
# 26| -3: [TypeAccess] LocalClass
# 29| 7: [Method] nullableAnonymous
# 29| 5: [BlockStmt] { ... }
# 35| 0: [ReturnStmt] return ...
# 29| 0: [StmtExpr] <Stmt>
# 29| 0: [BlockStmt] { ... }
# 29| 0: [LocalTypeDeclStmt] class ...
# 29| 0: [AnonymousClass,LocalClass] new Object(...) { ... }
# 29| 1: [Constructor]
# 29| 5: [BlockStmt] { ... }
# 29| 0: [SuperConstructorInvocationStmt] super(...)
# 29| 1: [BlockStmt] { ... }
# 30| 0: [ExprStmt] <Expr>;
# 30| 0: [KtInitializerAssignExpr] ...=...
# 30| 0: [VarAccess] x
# 30| 2: [Method] getX
# 30| 5: [BlockStmt] { ... }
# 30| 0: [ReturnStmt] return ...
# 30| 0: [VarAccess] this.x
# 30| -1: [ThisAccess] this
# 30| 2: [Method] setX
#-----| 4: (Parameters)
# 30| 0: [Parameter] <set-?>
# 30| 5: [BlockStmt] { ... }
# 30| 0: [ExprStmt] <Expr>;
# 30| 0: [AssignExpr] ...=...
# 30| 0: [VarAccess] this.x
# 30| -1: [ThisAccess] this
# 30| 1: [VarAccess] <set-?>
# 30| 2: [FieldDeclaration] int x;
# 30| -1: [TypeAccess] int
# 30| 0: [IntegerLiteral] 1
# 32| 5: [Method] member
# 32| 5: [BlockStmt] { ... }
# 33| 0: [LocalVariableDeclStmt] var ...;
# 33| 1: [LocalVariableDeclExpr] maybeThis
# 33| 0: [WhenExpr] when ...
# 33| 0: [WhenBranch] ... -> ...
# 33| 0: [ValueEQExpr] ... (value equals) ...
# 33| 0: [MethodAccess] getX(...)
# 33| -1: [ThisAccess] this
# 33| 1: [IntegerLiteral] 1
# 33| 1: [ExprStmt] <Expr>;
# 33| 0: [ThisAccess] this
# 33| 1: [WhenBranch] ... -> ...
# 33| 0: [BooleanLiteral] true
# 33| 1: [ExprStmt] <Expr>;
# 33| 0: [NullLiteral] null
# 29| 1: [ExprStmt] <Expr>;
# 29| 0: [ClassInstanceExpr] new (...)
# 29| -3: [TypeAccess] Object
superChain.kt:
# 0| [CompilationUnit] superChain
# 1| 1: [Class,GenericType,ParameterizedType] SuperChain1

View File

@@ -7,3 +7,4 @@
| classes.kt:89:16:89:44 | new Interface3<Integer>(...) { ... } | classes.kt:89:16:89:44 | new (...) | | classes.kt:89:16:89:44 | Interface3<Integer> | classes.kt:89:16:89:44 | class ... |
| classes.kt:127:16:134:9 | new Object(...) { ... } | classes.kt:127:16:134:9 | new (...) | | classes.kt:127:16:134:9 | Object | classes.kt:127:16:134:9 | class ... |
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | local_anonymous.kt:5:16:7:9 | new (...) | | local_anonymous.kt:5:16:7:9 | Object | local_anonymous.kt:5:16:7:9 | class ... |
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | local_anonymous.kt:29:31:35:5 | new (...) | | local_anonymous.kt:29:31:35:5 | Object | local_anonymous.kt:29:31:35:5 | class ... |

View File

@@ -34,13 +34,14 @@
| classes.kt:119:13:121:13 | Local2 | C1$Local2 | final, private |
| classes.kt:127:16:134:9 | new Object(...) { ... } | <anonymous class> | final, private |
| classes.kt:129:17:131:17 | Local3 | C1$$Local3 | final, private |
| local_anonymous.kt:3:1:28:1 | Class1 | LocalAnonymous.Class1 | final, public |
| local_anonymous.kt:3:1:36:1 | Class1 | LocalAnonymous.Class1 | final, public |
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | <anonymous class> | final, private |
| local_anonymous.kt:11:9:11:24 | | Class1$ | final, private |
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | <anonymous class> | final, private |
| local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | <anonymous class> | final, private |
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | <anonymous class> | final, private |
| local_anonymous.kt:25:9:25:27 | LocalClass | LocalAnonymous.Class1$LocalClass | final, private |
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | <anonymous class> | final, private |
| superChain.kt:1:1:1:33 | SuperChain1 | SuperChain1 | public |
| superChain.kt:2:1:2:60 | SuperChain2 | SuperChain2 | public |
| superChain.kt:3:1:3:60 | SuperChain3 | SuperChain3 | public |

View File

@@ -34,13 +34,14 @@ superCall
| classes.kt:119:13:121:13 | super(...) |
| classes.kt:127:16:134:9 | super(...) |
| classes.kt:129:17:131:17 | super(...) |
| local_anonymous.kt:3:1:28:1 | super(...) |
| local_anonymous.kt:3:1:36:1 | super(...) |
| local_anonymous.kt:5:16:7:9 | super(...) |
| local_anonymous.kt:11:9:11:24 | super(...) |
| local_anonymous.kt:16:23:16:49 | super(...) |
| local_anonymous.kt:17:23:17:49 | super(...) |
| local_anonymous.kt:21:21:21:31 | super(...) |
| local_anonymous.kt:25:9:25:27 | super(...) |
| local_anonymous.kt:29:31:35:5 | super(...) |
| superChain.kt:1:1:1:33 | super(...) |
| superChain.kt:2:33:2:57 | super(...) |
| superChain.kt:3:33:3:57 | super(...) |

View File

@@ -2,5 +2,5 @@
| classes.kt:118:9:123:9 | class ... | classes.kt:118:9:123:9 | | classes.kt:117:5:124:5 | fn2 | classes.kt:109:1:136:1 | C1 |
| classes.kt:119:13:121:13 | class ... | classes.kt:119:13:121:13 | Local2 | classes.kt:118:9:123:9 | localFn | classes.kt:109:1:136:1 | C1 |
| classes.kt:129:17:131:17 | class ... | classes.kt:129:17:131:17 | Local3 | classes.kt:128:13:133:13 | fn | classes.kt:127:16:134:9 | new Object(...) { ... } |
| local_anonymous.kt:11:9:11:24 | class ... | local_anonymous.kt:11:9:11:24 | | local_anonymous.kt:10:5:13:5 | fn2 | local_anonymous.kt:3:1:28:1 | Class1 |
| local_anonymous.kt:25:9:25:27 | class ... | local_anonymous.kt:25:9:25:27 | LocalClass | local_anonymous.kt:24:5:27:5 | fn5 | local_anonymous.kt:3:1:28:1 | Class1 |
| local_anonymous.kt:11:9:11:24 | class ... | local_anonymous.kt:11:9:11:24 | | local_anonymous.kt:10:5:13:5 | fn2 | local_anonymous.kt:3:1:36:1 | Class1 |
| local_anonymous.kt:25:9:25:27 | class ... | local_anonymous.kt:25:9:25:27 | LocalClass | local_anonymous.kt:24:5:27:5 | fn5 | local_anonymous.kt:3:1:36:1 | Class1 |

View File

@@ -1,5 +1,6 @@
anonymousObjects
| local_anonymous.kt:5:16:7:9 | new (...) | local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | anonymous | local |
| local_anonymous.kt:29:31:35:5 | new (...) | local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | anonymous | local |
localFunctions
| local_anonymous.kt:11:9:11:24 | fnLocal | local_anonymous.kt:11:9:11:24 | | not anonymous | local |
lambdas

View File

@@ -25,4 +25,12 @@ class Class1 {
class LocalClass {}
LocalClass()
}
fun nullableAnonymous() = object {
var x = 1
fun member() {
val maybeThis = if (x == 1) this else null // Expression with nullable anonymous type
}
}
}

View File

@@ -42,7 +42,7 @@
| classes.kt:127:16:134:9 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object |
| classes.kt:129:17:131:17 | Local3 | file://<external>/Object.class:0:0:0:0 | Object |
| classes.kt:129:17:131:17 | Local3<Integer> | file://<external>/Object.class:0:0:0:0 | Object |
| local_anonymous.kt:3:1:28:1 | Class1 | file://<external>/Object.class:0:0:0:0 | Object |
| local_anonymous.kt:3:1:36:1 | Class1 | file://<external>/Object.class:0:0:0:0 | Object |
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object |
| local_anonymous.kt:11:9:11:24 | | file://<external>/Object.class:0:0:0:0 | Object |
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Integer,Integer,Integer> |
@@ -52,6 +52,7 @@
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/Function1.class:0:0:0:0 | Function1<Class1,Unit> |
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/FunctionReference.class:0:0:0:0 | FunctionReference |
| local_anonymous.kt:25:9:25:27 | LocalClass | file://<external>/Object.class:0:0:0:0 | Object |
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object |
| superChain.kt:1:1:1:33 | SuperChain1 | file://<external>/Object.class:0:0:0:0 | Object |
| superChain.kt:1:1:1:33 | SuperChain1<T3,String> | file://<external>/Object.class:0:0:0:0 | Object |
| superChain.kt:1:1:1:33 | SuperChain1<T5,String> | file://<external>/Object.class:0:0:0:0 | Object |