diff --git a/lib/live_view_native/swiftui/rules_parser.ex b/lib/live_view_native/swiftui/rules_parser.ex index 3062ea296..baca93818 100644 --- a/lib/live_view_native/swiftui/rules_parser.ex +++ b/lib/live_view_native/swiftui/rules_parser.ex @@ -35,9 +35,6 @@ defmodule LiveViewNative.SwiftUI.RulesParser do |> Parser.error_from_result() case result do - {:ok, [output], _unconsumed = "", _context, _current_line_and_offset, _} -> - output - {:ok, output, _unconsumed = "", _context, _current_line_and_offset, _} -> output diff --git a/lib/live_view_native/swiftui/rules_parser/modifiers.ex b/lib/live_view_native/swiftui/rules_parser/modifiers.ex index 9b2341927..e4c8651a9 100644 --- a/lib/live_view_native/swiftui/rules_parser/modifiers.ex +++ b/lib/live_view_native/swiftui/rules_parser/modifiers.ex @@ -161,7 +161,7 @@ defmodule LiveViewNative.SwiftUI.RulesParser.Modifiers do |> replace(:__gesture_state__) |> post_traverse({PostProcessors, :add_annotations, []}) |> concat(wrap(modifier_brackets.(nested: true))) - |> post_traverse({PostProcessors, :wrap_in_tuple, []}) + |> wrap() ) @modifier_arguments fn inside_key_value_pair? -> @@ -207,10 +207,6 @@ defmodule LiveViewNative.SwiftUI.RulesParser.Modifiers do { frozen(parsec(:nested_modifier)), "a modifier eg ‘bold()’" - }, - { - variable(generate_error?: false), - ~s'a variable defined in the class header eg ‘color_name’' } ] |> Enum.flat_map(fn diff --git a/lib/live_view_native/swiftui/rules_parser/parser/annotations.ex b/lib/live_view_native/swiftui/rules_parser/parser/annotations.ex index 76ef447dd..666fbd080 100644 --- a/lib/live_view_native/swiftui/rules_parser/parser/annotations.ex +++ b/lib/live_view_native/swiftui/rules_parser/parser/annotations.ex @@ -4,10 +4,14 @@ defmodule LiveViewNative.SwiftUI.RulesParser.Parser.Annotations do def context_to_annotation(%Context{annotations: true} = context, line) do source = Enum.at(context.source_lines, line - context.source_line, "") - [file: context.file, line: line, module: context.module, source: String.trim(source)] + %{file: context.file, line: line, module: context.module, source: String.trim(source)} end def context_to_annotation(_, _) do - [] + empty() + end + + def empty() do + %{} end end diff --git a/lib/live_view_native/swiftui/rules_parser/post_processors.ex b/lib/live_view_native/swiftui/rules_parser/post_processors.ex index e21922338..73a264750 100644 --- a/lib/live_view_native/swiftui/rules_parser/post_processors.ex +++ b/lib/live_view_native/swiftui/rules_parser/post_processors.ex @@ -2,6 +2,7 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do @moduledoc false import LiveViewNative.SwiftUI.RulesParser.Parser.Annotations + alias LiveViewNative.SwiftUI.RulesParser.Parser.Annotations if Mix.env() == :test do @doc """ @@ -26,36 +27,7 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do end def to_attr_ast(rest, [attr, "attr"], context, {line, _}, _byte_offset) when is_binary(attr) do - {rest, [{:__attr__, context_to_annotation(context.context, line), attr}], context} - end - - def wrap_in_tuple(rest, args, context, {_line, _}, _byte_offset) do - {rest, [List.to_tuple(Enum.reverse(args))], context} - end - - def block_open_with_variable_to_ast(rest, [variable, string], context, {line, _}, _byte_offset) do - {rest, - [ - {:<>, - context_to_annotation(context.context, line) ++ [context: Elixir, imports: [{2, Kernel}]], - [string, variable]} - ], context} - end - - def tag_as_elixir_code(rest, [quotable], context, {line, _}, _byte_offset) do - {rest, - [ - {Elixir, context_to_annotation(context.context, line), quotable} - ], context} - end - - def to_elixir_variable_ast(rest, [variable_name], context, {line, _}, _byte_offset) do - {rest, - [ - {Elixir, context_to_annotation(context.context, line), - {String.to_atom(variable_name), context_to_annotation(context.context, line), - context.variable_context}} - ], context} + {rest, [[:__attr__, context_to_annotation(context.context, line), attr]], context} end def to_dotted_ime_ast(rest, [args, variable_name], context, {line, _}, _offset, is_initial) do @@ -63,12 +35,12 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do if args == [] do String.to_atom(variable_name) else - {String.to_atom(variable_name), context_to_annotation(context.context, line), args} + [String.to_atom(variable_name), context_to_annotation(context.context, line), args] end wrapped_ime = if is_initial do - [{:., context_to_annotation(context.context, line), [nil, ime]}] + [[:., context_to_annotation(context.context, line), [nil, ime]]] else [ime] end @@ -96,24 +68,24 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do defp combine_chain_ast_parts(outer, inner) when is_atom(outer) do if Regex.match?(~r/^[A-Z]/, Atom.to_string(outer)) do - {:., [], [outer, inner]} + [:., Annotations.empty(), [outer, inner]] else case outer do - {:., annotations, [nil, part]} -> - {:., annotations, [nil, {:., annotations, [part, inner]}]} + [:., annotations, [nil, part]] -> + [:., annotations, [nil, [:., annotations, [part, inner]]]] _ -> - {:., [], [outer, inner]} + [:., Annotations.empty(), [outer, inner]] end end end - defp combine_chain_ast_parts({:., annotations, [nil, part]}, inner) do - {:., annotations, [nil, {:., annotations, [part, inner]}]} + defp combine_chain_ast_parts([:., annotations, [nil, part]], inner) do + [:., annotations, [nil, [:., annotations, [part, inner]]]] end defp combine_chain_ast_parts(outer, inner) do - {:., [], [outer, inner]} + [:., Annotations.empty(), [outer, inner]] end def chain_ast(rest, sections, context, {_line, _}, _byte_offset) do @@ -126,7 +98,7 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do [ast_name | other_args] = Enum.reverse(args) annotations = context_to_annotation(context.context, line) - {rest, [{String.to_atom(ast_name), annotations, other_args}], context} + {rest, [[String.to_atom(ast_name), annotations, other_args]], context} end def to_keyword_tuple_ast(rest, [arg1, arg2], context, {_line, _}, _byte_offset) do @@ -149,12 +121,12 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do def event_to_ast(rest, [name], context, {line, _}, _byte_offset) do annotations = context_to_annotation(context.context, line) - {rest, [{:__event__, annotations, [name]}], context} + {rest, [[:__event__, annotations, [name]]], context} end def event_to_ast(rest, [opts, name], context, {line, _}, _byte_offset) do annotations = context_to_annotation(context.context, line) - {rest, [{:__event__, annotations, [name, opts]}], context} + {rest, [[:__event__, annotations, [name, opts]]], context} end def add_annotations(rest, parts, context, {line, _}, _byte_offset) do @@ -164,11 +136,11 @@ defmodule LiveViewNative.SwiftUI.RulesParser.PostProcessors do def to_scoped_atom(rest, [variable_name, scope], context, {line, _}, _byte_offset) do annotations = context_to_annotation(context.context, line) - {rest, [{:., annotations, [String.to_atom(scope), String.to_atom(variable_name)]}], context} + {rest, [[:., annotations, [String.to_atom(scope), String.to_atom(variable_name)]]], context} end def to_swift_range_ast(rest, [end_, range, start], context, {line, _}, _byte_offset) do annotations = context_to_annotation(context.context, line) - {rest, [{String.to_atom(range), annotations, [start, end_]}], context} + {rest, [[String.to_atom(range), annotations, [start, end_]]], context} end end diff --git a/lib/live_view_native/swiftui/rules_parser/tokens.ex b/lib/live_view_native/swiftui/rules_parser/tokens.ex index bab7af11c..5ff9816bb 100644 --- a/lib/live_view_native/swiftui/rules_parser/tokens.ex +++ b/lib/live_view_native/swiftui/rules_parser/tokens.ex @@ -3,7 +3,6 @@ defmodule LiveViewNative.SwiftUI.RulesParser.Tokens do import NimbleParsec import LiveViewNative.SwiftUI.RulesParser.Parser - alias LiveViewNative.SwiftUI.RulesParser.PostProcessors def comment() do ignore_whitespace() @@ -157,17 +156,6 @@ defmodule LiveViewNative.SwiftUI.RulesParser.Tokens do |> reduce({Enum, :join, [""]}) end - def variable(opts \\ []) do - variable_name() - |> post_traverse({PostProcessors, :to_elixir_variable_ast, []}) - |> expect( - Keyword.merge( - opts, - error_message: "expected a variable" - ) - ) - end - def modifier_name() do ascii_string([?a..?z, ?A..?Z, ?_], 1) |> ascii_string([?a..?z, ?A..?Z, ?0..?9, ?_], min: 0) diff --git a/mix.exs b/mix.exs index e29c65048..b10d596a7 100644 --- a/mix.exs +++ b/mix.exs @@ -55,7 +55,7 @@ defmodule LiveViewNative.SwiftUI.MixProject do {:makeup_eex, ">= 0.1.1"}, {:floki, ">= 0.30.0", only: :test}, {:live_view_native, "~> 0.3.0"}, - {:live_view_native_stylesheet, "~> 0.3.0", only: :test}, + {:live_view_native_stylesheet, github: "liveview-native/live_view_native_stylesheet", branch: "nk-change-stylesheet-output-to-json", only: :test}, {:live_view_native_test, github: "liveview-native/live_view_native_test", branch: "main", only: :test}, {:nimble_parsec, "~> 1.3"} ] diff --git a/mix.lock b/mix.lock index 67689d263..5e68e45bb 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, + "castore": {:hex, :castore, "1.0.9", "5cc77474afadf02c7c017823f460a17daa7908e991b0cc917febc90e466a375c", [:mix], [], "hexpm", "5ea956504f1ba6f2b4eb707061d8e17870de2bee95fb59d512872c2ef06925e7"}, "cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, @@ -8,7 +8,7 @@ "floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "live_view_native": {:hex, :live_view_native, "0.3.0", "a99d773740c7ca0178fdf609e4585dbd9859e1e29f65b67e3301da9afccc0e9c", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.10", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0.4", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.5", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.5", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7a343414c210f8f088b4aa5981490a1db8ef39a629ce55f79843919813e92e8c"}, - "live_view_native_stylesheet": {:hex, :live_view_native_stylesheet, "0.3.0", "decd7a02ee490406045649e911426d5ea515543023a29256dca95a409ca9079b", [:mix], [{:live_view_native, "~> 0.3.0", [hex: :live_view_native, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cec8e41b12c5177e1ffd63c061a6eab6455617d53d99c506c3787c8970de7c19"}, + "live_view_native_stylesheet": {:git, "https://github.com/liveview-native/live_view_native_stylesheet.git", "87d4a6589d51a0971158cd0a61fda2c1a1ff5607", [branch: "nk-change-stylesheet-output-to-json"]}, "live_view_native_test": {:git, "https://github.com/liveview-native/live_view_native_test.git", "539ae931fa3936f3ee2f73ffa11f7100fe6554db", [branch: "main"]}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup_eex": {:hex, :makeup_eex, "0.1.2", "93a5ef3d28ed753215dba2d59cb40408b37cccb4a8205e53ef9b5319a992b700", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.16 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_html, "~> 0.1.0 or ~> 1.0", [hex: :makeup_html, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "6140eafb28215ad7182282fd21d9aa6dcffbfbe0eb876283bc6b768a6c57b0c3"}, @@ -26,11 +26,11 @@ "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"}, "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.7.1", "87677ffe3b765bc96a89be7960f81703223fe2e21efa42c125fcd0127dd9d6b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "02dbd5f9ab571b864ae39418db7811618506256f6d13b4a45037e5fe78dc5de3"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.7.2", "fdadb973799ae691bf9ecad99125b16625b1c6039999da5fe544d99218e662e4", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "245d8a11ee2306094840c000e8816f0cbed69a23fc0ac2bcf8d7835ae019bb2f"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "sourceror": {:hex, :sourceror, "1.6.0", "9907884e1449a4bd7dbaabe95088ed4d9a09c3c791fb0103964e6316bc9448a7", [:mix], [], "hexpm", "e90aef8c82dacf32c89c8ef83d1416fc343cd3e5556773eeffd2c1e3f991f699"}, - "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.7", "65fa74042530064ef0570b75b43f5c49bb8b235d6515671b3d250022cb8a1f9e", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d0f478ee64deddfec64b800673fd6e0c8888b079d9f3444dd96d2a98383bdbd1"}, diff --git a/test/live_view_native/swiftui/rules_parser_test.exs b/test/live_view_native/swiftui/rules_parser_test.exs index e256103c9..e3393e7d7 100644 --- a/test/live_view_native/swiftui/rules_parser_test.exs +++ b/test/live_view_native/swiftui/rules_parser_test.exs @@ -18,7 +18,7 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do {line, input} = {__ENV__.line, "\nbold(true)"} # We add 1 because the modifier is on the second line of the input - output = {:bold, [file: __ENV__.file, line: line + 1, module: __ENV__.module, source: "bold(true)"], [true]} + output = [[:bold, %{file: __ENV__.file, line: line + 1, module: __ENV__.module, source: "bold(true)"}, [true]]] assert parse(input, file: __ENV__.file, @@ -37,9 +37,9 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do """} output = [ - {:font, [file: __ENV__.file, line: line, module: __ENV__.module, source: "font(.largeTitle)"], [{:., [file: __ENV__.file, line: line, module: __ENV__.module, source: "font(.largeTitle)"], [nil, :largeTitle]}]}, - {:bold, [file: __ENV__.file, line: line + 1, module: __ENV__.module, source: "bold(true)"], [true]}, - {:italic, [file: __ENV__.file, line: line + 2, module: __ENV__.module, source: "italic(true)"], [true]} + [:font, %{file: __ENV__.file, line: line, module: __ENV__.module, source: "font(.largeTitle)"}, [[:., %{file: __ENV__.file, line: line, module: __ENV__.module, source: "font(.largeTitle)"}, [nil, :largeTitle]]]], + [:bold, %{file: __ENV__.file, line: line + 1, module: __ENV__.module, source: "bold(true)"}, [true]], + [:italic, %{file: __ENV__.file, line: line + 2, module: __ENV__.module, source: "italic(true)"}, [true]] ] assert parse(input, @@ -52,14 +52,14 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses modifier function definition" do input = "bold(true)" - output = {:bold, [], [true]} + output = [[:bold, %{}, [true]]] assert parse(input) == output end test "parses modifier with multiple arguments" do input = "background(\"foo\", \"bar\")" - output = {:background, [], ["foo", "bar"]} + output = [[:background, %{}, ["foo", "bar"]]] assert parse(input) == output @@ -78,14 +78,14 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses atoms as an argument value" do input = "background(content: :star_red)" - output = {:background, [], [[content: :star_red]]} + output = [[:background, %{}, [[content: :star_red]]]] assert parse(input) == output end test "parses string wrapped atoms as an argument value" do input = "background(content: :\"star-red\")" - output = {:background, [], [[content: :"star-red"]]} + output = [[:background, %{}, [[content: :"star-red"]]]] assert parse(input) == output end @@ -93,7 +93,7 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses a naked IME" do input = "font(.largeTitle)" - output = {:font, [], [{:., [], [nil, :largeTitle]}]} + output = [[:font, %{}, [[:., %{}, [nil, :largeTitle]]]]] assert parse(input) == output end @@ -101,7 +101,7 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses comma seperated IMEs" do input = "font(.largeTitle, .bold)" - output = {:font, [], [{:., [], [nil, :largeTitle]}, {:., [], [nil, :bold]}]} + output = [[:font, %{}, [[:., %{}, [nil, :largeTitle]], [:., %{}, [nil, :bold]]]]] assert parse(input) == output end @@ -109,22 +109,22 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses chained IMEs" do input = "font(color: Color.red)" - output = {:font, [], [[color: {:., [], [:Color, :red]}]]} + output = [[:font, %{}, [[color: [:., %{}, [:Color, :red]]]]]] assert parse(input) == output input = "font(color: Color.red.shadow(.thick))" output = - {:font, [], - [[color: {:., [], [:Color, {:., [], [:red, {:shadow, [], [{:., [], [nil, :thick]}]}]}]}]]} + [[:font, %{}, + [[color: [:., %{}, [:Color, [:., %{}, [:red, [:shadow, %{}, [[:., %{}, [nil, :thick]]]]]]]]]]]] assert parse(input) == output input = "foregroundStyle(Color(.displayP3, red: 0.4627, green: 0.8392, blue: 1.0).opacity(0.25))" output = - {:foregroundStyle, [], [{:., [], [{:Color, [], [{:., [], [nil, :displayP3]}, [red: 0.4627, green: 0.8392, blue: 1.0]]}, {:opacity, [], [0.25]}]}]} + [[:foregroundStyle, %{}, [[:., %{}, [[:Color, %{}, [[:., %{}, [nil, :displayP3]], [red: 0.4627, green: 0.8392, blue: 1.0]]], [:opacity, %{}, [0.25]]]]]]] assert parse(input) == output end @@ -132,30 +132,30 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses naked chained IME" do input = "font(.largeTitle.red)" - output = {:font, [], [{:., [], [nil, {:., [], [:largeTitle, :red]}]}]} + output = [[:font, %{}, [[:., %{}, [nil, [:., %{}, [:largeTitle, :red]]]]]]] assert parse(input) == output end test "parses non-key-value lists" do input = ~s/Gradient([0, 1, 2])/ - output = {:Gradient, [], [[0, 1, 2]]} + output = [[:Gradient, %{}, [[0, 1, 2]]]] assert parse(input) == output input = ~s/Gradient([0, 1, 2], 3)/ - output = {:Gradient, [], [[0, 1, 2], 3]} + output = [[:Gradient, %{}, [[0, 1, 2], 3]]] assert parse(input) == output input = ~s/Gradient(colors: [0, 1, 2])/ - output = {:Gradient, [], [[colors: [0, 1, 2]]]} + output = [[:Gradient, %{}, [[colors: [0, 1, 2]]]]] assert parse(input) == output input = ~s/Gradient(colors: [Color.red, Color.blue])/ - output = {:Gradient, [], [[colors: [{:., [], [:Color, :red]}, {:., [], [:Color, :blue]}]]]} + output = [[:Gradient, %{}, [[colors: [[:., %{}, [:Color, :red]], [:., %{}, [:Color, :blue]]]]]]] assert parse(input) == output input = ~s/Gradient(colors: ["red", "blue"])/ - output = {:Gradient, [], [[colors: ["red", "blue"]]]} + output = [[:Gradient, %{}, [[colors: ["red", "blue"]]]]] assert parse(input) == output end @@ -163,9 +163,9 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do input = "font(.largeTitle) bold(true) italic(true)" output = [ - {:font, [], [{:., [], [nil, :largeTitle]}]}, - {:bold, [], [true]}, - {:italic, [], [true]} + [:font, %{}, [[:., %{}, [nil, :largeTitle]]]], + [:bold, %{}, [true]], + [:italic, %{}, [true]] ] assert parse(input) == output @@ -175,14 +175,14 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do input = "color(color: .foo.bar.baz(1, 2).qux)" output = - {:color, [], + [[:color, %{}, [ [ color: - {:., [], - [nil, {:., [], [:foo, {:., [], [:bar, {:., [], [{:baz, [], [1, 2]}, :qux]}]}]}]} + [:., %{}, + [nil, [:., %{}, [:foo, [:., %{}, [:bar, [:., %{}, [[:baz, %{}, [1, 2]], :qux]]]]]]]] ] - ]} + ]]] assert parse(input) == output end @@ -195,9 +195,9 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do """ output = [ - {:font, [], [{:., [], [nil, :largeTitle]}]}, - {:bold, [], [true]}, - {:italic, [], [true]} + [:font, %{}, [[:., %{}, [nil, :largeTitle]]]], + [:bold, %{}, [true]], + [:italic, %{}, [true]] ] assert parse(input) == output @@ -205,155 +205,141 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do test "parses string literal value type" do input = "foo(\"bar\")" - output = {:foo, [], ["bar"]} + output = [[:foo, %{}, ["bar"]]] assert parse(input) == output end test "parses numerical types" do input = "foo(1, -1, 1.1)" - output = {:foo, [], [1, -1, 1.1]} + output = [[:foo, %{}, [1, -1, 1.1]]] assert parse(input) == output end test "parses underscore numbers" do input = "foo(1_000, 1_000_000_000_000, 1_000.4)" - output = {:foo, [], [1_000, 1_000_000_000_000, 1_000.4]} + output = [[:foo, %{}, [1_000, 1_000_000_000_000, 1_000.4]]] assert parse(input) == output end test "parses key/value pairs" do input = ~s|foo(bar: "baz", qux: .quux)| - output = {:foo, [], [[bar: "baz", qux: {:., [], [nil, :quux]}]]} + output = [[:foo, %{}, [[bar: "baz", qux: [:., %{}, [nil, :quux]]]]]] assert parse(input) == output end test "parses bool and nil values" do input = "foo(true, false, nil)" - output = {:foo, [], [true, false, nil]} + output = [[:foo, %{}, [true, false, nil]]] assert parse(input) == output end test "parses Implicit Member Expressions" do input = "color(.red)" - output = {:color, [], [{:., [], [nil, :red]}]} + output = [[:color, %{}, [[:., %{}, [nil, :red]]]]] assert parse(input) == output end test "parses nested function calls" do input = ~s|foo(bar("baz"))| - output = {:foo, [], [{:bar, [], ["baz"]}]} + output = [[:foo, %{}, [[:bar, %{}, ["baz"]]]]] assert parse(input) == output end test "parses attr value references" do input = ~s|foo(attr("bar"))| - output = {:foo, [], [{:__attr__, [], "bar"}]} - - assert parse(input) == output - end - - test "parses variables" do - input = "foo(color_name)" - output = {:foo, [], [{Elixir, [], {:color_name, [], Elixir}}]} - - assert parse(input) == output - end - - test "parses single character variables" do - input = "foo(c)" - output = {:foo, [], [{Elixir, [], {:c, [], Elixir}}]} + output = [[:foo, %{}, [[:__attr__, %{}, "bar"]]]] assert parse(input) == output end test "parses closed ranges" do input = "foo(Foo.bar...Baz.qux)" - output = {:foo, [], [{:..., [], [{:., [], [:Foo, :bar]}, {:., [], [:Baz, :qux]}]}]} + output = [[:foo, %{}, [[:..., %{}, [[:., %{}, [:Foo, :bar]], [:., %{}, [:Baz, :qux]]]]]]] assert parse(input) == output input = "foo(1...10)" - output = {:foo, [], [{:..., [], [1, 10]}]} + output = [[:foo, %{}, [[:..., %{}, [1, 10]]]]] assert parse(input) == output input = "foo(\"a\"...\"z\")" - output = {:foo, [], [{:..., [], ["a", "z"]}]} + output = [[:foo, %{}, [[:..., %{}, ["a", "z"]]]]] assert parse(input) == output end test "parses left-hand range" do input = "foo(Foo.bar...)" - output = {:foo, [], [{:..., [], [{:., [], [:Foo, :bar]}, nil]}]} + output = [[:foo, %{}, [[:..., %{}, [[:., %{}, [:Foo, :bar]], nil]]]]] assert parse(input) == output input = "foo(1...)" - output = {:foo, [], [{:..., [], [1, nil]}]} + output = [[:foo, %{}, [[:..., %{}, [1, nil]]]]] assert parse(input) == output input = "foo(\"a\"...)" - output = {:foo, [], [{:..., [], ["a", nil]}]} + output = [[:foo, %{}, [[:..., %{}, ["a", nil]]]]] assert parse(input) == output end test "parses right-hand range" do input = "foo(...Baz.qux)" - output = {:foo, [], [{:..., [], [nil, {:., [], [:Baz, :qux]}]}]} + output = [[:foo, %{}, [[:..., %{}, [nil, [:., %{}, [:Baz, :qux]]]]]]] assert parse(input) == output input = "foo(...10)" - output = {:foo, [], [{:..., [], [nil, 10]}]} + output = [[:foo, %{}, [[:..., %{}, [nil, 10]]]]] assert parse(input) == output input = "foo(...\"z\")" - output = {:foo, [], [{:..., [], [nil, "z"]}]} + output = [[:foo, %{}, [[:..., %{}, [nil, "z"]]]]] assert parse(input) == output end test "parses half-open range" do input = "foo(Foo.bar.. [ - {:color, [], [{:., [], [nil, :red]}]} + [:color, %{}, [[:., %{}, [nil, :red]]]] ]} end @@ -398,7 +385,7 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do output = MockSheet.compile_ast(["button-plain"]) assert output == %{"button-plain" => [ - {:buttonStyle, [], [{:., [], [nil, :plain]}]} + [:buttonStyle, %{}, [[:., %{}, [nil, :plain]]]] ]} end @@ -406,7 +393,7 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do output = MockSheet.compile_ast(["color-blue"]) assert output == %{"color-blue" => [ - {:color, [], [{:., [], [nil, :blue]}]} + [:color, %{}, [[:., %{}, [nil, :blue]]]] ]} end end @@ -447,7 +434,6 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do - an IME eg ‘Color.red’ or ‘.largeTitle’’ - a list of keyword pairs eg ‘style: :dashed’, ‘size: 12’ or ‘style: [lineWidth: 1]’ - a modifier eg ‘bold()’ - - a variable defined in the class header eg ‘color_name’ """ |> String.trim() @@ -547,7 +533,7 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do end test "invalid keyword pair: double nesting" do - input = "abc(def: 11, b: lineWidth: a, l: 2a]" + input = "abc(def: 11, b: \"lineWidth\": a, l: 2a]" error = assert_raise SyntaxError, fn -> @@ -558,8 +544,8 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do """ Unsupported input: | - 1 | abc(def: 11, b: lineWidth: a, l: 2a] - | ^ + 1 | abc(def: 11, b: "lineWidth": a, l: 2a] + | ^ | expected ‘)’ @@ -709,7 +695,6 @@ defmodule LiveViewNative.SwiftUI.RulesParserTest do - an IME eg ‘Color.red’ or ‘.largeTitle’’ - a list of keyword pairs eg ‘style: :dashed’, ‘size: 12’ or ‘style: [lineWidth: 1]’ - a modifier eg ‘bold()’ - - a variable defined in the class header eg ‘color_name’ """ |> String.trim()