예제 #1
0
def test_archive_member_schemas_references_dependent_types():
    root = _build_node_tree("""namespace n{
        struct T { t : u8 : 7; }
        struct U { u : u8 : 7; }
        struct V { v : u8 : 7; }
        archive A {
            a : T;
            b : vector< V >;
            c : multivector< 17, U, V >;
        }
        }
        """)
    resolve_references(root)
    assert_equal(
        SyntaxTree.schema(root.find(".n.A.a")),
        "namespace n { struct T { t : u8 : 7; } }\n"
        "namespace n { a : T; }")
    assert_equal(
        SyntaxTree.schema(root.find(".n.A.b")),
        "namespace n { struct V { v : u8 : 7; } }\n"
        "namespace n { b : vector< V >; }")
    assert_equal(
        SyntaxTree.schema(root.find(".n.A.c")),
        "namespace n { struct U { u : u8 : 7; } }\n"
        "namespace n { struct V { v : u8 : 7; } }\n"
        "namespace n { c : multivector< 17, U, V >; }")
예제 #2
0
def test_schemas_are_not_duplicated_if_several_type_references_occur():
    root = _build_node_tree("""namespace foo{
/// T Comment
struct T { /* fieldA comment*/ fieldA : u8 : 7; }
/**
 * Archive comment
 */
archive A {
    resourceA : T;
    resourceB : T;
}
}
        """)
    resolve_references(root)
    expected = """namespace foo {
struct T
{
    fieldA : u8 : 7;
}
}

namespace foo {
archive A
{
    resourceA : .foo.T;
    resourceB : .foo.T;
}
}

"""
    actual = SyntaxTree.schema(root.find(".foo.A"))
    assert_equal(actual, expected)
예제 #3
0
def test_archive_schemas_include_constants():
    root = build_ast("""namespace foo{
const u8 C = 42;
struct T { f : u8 : 7; }
archive A {
    resourceA : T;
}
}
        """)
    resolve_references(root)
    expected = """namespace foo {
struct T
{
    f : u8 : 7;
}
}

namespace foo {
const u8 C = 42;
}

namespace foo {
archive A
{
    resourceA : .foo.T;
}
}

"""
    actual = SyntaxTree.schema(root.find(".foo.A"))
    assert_equal(actual, expected)
예제 #4
0
def test_archive_schema_preserves_references():
    root = _build_node_tree("""namespace foo{
/// T Comment
struct T { /* fieldA comment*/ fieldA : u8 : 7; }
/**
 * Archive comment
 */
archive A {
    /// resource comment
    resourceA : T;
}
}
        """)
    resolve_references(root)
    expected = """namespace foo {
struct T
{
    fieldA : u8 : 7;
}
}

namespace foo {
archive A
{
    resourceA : .foo.T;
}
}

"""
    assert_equal(SyntaxTree.schema(root.find(".foo.A")), expected)
예제 #5
0
def create_tree_with_topological_ordering():
    return SyntaxTree(
        Node("ns").insert(
            Node("S0"),
            Node("A0").insert(
                Node("R0").insert(refs.TypeReference("ns.A1")),
                Node("R1").insert(refs.TypeReference("ns.S0"))), Node("A1")))
예제 #6
0
def _create_tree_resource_to_archive():
    root = Root().insert(
        nodes.Namespace(name="ns").insert(
            Archive(name="RefArchive"),
            Archive(name="Archive").insert(
                res.Archive(name="resource").insert(
                    refs.ArchiveReference(name="RefArchive")))))
    return SyntaxTree(root)
예제 #7
0
def _create_tree_resource_to_struct_with_extra_folding(actual, reference):
    root = Root().insert(
        nodes.Namespace(name="ns").insert(
            nodes.Namespace(name="fold").insert(nodes.Structure(name=actual)),
            Archive(name="Archive").insert(
                res.Vector(name="resource").insert(
                    refs.StructureReference(name=reference)))))
    return SyntaxTree(root)
예제 #8
0
def _create_tree_with_two_struct_references():
    root = Root().insert(
        nodes.Namespace(name="ns").insert(
            nodes.Structure(name="S1"), nodes.Structure(name="S2"),
            Archive(name="Archive").insert(
                res.Multivector(name="resource").insert(
                    refs.StructureReference(name="S1"),
                    refs.StructureReference(name="S2")))))
    return SyntaxTree(root)
예제 #9
0
 def build(definition):
     root = _build_node_tree(definition=definition)
     _append_builtin_structures(root)
     _append_constant_references(root)
     resolve_references(root)
     #now compute data based on resolved references
     _update_field_type_references(root)
     _compute_structure_sizes(root)
     return SyntaxTree(root)
예제 #10
0
def build_ast(definition):
    """Build the Flatdata syntax tree from a definition"""
    root = _build_node_tree(definition=definition)
    _append_builtin_structures(root)
    _append_constant_references(root)
    resolve_references(root)
    # now compute data based on resolved references
    _update_field_type_references(root)
    _compute_structure_sizes(root)
    return SyntaxTree(root)
예제 #11
0
def _create_tree_with_explicit_reference(name):
    root = Root().insert(
        nodes.Namespace(name="ns").insert(
            nodes.Structure(name="Struct").insert(nodes.Field(name="Field")),
            Archive(name="Archive").insert(
                res.Vector(name="resource").insert(
                    refs.FieldReference(name="Struct.Field"),
                    refs.ResourceReference(name=name)),
                res.Vector(name="resource2"))))
    return SyntaxTree(root)
