src/basilisp/lang/compiler/generator.py
def _deftype_to_py_ast(  # pylint: disable=too-many-branches
    ctx: GeneratorContext, node: DefType
) -> GeneratedPyAST:
    """Return a Python AST Node for a `deftype*` expression."""
    assert node.op == NodeOp.DEFTYPE
    type_name = munge(node.name)
    ctx.symbol_table.new_symbol(sym.symbol(node.name), type_name, LocalType.DEFTYPE)

    bases = []
    for base in node.interfaces:
        base_node = gen_py_ast(ctx, base)
        assert (
            count(base_node.dependencies) == 0
        ), "Class and host form nodes do not have dependencies"
        bases.append(base_node.node)

    decorator = ast.Call(
        func=_ATTR_CLASS_DECORATOR_NAME,
        args=[],
        keywords=[
            ast.keyword(arg="cmp", value=ast.NameConstant(False)),
            ast.keyword(arg="frozen", value=ast.NameConstant(node.is_frozen)),
            ast.keyword(arg="slots", value=ast.NameConstant(True)),
        ],
    )

    with ctx.new_symbol_table(node.name):
        type_nodes = []
        for field in node.fields:
            safe_field = munge(field.name)
            type_nodes.append(
                ast.Assign(
                    targets=[ast.Name(id=safe_field, ctx=ast.Store())],
                    value=ast.Call(func=_ATTRIB_FIELD_FN_NAME, args=[], keywords=[]),
                )
            )
            ctx.symbol_table.new_symbol(sym.symbol(field.name), safe_field, field.local)

        type_deps: List[ast.AST] = []
        for method in node.methods:
            type_ast = __deftype_method_to_py_ast(ctx, method)
            type_nodes.append(type_ast.node)
            type_deps.extend(type_ast.dependencies)

        return GeneratedPyAST(
            node=ast.Name(id=type_name, ctx=ast.Load()),
            dependencies=list(
                chain(
                    type_deps,
                    [
                        ast.ClassDef(
                            name=type_name,
                            bases=bases,
                            keywords=[],
                            body=type_nodes,
                            decorator_list=[decorator],
                        )
                    ],
                )
            ),
        )
def _deftype_to_py_ast(  # pylint: disable=too-many-branches
    ctx: GeneratorContext, node: DefType
) -> GeneratedPyAST:
    """Return a Python AST Node for a `deftype*` expression."""
    assert node.op == NodeOp.DEFTYPE
    type_name = munge(node.name)
    ctx.symbol_table.new_symbol(sym.symbol(node.name), type_name, LocalType.DEFTYPE)

    bases = []
    for base in node.interfaces:
        base_node = gen_py_ast(ctx, base)
        assert (
            count(base_node.dependencies) == 0
        ), "Class and host form nodes do not have dependencies"
        bases.append(base_node.node)

    decorator = ast.Call(
        func=_ATTR_CLASS_DECORATOR_NAME,
        args=[],
        keywords=[
            ast.keyword(arg="cmp", value=ast.NameConstant(False)),
            ast.keyword(arg="frozen", value=ast.NameConstant(node.is_frozen)),
            ast.keyword(arg="slots", value=ast.NameConstant(True)),
        ],
    )

    with ctx.new_symbol_table(node.name):
        type_nodes = []
        for field in node.fields:
            safe_field = munge(field.name)
            type_nodes.append(
                ast.Assign(
                    targets=[ast.Name(id=safe_field, ctx=ast.Store())],
                    value=ast.Call(func=_ATTRIB_FIELD_FN_NAME, args=[], keywords=[]),
                )
            )
            ctx.symbol_table.new_symbol(sym.symbol(field.name), safe_field, field.local)

        type_deps: List[ast.AST] = []
        for method in node.methods:
            type_ast = __deftype_method_to_py_ast(ctx, method)
            type_nodes.append(type_ast.node)
            type_deps.extend(type_ast.dependencies)

        return GeneratedPyAST(
            node=ast.Name(id=type_name, ctx=ast.Load()),
            dependencies=list(
                chain(
                    type_deps,
                    [
                        ast.ClassDef(
                            name=type_name,
                            bases=bases,
                            keywords=[],
                            body=type_nodes,
                            decorator_list=[decorator],
                        )
                    ],
                )
            ),
        )
Return a Python AST Node for a `deftype*` expression.