示例#1
0
 def test_add_assignment_reserved(self):
     scope = codegen.Scope()
     let = codegen.Let(parent_scope=scope)
     name = let.add_assignment("x", codegen.String("a string"))
     self.assertEqual(name.name, "x")
     let.value = codegen.String("other")
     self.assertCodeEqual(
         let.as_source_code(),
         """
         let
             x = "a string"
         in
             "other"
     """,
     )
示例#2
0
 def test_string_join_omit_empty_2(self):
     scope = codegen.Scope()
     scope.reserve_name("tmp", type=dtypes.String)
     var = scope.variables["tmp"]
     join = codegen.StringConcat([codegen.String(""), var])
     join = codegen.simplify(join)
     self.assertCodeEqual(
         join.as_source_code(),
         """
         tmp
     """,
     )
示例#3
0
 def test_string_join_collapse_strings(self):
     scope = codegen.Scope()
     scope.reserve_name("tmp", type=dtypes.String)
     var = scope.variables["tmp"]
     join1 = codegen.StringConcat([
         codegen.String("hello "),
         codegen.String("there "),
         var,
         codegen.String(" how"),
         codegen.String(" are you?"),
     ])
     join1 = codegen.simplify(join1)
     self.assertCodeEqual(
         join1.as_source_code(),
         """
         String.concat [ "hello there "
                       , tmp
                       , " how are you?"
                       ]
         """,
     )
示例#4
0
 def test_let_no_assignments(self):
     module = codegen.Module()
     func = codegen.Function("myfunc", parent_scope=module)
     func.body.value = codegen.String("Hello")
     func = codegen.simplify(func)
     self.assertCodeEqual(
         func.as_source_code(),
         """
         myfunc =
             "Hello"
     """,
     )
示例#5
0
 def test_string_join_two(self):
     scope = codegen.Scope()
     scope.reserve_name("tmp", type=dtypes.String)
     var = scope.variables["tmp"]
     join = codegen.StringConcat([codegen.String("hello "), var])
     self.assertCodeEqual(
         join.as_source_code(),
         """
         String.concat [ "hello "
                       , tmp
                       ]
     """,
     )
示例#6
0
 def test_function(self):
     module = codegen.Module()
     func = codegen.Function("myfunc",
                             args=["myarg1", "myarg2"],
                             parent_scope=module)
     func.body.value = codegen.String("hello")
     func = codegen.simplify(func)
     self.assertCodeEqual(
         func.as_source_code(),
         """
         myfunc myarg1 myarg2 =
             "hello"
     """,
     )
示例#7
0
    def test_case(self):
        scope = codegen.Scope()
        tmp = scope.reserve_name("tmp")
        case = codegen.Case(scope.variables[tmp])
        branch1 = case.add_branch(codegen.String("x"))
        branch1.value = codegen.Number(1)
        branch2 = case.add_branch(codegen.String("y"))
        branch2.value = codegen.Number(2)
        branch3 = case.add_branch(codegen.Otherwise())
        branch3.value = codegen.Number(3)

        case = codegen.simplify(case)
        self.assertCodeEqual(
            case.as_source_code(),
            """
            case tmp of
                "x" ->
                    1
                "y" ->
                    2
                _ ->
                    3
        """,
        )
示例#8
0
    def test_add_function(self):
        module = codegen.Module(name="Main")
        func_name = module.reserve_name("myfunc")
        func = codegen.Function(func_name, parent_scope=module)
        func.body.value = codegen.String("hi")
        module.add_function(func_name, func)
        func = codegen.simplify(func)
        self.assertCodeEqual(
            module.as_source_code(),
            """
            module Main exposing (myfunc)

            myfunc =
                "hi"
        """,
        )
示例#9
0
 def test_let_one_assignment(self):
     module = codegen.Module()
     func = codegen.Function("myfunc", parent_scope=module)
     let = func.body
     x = let.add_assignment("x", codegen.String("Hello"))
     self.assertEqual(x.name, "x")
     self.assertEqual(x.type, dtypes.String)
     let.value = x
     func = codegen.simplify(func)
     self.assertCodeEqual(
         func.as_source_code(),
         """
         myfunc =
             "Hello"
     """,
     )
示例#10
0
 def test_record_update(self):
     rec = types.Record()
     rec.add_field("name", dtypes.String)
     rec.add_field("age", dtypes.Number)
     rec.add_field("height", dtypes.Number)
     scope = codegen.Scope()
     tmp = scope.reserve_name("tmp", type=rec)
     var = scope.variables[tmp]
     update = codegen.RecordUpdate(var,
                                   name=codegen.String("Fred"),
                                   age=codegen.Number(34))
     self.assertCodeEqual(
         update.as_source_code(),
         """
         { tmp | age = 34, name = "Fred" }
     """,
     )
