diff --git a/bytecode_migration_plan.md b/bytecode_migration_plan.md index cb8e801..463e6ef 100644 --- a/bytecode_migration_plan.md +++ b/bytecode_migration_plan.md @@ -53,6 +53,18 @@ Goal: migrate the compiler so all values live in frames/bytecode, keeping JVM te - [x] Step 15: Class-scope `?=` in bytecode. - [x] Handle `C.x ?= v` and `C?.x ?= v` for class-scope members without falling back. - [x] Add a JVM test for class-scope `?=` on static vars. +- [ ] Step 16: Remove dead `ToBoolStatement`. + - [ ] Confirm no parser/compiler paths construct `ToBoolStatement` and delete it plus interpreter hooks. + - [ ] Keep JVM tests green after removal. +- [x] Step 17: Callable property calls in bytecode. + - [x] Support `CallRef` where the target is a `FieldRef` (e.g., `(obj.fn)()`), keeping compile-time resolution. + - [x] Add a JVM test for a callable property call compiled to bytecode. +- [ ] Step 18: Delegated member access in bytecode. + - [ ] Remove `containsDelegatedRefs` guard once bytecode emits delegated get/set/call correctly. + - [ ] Add JVM coverage for delegated member get/set/call in bytecode. +- [ ] Step 19: Unknown receiver member access in bytecode. + - [ ] Decide on allowed fallback behavior for unknown receiver types without runtime name resolution. + - [ ] Add JVM tests for member access on unresolved receiver types and keep compile-time-only resolution. ## Notes diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt index ba7ca2a..ae0a09a 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/bytecode/BytecodeCompiler.kt @@ -3375,13 +3375,6 @@ class BytecodeCompiler( } } } - val fieldTarget = ref.target as? FieldRef - if (fieldTarget != null) { - throw BytecodeCompileException( - "Member call requires compile-time receiver type: ${fieldTarget.name}", - Pos.builtIn - ) - } val initClass = when (localTarget?.name) { "List" -> ObjList.type "Map" -> ObjMap.type diff --git a/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt b/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt index 160f970..b5cc1e5 100644 --- a/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt +++ b/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt @@ -159,6 +159,18 @@ class BytecodeRecentOpsTest { ) } + @Test + fun callablePropertyCall() = runTest { + eval( + """ + class C { var f = { x -> x + 1 } } + val c = C() + val r = (c.f)(2) + assertEquals(3, r) + """.trimIndent() + ) + } + @Test fun qualifiedThisValueRef() = runTest { eval(