From 3530dc17c5dc836c826b4a29cff2f3408dc8590d Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Tue, 14 Jun 2022 14:34:30 -0400 Subject: Better syntax for JVM class field imports. --- stdlib/source/library/lux/ffi.jvm.lux | 113 ++++++++++++--------- stdlib/source/library/lux/ffi.old.lux | 8 +- stdlib/source/library/lux/target/jvm/loader.lux | 2 +- .../lux/tool/compiler/meta/packager/jvm.lux | 4 +- stdlib/source/library/lux/world/console.lux | 4 +- stdlib/source/library/lux/world/file.lux | 2 +- stdlib/source/library/lux/world/file/watch.lux | 6 +- stdlib/source/test/lux.lux | 15 ++- stdlib/source/test/lux/ffi.jvm.lux | 59 ++++++++++- stdlib/source/test/lux/ffi/export.jvm.lux | 18 ++-- 10 files changed, 154 insertions(+), 77 deletions(-) (limited to 'stdlib') diff --git a/stdlib/source/library/lux/ffi.jvm.lux b/stdlib/source/library/lux/ffi.jvm.lux index 32b5410ee..f5ae643ad 100644 --- a/stdlib/source/library/lux/ffi.jvm.lux +++ b/stdlib/source/library/lux/ffi.jvm.lux @@ -988,17 +988,17 @@ [#import_method_name name #import_method_return return]]}))) (.form (do <>.monad - [static? (<>.parses? (.this (' "static"))) + [read_only? (<>.parses? (.this (' "read_only"))) + static? (<>.parses? (.this (' "static"))) name .local ?prim_mode (<>.maybe primitive_mode^) - gtype (..type^ owner_vars) maybe? (<>.parses? (.this (' "?"))) - setter? (<>.parses? (.this (' #!)))] + gtype (..type^ owner_vars)] (in {#FieldAccessDecl [#import_field_mode (maybe.else {#AutoPrM} ?prim_mode) #import_field_name name #import_field_static? static? #import_field_maybe? maybe? - #import_field_setter? setter? + #import_field_setter? (not read_only?) #import_field_type gtype]}))) )) @@ -1500,6 +1500,12 @@ (list name (` (~! .any))))) list#conjoint)) +(exception: .public (cannot_write_to_field [class Text + field Text]) + (exception.report + "Class" (%.text class) + "Field" (%.text field))) + (def: (member_def_interop vars kind class [arg_function_inputs input_jvm_types arg_types] member method_prefix import_format) (-> (List (Type Var)) Class_Kind (Type Declaration) [(List [Bit Code]) (List (Type Value)) (List Code)] Import_Member_Declaration Text Text (Meta (List Code))) (let [[full_name class_tvars] (parser.declaration class)] @@ -1603,49 +1609,62 @@ {#FieldAccessDecl fad} (do meta.monad [.let [(open "_[0]") fad - getter_name (code.symbol ["" (..import_name import_format method_prefix _#import_field_name)]) - setter_name (code.symbol ["" (..import_name import_format method_prefix (format _#import_field_name "!"))])] - getter_interop (with_symbols [g!obj] - (let [getter_call (if _#import_field_static? - (` ((~ getter_name) [])) - (` ((~ getter_name) [(~ g!obj) (~! .any)]))) - getter_body (<| (with_automatic_output_conversion _#import_field_mode) - [_#import_field_type - (if _#import_field_static? - (get_static_field full_name _#import_field_name) - (get_virtual_field full_name _#import_field_name (..un_quoted g!obj)))]) - getter_body (if _#import_field_maybe? - (` ((~! ???) (~ getter_body))) - getter_body) - getter_body (if _#import_field_setter? - (` ((~! io.io) (~ getter_body))) - getter_body)] - (in (` (def: (~ getter_name) - ((~! syntax) (~ getter_call) - ((~' in) (.list (.` (~ getter_body)))))))))) - setter_interop (.is (Meta (List Code)) - (if _#import_field_setter? - (with_symbols [g!obj g!value] - (let [setter_call (if _#import_field_static? - (` ((~ setter_name) [(~ g!value) (~! .any)])) - (` ((~ setter_name) [(~ g!value) (~! .any) - (~ g!obj) (~! .any)]))) - setter_value (|> [_#import_field_type (..un_quoted g!value)] - (with_automatic_input_conversion _#import_field_mode)) - setter_value (if _#import_field_maybe? - (` ((~! !!!) (~ setter_value))) - setter_value) - setter_command (format (if _#import_field_static? "jvm putstatic" "jvm putfield") - ":" full_name ":" _#import_field_name) - g!obj+ (.is (List Code) - (if _#import_field_static? - (list) - (list (..un_quoted g!obj))))] - (in (list (` (def: (~ setter_name) - ((~! syntax) (~ setter_call) - ((~' in) (.list (.` ((~! io.io) ((~ (code.text setter_command)) (~+ g!obj+) (~ setter_value))))))))))))) - (in (list))))] - (in (list.partial getter_interop setter_interop))) + g!name (code.symbol ["" (..import_name import_format method_prefix _#import_field_name)])]] + (with_symbols [g!obj g!value write|read] + (in (let [getter_body (<| (with_automatic_output_conversion _#import_field_mode) + [_#import_field_type + (if _#import_field_static? + (get_static_field full_name _#import_field_name) + (get_virtual_field full_name _#import_field_name (..un_quoted g!obj)))]) + getter_body (if _#import_field_maybe? + (` ((~! ???) (~ getter_body))) + getter_body) + getter_body (if _#import_field_setter? + (` ((~! io.io) (~ getter_body))) + getter_body) + + setter_value (|> [_#import_field_type (..un_quoted g!value)] + (with_automatic_input_conversion _#import_field_mode)) + setter_value (if _#import_field_maybe? + (` ((~! !!!) (~ setter_value))) + setter_value) + setter_command (if _#import_field_static? "jvm member put static" "jvm member put virtual") + g!obj+ (.is (List Code) + (if _#import_field_static? + (list) + (list (..un_quoted g!obj)))) + + parser (let [write (if _#import_field_static? + (` (~! .any)) + (` ((~! <>.and) + (~! .any) + (~! .any)))) + read (if _#import_field_static? + (` (~! .end)) + (` (~! .any)))] + (` ((~! <>.or) (~ write) (~ read)))) + write (list (if _#import_field_static? + (` {.#Left [(~ g!value)]}) + (` {.#Left [(~ g!value) (~ g!obj)]})) + (if _#import_field_setter? + (` ((~' in) (.list (.` ((~! io.io) ((~ (code.text setter_command)) + (~ (code.text full_name)) + (~ (code.text _#import_field_name)) + (~ setter_value) + (~+ g!obj+))))))) + (` ((~! meta.failure) (~ (code.text (exception.error ..cannot_write_to_field [full_name _#import_field_name]))))))) + read (list (if _#import_field_static? + (` {.#Right []}) + (` {.#Right [(~ g!obj)]})) + (` ((~' in) (.list (.` (~ getter_body)))))) + + it (` (def: (~ g!name) + ((~! syntax) ((~ g!name) [(~ write|read) (~ parser)]) + (case (~ write|read) + (~+ write) + (~+ read))))) + _ ("lux io log" (%.format "[!] " (%.code it)))] + (list it))))) ))) (def: (member_import$ vars kind class [import_format member]) diff --git a/stdlib/source/library/lux/ffi.old.lux b/stdlib/source/library/lux/ffi.old.lux index 1933ba032..92d7322fd 100644 --- a/stdlib/source/library/lux/ffi.old.lux +++ b/stdlib/source/library/lux/ffi.old.lux @@ -959,17 +959,17 @@ [#import_method_name name #import_method_return return]]}))) (.form (do <>.monad - [static? (<>.parses? (.this (' "static"))) + [read_only? (<>.parses? (.this (' "read_only"))) + static? (<>.parses? (.this (' "static"))) name .local ?prim_mode (<>.maybe primitive_mode^) gtype (..generic_type^ owner_vars) - maybe? (<>.parses? (.this (' "?"))) - setter? (<>.parses? (.this (' "!")))] + maybe? (<>.parses? (.this (' "?")))] (in {#FieldAccessDecl [#import_field_mode (maybe.else {#AutoPrM} ?prim_mode) #import_field_name name #import_field_static? static? #import_field_maybe? maybe? - #import_field_setter? setter? + #import_field_setter? (not read_only?) #import_field_type gtype]}))) )) diff --git a/stdlib/source/library/lux/target/jvm/loader.lux b/stdlib/source/library/lux/target/jvm/loader.lux index f582d2140..ee54b8aef 100644 --- a/stdlib/source/library/lux/target/jvm/loader.lux +++ b/stdlib/source/library/lux/target/jvm/loader.lux @@ -53,7 +53,7 @@ (import java/lang/Integer "[1]::[0]" - ("static" TYPE (java/lang/Class java/lang/Integer))) + ("read_only" "static" TYPE (java/lang/Class java/lang/Integer))) (import java/lang/reflect/AccessibleObject "[1]::[0]" diff --git a/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux b/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux index c19c7ed00..47fb81088 100644 --- a/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux +++ b/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux @@ -60,8 +60,8 @@ (import java/util/jar/Attributes$Name "[1]::[0]" - ("static" MAIN_CLASS java/util/jar/Attributes$Name) - ("static" MANIFEST_VERSION java/util/jar/Attributes$Name)) + ("read_only" "static" MAIN_CLASS java/util/jar/Attributes$Name) + ("read_only" "static" MANIFEST_VERSION java/util/jar/Attributes$Name)) (import java/util/jar/Manifest "[1]::[0]" diff --git a/stdlib/source/library/lux/world/console.lux b/stdlib/source/library/lux/world/console.lux index f7fee43da..4112af8f4 100644 --- a/stdlib/source/library/lux/world/console.lux +++ b/stdlib/source/library/lux/world/console.lux @@ -60,8 +60,8 @@ (import java/lang/System "[1]::[0]" ("static" console [] "io" "?" java/io/Console) - ("static" in java/io/InputStream) - ("static" out java/io/PrintStream)) + ("read_only" "static" in java/io/InputStream) + ("read_only" "static" out java/io/PrintStream)) (exception: .public cannot_open) diff --git a/stdlib/source/library/lux/world/file.lux b/stdlib/source/library/lux/world/file.lux index 51abe0483..420fd0bde 100644 --- a/stdlib/source/library/lux/world/file.lux +++ b/stdlib/source/library/lux/world/file.lux @@ -177,7 +177,7 @@ (renameTo [java/io/File] "io" "try" boolean) (lastModified [] "io" "try" long) (setLastModified [long] "io" "try" boolean) - ("static" separator java/lang/String))) + ("read_only" "static" separator java/lang/String))) (ffi.import java/lang/AutoCloseable "[1]::[0]" diff --git a/stdlib/source/library/lux/world/file/watch.lux b/stdlib/source/library/lux/world/file/watch.lux index d9b982faf..84f9cae1d 100644 --- a/stdlib/source/library/lux/world/file/watch.lux +++ b/stdlib/source/library/lux/world/file/watch.lux @@ -301,9 +301,9 @@ (import java/nio/file/StandardWatchEventKinds "[1]::[0]" - ("static" ENTRY_CREATE (java/nio/file/WatchEvent$Kind java/nio/file/Path)) - ("static" ENTRY_MODIFY (java/nio/file/WatchEvent$Kind java/nio/file/Path)) - ("static" ENTRY_DELETE (java/nio/file/WatchEvent$Kind java/nio/file/Path))) + ("read_only" "static" ENTRY_CREATE (java/nio/file/WatchEvent$Kind java/nio/file/Path)) + ("read_only" "static" ENTRY_MODIFY (java/nio/file/WatchEvent$Kind java/nio/file/Path)) + ("read_only" "static" ENTRY_DELETE (java/nio/file/WatchEvent$Kind java/nio/file/Path))) (def: (default_event_concern event) (All (_ a) diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index ad0f5fc95..a43e6a889 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -47,18 +47,22 @@ ["[1][0]" control] ["[1][0]" data] ["[1][0]" debug] + ["[1][0]" documentation] ["[1][0]" locale] ["[1][0]" macro] ["[1][0]" math] + ["[1][0]" meta] ["[1][0]" program] ["[1][0]" static] ["[1][0]" test] + ["[1][0]" time] ["[1][0]" tool] ["[1][0]" type] ["[1][0]" world] + ["[1][0]" ffi] ["[1][0]" extension] ["[1][0]" target (.only) @@ -68,7 +72,8 @@ "Lua" (~~ (.these ["[1]/[0]" lua])) "Python" (~~ (.these ["[1]/[0]" python])) "Ruby" (~~ (.these ["[1]/[0]" ruby])) - (~~ (.these))))]]))) + (~~ (.these))))] + ]))) (def: for_bit Test @@ -1217,18 +1222,18 @@ /meta.test /program.test /static.test - /target.test - /test.test + /time.test /tool.test /type.test - /world.test + /ffi.test - (~~ (for @.old (~~ (these)) (~~ (these /extension.test)))) + + /target.test (~~ (for @.jvm (~~ (these /target/jvm.test)) @.old (~~ (these /target/jvm.test)) @.js (~~ (these /target/js.test)) diff --git a/stdlib/source/test/lux/ffi.jvm.lux b/stdlib/source/test/lux/ffi.jvm.lux index 146fb5683..d30eee0ae 100644 --- a/stdlib/source/test/lux/ffi.jvm.lux +++ b/stdlib/source/test/lux/ffi.jvm.lux @@ -9,6 +9,7 @@ [abstract [monad (.only do)]] [control + ["[0]" io] ["[0]" pipe] ["[0]" try (.open: "[1]#[0]" functor)] ["[0]" exception] @@ -526,6 +527,30 @@ (set_actual9 [a] void) (get_actual9 [] a)) +(/.class: "final" (test/TestClass10 a) [] + ... Fields + ("public" value10 a) + ... Constructors + ("public" [] (new self [init a]) [] + (:= ::value10 init))) + +(/.import (test/TestClass10 a) + "[1]::[0]" + (new [a]) + (value10 a)) + +(/.class: "final" (test/TestClass11 a) [] + ... Fields + ("public" value11 a) + ... Constructors + ("public" [] (new self [init a]) [] + (:= ::value11 init))) + +(/.import (test/TestClass11 a) + "[1]::[0]" + (new [a]) + ("read_only" value11 a)) + (def: for_class Test (do [! random.monad] @@ -595,12 +620,36 @@ (test/TestClass9::new dummy/0)) (test/TestClass9::set_actual9 dummy/1) (test/TestClass9::set_actual9 dummy/2)) - example/9! (|> object/9 test/TestClass9::get_actual9 /.as_long - (same? dummy/2))]] + (same? dummy/2)) + + object/10 (is (test/TestClass10 java/lang/Long) + (test/TestClass10::new dummy/0)) + example/10! + (and (|> object/10 + test/TestClass10::value10 + io.run! + (same? dummy/0)) + (|> object/10 + (test/TestClass10::value10 dummy/1) + io.run! + test/TestClass10::value10 + io.run! + (same? dummy/1))) + + object/11 (is (test/TestClass11 java/lang/Long) + (test/TestClass11::new dummy/0)) + example/11! + (and (|> object/11 + test/TestClass11::value11 + (same? dummy/0)) + (|> object/11 + (test/TestClass11::value11 dummy/1) + macro_error + (text.contains? (the exception.#label /.cannot_write_to_field))))]] (all _.and (_.coverage [/.class: /.import] (and example/0! @@ -610,7 +659,11 @@ example/4! example/5! example/7! - example_8!)) + example_8! + example/10! + )) + (_.coverage [/.cannot_write_to_field] + example/11!) (_.coverage [/.do_to] example/9!) ))) diff --git a/stdlib/source/test/lux/ffi/export.jvm.lux b/stdlib/source/test/lux/ffi/export.jvm.lux index c3fd80bea..e9468a8fe 100644 --- a/stdlib/source/test/lux/ffi/export.jvm.lux +++ b/stdlib/source/test/lux/ffi/export.jvm.lux @@ -68,14 +68,14 @@ (`` (`` (//.import Primitives "[1]::[0]" - ("static" actual_boolean boolean) - ("static" actual_byte byte) - ("static" actual_short short) - ("static" actual_int int) - ("static" actual_long long) - ("static" actual_char char) - ("static" actual_float float) - ("static" actual_double double) + ("read_only" "static" actual_boolean boolean) + ("read_only" "static" actual_byte byte) + ("read_only" "static" actual_short short) + ("read_only" "static" actual_int int) + ("read_only" "static" actual_long long) + ("read_only" "static" actual_char char) + ("read_only" "static" actual_float float) + ("read_only" "static" actual_double double) (~~ (with_template [] [("static" (~~ (template.symbol [ "_method"])) [ ] )] @@ -103,7 +103,7 @@ (//.import Objects "[1]::[0]" - ("static" actual_string java/lang/String) + ("read_only" "static" actual_string java/lang/String) ("static" string_method [java/lang/String java/lang/String] java/lang/String) -- cgit v1.2.3