예제 #12
0
    def render(self, tree):
        env = Environment(loader=PackageLoader('generator', 'templates'), lstrip_blocks=True,
                          trim_blocks=True, autoescape=False, extensions=[RaiseExtension])
        env.filters['is_archive'] = lambda n: isinstance(n, Archive)
        env.filters['is_instance'] = lambda n: isinstance(n, Instance)
        env.filters['is_raw_data'] = lambda n: isinstance(n, RawData)
        env.filters['is_archive_resource'] = lambda n: isinstance(n, ArchiveResource)
        env.filters['is_structure'] = lambda n: isinstance(n, Structure)
        env.filters['is_enumeration'] = lambda n: isinstance(n, Enumeration)
        env.filters['is_constant'] = lambda n: isinstance(n, Constant)
        env.filters['is_namespace'] = lambda n: isinstance(n, Namespace)
        env.filters['is_resource'] = lambda n: isinstance(n, ResourceBase)
        env.filters['is_bound_resource'] = lambda n: isinstance(n, BoundResource)
        env.filters['is_vector'] = lambda n: isinstance(n, Vector)
        env.filters['is_multivector'] = lambda n: isinstance(n, Multivector)
        env.filters['is_multivector_index'] = lambda n: (isinstance(n, Structure) and
            "_builtin.multivector" in SyntaxTree.namespace_path(n))
        env.filters['namespaces'] = SyntaxTree.namespaces
        self._populate_environment(env)
        template = env.get_template(self._template)

        nodes = [n for n, _ in DfsTraversal(tree).dependency_order() if
                 any([isinstance(n, t) for t in self._supported_nodes()])]
        return template.render(nodes=nodes, tree=tree)
예제 #13
0
def create_tree_with_cycle():
    return SyntaxTree(
        Node("a").insert(
            Node("b").insert(Structure("c").insert(refs.TypeReference("a.d"))),
            Node("d").insert(refs.TypeReference("a.b"))))
예제 #14
0
def create_tree_with_type_refs():
    return SyntaxTree(
        Node("a").insert(
            Node("b").insert(Node("d"), refs.TypeReference("a.c.e")),
            Node("c").insert(Node("e"), refs.TypeReference("a.b.d"))))
예제 #15
0
def create_basic_tree():
    return SyntaxTree(
        Node("a").insert(
            Node("b").insert(Node("c"), Node("d"), Node("e")),
            Node("f").insert(Node("g").insert(Node("h")))))
예제 #16
0
 def _is_builtin(node):
     for x in SyntaxTree.namespaces(node):
         if x.name == "_builtin":
             return True
     return False
예제 #17
0
파일: builder.py 프로젝트: ogrian/flatdata
 def build(definition):
     root = _build_node_tree(definition=definition)
     _append_builtin_structures(root)
     _append_constant_references(root)
     resolve_references(root)
     return SyntaxTree(root)
예제 #18
0
    def _populate_environment(self, env):
        def _camel_to_snake_case(expr):
            step1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', expr)
            return re.sub('([a-z0-9])(A-Z)', r'\1_\2', step1).lower()

        env.filters["camel_to_snake_case"] = _camel_to_snake_case

        def _snake_to_upper_camel_case(expr):
            return ''.join(p.title() for p in expr.split('_'))

        env.filters["snake_to_upper_camel_case"] = _snake_to_upper_camel_case

        def _rust_doc(expr):
            lines = [
                re.sub(r'^[ \t]*(/\*\*|/\*|\*/|\*)\s*(.*?)\s*(\*/)?$',
                       r"/// \2", line).strip() for line in expr.split('\n')
            ]
            start = 0
            end = len(lines)
            if lines[0] == "///":
                start = 1
            if lines[-1] == "///":
                end = -1
            return "\n".join(lines[start:end])

        env.filters["rust_doc"] = _rust_doc

        def _escape_rust_keywords(expr):
            if expr in self.RESERVED_KEYWORDS:
                return "{}_".format(expr)
            return expr

        def _field_type(field):
            if isinstance(field.type, EnumType):
                return "{}, {}".format(
                    _fully_qualified_name(field.parent,
                                          field.type_reference.node),
                    field.type_reference.node.type.name)
            return "{}, {}".format(field.type.name, field.type.name)

        def _fully_qualified_name(current, node):
            return "::".join(
                (current.path_depth() - 1) * ["super"]) + node.path_with("::")

        env.globals["fully_qualified_name"] = _fully_qualified_name
        env.filters["escape_rust_keywords"] = _escape_rust_keywords
        env.filters["field_type"] = _field_type
        env.filters['structure_references'] = lambda ls: [
            x for x in ls
            if (isinstance(x.node, Structure) and "_builtin.multivector" not in
                SyntaxTree.namespace_path(x.node))
        ]
        env.filters['instance_resources'] = lambda ls: [
            x for x in ls if isinstance(x, Instance)
        ]
        env.filters['vector_resources'] = lambda ls: [
            x for x in ls if isinstance(x, Vector)
        ]
        env.filters['multivector_resources'] = lambda ls: [
            x for x in ls if isinstance(x, Multivector)
        ]
        env.filters['rawdata_resources'] = lambda ls: [
            x for x in ls if isinstance(x, RawData)
        ]
        env.filters['subarchive_resources'] = lambda ls: [
            x for x in ls if isinstance(x, ArchiveResource)
        ]

        env.filters["supported_resources"] = lambda l: [
            x for x in l if not isinstance(x, BoundResource)
        ]

        env.filters[
            "format_numeric_literal"] = RustGenerator._format_numeric_literal