Пример #1
0
    def render(self, tree):
        """Generate the language implementation from the AST"""
        env = Environment(loader=PackageLoader('flatdata.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_reference'] = lambda n: isinstance(n, EnumerationReference)
        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
        env.filters['not_auto_generated'] = lambda n: [ x for x in n if not x.auto_generated]
        self._populate_environment(env)
        template = env.get_template(self._template)

        flatdata_nodes = [n for n, _ in DfsTraversal(tree).dependency_order() if
                          any([isinstance(n, t) for t in self.supported_nodes()])]
        return template.render(nodes=flatdata_nodes, tree=tree)
Пример #2
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