src/basilisp/lang/compiler/parser.py
def __deftype_impls(  # pylint: disable=too-many-branches
    ctx: ParserContext, form: ISeq
) -> Tuple[List[DefTypeBase], List[Method]]:
    """Roll up deftype* declared bases and method implementations."""
    current_interface_sym: Optional[sym.Symbol] = None
    current_interface: Optional[DefTypeBase] = None
    interfaces = []
    methods: List[Method] = []
    interface_methods: MutableMapping[sym.Symbol, List[Method]] = {}
    for elem in form:
        if isinstance(elem, sym.Symbol):
            if current_interface is not None:
                if current_interface_sym in interface_methods:
                    raise ParserException(
                        f"deftype* forms may only implement an interface once",
                        form=elem,
                    )
                assert (
                    current_interface_sym is not None
                ), "Symbol must be defined with interface"
                interface_methods[current_interface_sym] = methods

            current_interface_sym = elem
            current_interface = _parse_ast(ctx, elem)
            methods = []

            if not isinstance(current_interface, (MaybeClass, MaybeHostForm, VarRef)):
                raise ParserException(
                    f"deftype* interface implementation must be an existing interface",
                    form=elem,
                )
            interfaces.append(current_interface)
        elif isinstance(elem, ISeq):
            if current_interface is None:
                raise ParserException(
                    f"deftype* method cannot be declared without interface", form=elem
                )
            methods.append(__deftype_method(ctx, elem, current_interface))
        else:
            raise ParserException(
                f"deftype* must consist of interface or protocol names and methods",
                form=elem,
            )

    if current_interface is not None:
        if len(methods) > 0:
            if current_interface_sym in interface_methods:
                raise ParserException(
                    f"deftype* forms may only implement an interface once",
                    form=current_interface_sym,
                )
            assert (
                current_interface_sym is not None
            ), "Symbol must be defined with interface"
            interface_methods[current_interface_sym] = methods
        else:
            raise ParserException(
                f"deftype* may not declare interface without at least one method",
                form=current_interface_sym,
            )

    return interfaces, list(chain.from_iterable(interface_methods.values()))
def __deftype_impls(  # pylint: disable=too-many-branches
    ctx: ParserContext, form: ISeq
) -> Tuple[List[DefTypeBase], List[Method]]:
    """Roll up deftype* declared bases and method implementations."""
    current_interface_sym: Optional[sym.Symbol] = None
    current_interface: Optional[DefTypeBase] = None
    interfaces = []
    methods: List[Method] = []
    interface_methods: MutableMapping[sym.Symbol, List[Method]] = {}
    for elem in form:
        if isinstance(elem, sym.Symbol):
            if current_interface is not None:
                if current_interface_sym in interface_methods:
                    raise ParserException(
                        f"deftype* forms may only implement an interface once",
                        form=elem,
                    )
                assert (
                    current_interface_sym is not None
                ), "Symbol must be defined with interface"
                interface_methods[current_interface_sym] = methods

            current_interface_sym = elem
            current_interface = _parse_ast(ctx, elem)
            methods = []

            if not isinstance(current_interface, (MaybeClass, MaybeHostForm, VarRef)):
                raise ParserException(
                    f"deftype* interface implementation must be an existing interface",
                    form=elem,
                )
            interfaces.append(current_interface)
        elif isinstance(elem, ISeq):
            if current_interface is None:
                raise ParserException(
                    f"deftype* method cannot be declared without interface", form=elem
                )
            methods.append(__deftype_method(ctx, elem, current_interface))
        else:
            raise ParserException(
                f"deftype* must consist of interface or protocol names and methods",
                form=elem,
            )

    if current_interface is not None:
        if len(methods) > 0:
            if current_interface_sym in interface_methods:
                raise ParserException(
                    f"deftype* forms may only implement an interface once",
                    form=current_interface_sym,
                )
            assert (
                current_interface_sym is not None
            ), "Symbol must be defined with interface"
            interface_methods[current_interface_sym] = methods
        else:
            raise ParserException(
                f"deftype* may not declare interface without at least one method",
                form=current_interface_sym,
            )

    return interfaces, list(chain.from_iterable(interface_methods.values()))
Roll up deftype* declared bases and method implementations.