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)
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