Add typed Kotlin member-set extern

ober

af4e25b78c7dbfee06a40057c5b951f032f234de

diff --git a/lib/jerboa/typed/checker.ss b/lib/jerboa/typed/checker.ss
index a6ae91e..208aac3 100644
--- a/lib/jerboa/typed/checker.ss
+++ b/lib/jerboa/typed/checker.ss
@@ -377,6 +377,7 @@
                      [(call) 'kotlin-call]
                      [(member-call) 'kotlin-member-call]
                      [(member-get) 'kotlin-member-get]
+                     [(member-set) 'kotlin-member-set]
                      [else 'kotlin-call])
                    target)))))
 
diff --git a/lib/jerboa/typed/core.ss b/lib/jerboa/typed/core.ss
index 47d2402..c84c22f 100644
--- a/lib/jerboa/typed/core.ss
+++ b/lib/jerboa/typed/core.ss
@@ -136,6 +136,7 @@
       kotlin-call
       kotlin-member-call
       kotlin-member-get
+      kotlin-member-set
       jvm-pair
       jvm-pair-first
       jvm-pair-second
diff --git a/lib/jerboa/typed/kotlin/lower.ss b/lib/jerboa/typed/kotlin/lower.ss
index 5f9105f..abc361b 100644
--- a/lib/jerboa/typed/kotlin/lower.ss
+++ b/lib/jerboa/typed/kotlin/lower.ss
@@ -633,6 +633,15 @@
          (make-kt-member-get
            (car args)
            (info-ref info 'member operator))]
+        [(kotlin-member-set)
+         (make-kt-block
+           (list
+             (make-kt-assign
+               (make-kt-member-get
+                 (car args)
+                 (info-ref info 'member operator))
+               (cadr args)))
+           (make-kt-lit 'Unit '()))]
         [(record-ctor)
          (make-kt-new
            (make-kt-type (info-ref info 'record operator) #f '())
diff --git a/lib/jerboa/typed/parser.ss b/lib/jerboa/typed/parser.ss
index baad2c7..67dd57e 100644
--- a/lib/jerboa/typed/parser.ss
+++ b/lib/jerboa/typed/parser.ss
@@ -443,9 +443,14 @@
               (symbol? (cadr form)))
          (list (cons 'kind 'member-get)
                (cons 'member (cadr form)))]
+        [(and (= (length form) 2)
+              (eq? (car form) 'kotlin-member-set)
+              (symbol? (cadr form)))
+         (list (cons 'kind 'member-set)
+               (cons 'member (cadr form)))]
         [else
          (error 'parse-typed-extern
-          "expected (kotlin-call PackageOrObject function), (kotlin-member-call method), or (kotlin-member-get property)"
+          "expected (kotlin-call PackageOrObject function), (kotlin-member-call method), (kotlin-member-get property), or (kotlin-member-set property)"
           form)])))
 
   (def (parse-extern form)
diff --git a/tests/test-typed-checker.ss b/tests/test-typed-checker.ss
index 3a79560..5d67345 100644
--- a/tests/test-typed-checker.ss
+++ b/tests/test-typed-checker.ss
@@ -494,6 +494,17 @@
          (boxTypesResolve context raw))))
   '(argument-type-mismatch))
 
+(test "extern kotlin member set can be used from typed code"
+  (error-kinds
+    '(typed-library (body extern-member-set-ok)
+       (export select)
+       (type ReviewView)
+       (extern (reviewViewSelectedGroupId-set (view : ReviewView) (id : String)) : Unit
+         (kotlin-member-set selectedGroupId))
+       (def (select (view : ReviewView) (id : String)) : Unit
+         (reviewViewSelectedGroupId-set view id))))
+  '())
+
 (test "effect annotation accepted"
   (error-kinds
     '(typed-library (effects accepted)
diff --git a/tests/test-typed-kotlin.ss b/tests/test-typed-kotlin.ss
index fae3f02..f221a65 100644
--- a/tests/test-typed-kotlin.ss
+++ b/tests/test-typed-kotlin.ss
@@ -279,12 +279,15 @@
 
 (define member-extern-form
   '(typed-library (sample typed memberextern)
-     (export width copyPixels)
+     (export width copyPixels setSelectedGroup)
      (type Bitmap)
+     (type ReviewView)
      (type Int32)
      (type IntArray)
      (extern (bitmapWidth (bitmap : Bitmap)) : Int32
        (kotlin-member-get width))
+     (extern (reviewViewSelectedGroupId-set (view : ReviewView) (id : String)) : Unit
+       (kotlin-member-set selectedGroupId))
      (extern (bitmapGetPixels (bitmap : Bitmap)
                               (pixels : IntArray)
                               (offset : Int32)
@@ -305,7 +308,9 @@
          (int32 0)
          (int32 0)
          (bitmapWidth bitmap)
-         (int32 1)))))
+         (int32 1)))
+     (def (setSelectedGroup (view : ReviewView) (id : String)) : Unit
+       (reviewViewSelectedGroupId-set view id))))
 
 (define member-extern-kotlin
   (typed-library-form->kotlin-string member-extern-form))
@@ -318,6 +323,10 @@
   member-extern-kotlin
   "bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, 1)")
 
+(test-contains "extern Kotlin member set lowers to property assignment"
+  member-extern-kotlin
+  "view.selectedGroupId = id")
+
 (define geometry-form
   '(typed-library (sample typed geometry)
      (export make-SsdCell SsdCell? SsdCell-x SsdCell-y SsdCell-w SsdCell-h