示例#11
0
 def test_function_typed(self):
     module = codegen.Module()
     function_type = types.Function.for_multiple_inputs(
         [dtypes.String, dtypes.Number], dtypes.String)
     module.reserve_name("myfunc", type=function_type)
     func = codegen.Function(
         "myfunc",
         args=["myarg1", "myarg2"],
         parent_scope=module,
         function_type=function_type,
     )
     func.body.value = codegen.String("hello")
     func = codegen.simplify(func)
     self.assertCodeEqual(
         func.as_source_code(),
         """
         myfunc : String -> number -> String
         myfunc myarg1 myarg2 =
             "hello"
     """,
     )
     self.assertEqual(func.variables["myarg2"].type, dtypes.Number)
示例#12
0
def dom_nodes_to_elm(nodes, expr_replacements, local_scope, compiler_env):
    # We have to structure this as a list of lists, then do a List.concat
    # at the end. In many cases the List.concat will disappear after
    # simplify.
    from elm_fluent import compiler

    items = []
    for node in nodes:
        if isinstance(node, bs4.element.NavigableString):
            parts = interpolate_replacements(text_type(node), expr_replacements)
            for part in parts:
                if isinstance(part, string_types):
                    items.append(
                        HtmlList(
                            [
                                local_scope.variables["Html.text"].apply(
                                    codegen.String(text_type(part))
                                )
                            ]
                        )
                    )
                else:
                    val = compiler.compile_expr(part, local_scope, compiler_env)
                    if val.type == html_output_type:
                        # This is a list type, so simply append to our list of lists
                        items.append(val)
                    else:
                        val = local_scope.variables["Html.text"].apply(
                            compiler.Stringable(val, local_scope)
                        )
                        items.append(HtmlList([val]))
        else:
            assert isinstance(node, bs4.element.Tag)
            tag_name = node.name.lower()
            static_attributes = []
            for attr_name, attr_value in sorted(node.attrs.items()):
                if isinstance(attr_value, list):
                    # Bs4 treats class attribute differently, returns a list, which we convert
                    # back to a string here:
                    attr_value = " ".join(attr_value)

                attr_value_parts = interpolate_replacements(
                    attr_value, expr_replacements
                )
                attr_output_parts = []
                for part in attr_value_parts:
                    if isinstance(part, string_types):
                        attr_output_parts.append(codegen.String(text_type(part)))
                    else:
                        with compiler_env.modified(html_context=False):
                            attr_output_parts.append(
                                compiler.Stringable(
                                    compiler.compile_expr(
                                        part, local_scope, compiler_env
                                    ),
                                    local_scope,
                                    from_ftl_source=compiler.make_ftl_source(
                                        part, compiler_env
                                    ),
                                )
                            )

                attr_final_value = codegen.StringConcat(attr_output_parts)

                if attr_name in html_attributes.ATTRIBUTES:
                    attr_constructor = local_scope.variables[
                        "Attributes.{0}".format(attr_name)
                    ]
                else:
                    attr_constructor = local_scope.variables[
                        "Attributes.attribute"
                    ].apply(codegen.String(attr_name))
                static_attributes.append(attr_constructor.apply(attr_final_value))

            if compiler_env.dynamic_html_attributes:
                selectors_for_node = codegen.List(
                    list(
                        map(
                            codegen.String,
                            get_selectors_for_node(node, expr_replacements),
                        )
                    )
                )
                dynamic_attributes = local_scope.variables[
                    "Fluent.selectAttributes"
                ].apply(
                    local_scope.variables[compiler.ATTRS_ARG_NAME], selectors_for_node
                )
            else:
                dynamic_attributes = codegen.List([])
            attributes = codegen.ListConcat(
                [codegen.List(static_attributes), dynamic_attributes],
                dtypes.List.specialize(a=html.Attribute),
            )

            sub_items = dom_nodes_to_elm(
                list(node.children), expr_replacements, local_scope, compiler_env
            )
            if tag_name in html.ELEMENTS:
                node_constructor = local_scope.variables["Html.{0}".format(tag_name)]
            else:
                node_constructor = local_scope.variables["Html.node"].apply(
                    codegen.String(tag_name)
                )
            item = node_constructor.apply(attributes, sub_items)
            items.append(HtmlList([item]))

    return HtmlListConcat(items)
示例#13
0
 def test_string_join_one(self):
     join = codegen.StringConcat([codegen.String("hello")])
     join = codegen.simplify(join)
     self.assertCodeEqual(join.as_source_code(), '"hello"')