def build_fncall(<EOL>ctx,<EOL>fndoc,<EOL>argdocs=(),<EOL>kwargdocs=(),<EOL>hug_sole_arg=False,<EOL>trailing_comment=None,<EOL>):
if callable(fndoc):<EOL><INDENT>fndoc = general_identifier(fndoc)<EOL><DEDENT>has_comment = bool(trailing_comment)<EOL>argdocs = list(argdocs)<EOL>kwargdocs = list(kwargdocs)<EOL>kwargdocs = [<EOL>(<EOL>comment_doc(<EOL>concat([<EOL>keyword_arg(binding),<EOL>ASSIGN_OP,<EOL>doc.doc<EOL>]),<EOL>doc.annotation.value<EOL>)<EOL>if is_commented(doc)<EOL>else concat([<EOL>keyword_arg(binding),<EOL>ASSIGN_OP,<EOL>doc<EOL>])<EOL>)<EOL>for binding, doc in kwargdocs<EOL>]<EOL>if not (argdocs or kwargdocs):<EOL><INDENT>return concat([<EOL>fndoc,<EOL>LPAREN,<EOL>RPAREN,<EOL>])<EOL><DEDENT>if (<EOL>hug_sole_arg and<EOL>not kwargdocs and<EOL>len(argdocs) == <NUM_LIT:1> and<EOL>not is_commented(argdocs[<NUM_LIT:0>])<EOL>):<EOL><INDENT>return group(<EOL>concat([<EOL>fndoc,<EOL>LPAREN,<EOL>argdocs[<NUM_LIT:0>],<EOL>RPAREN<EOL>])<EOL>)<EOL><DEDENT>allarg_docs = [*argdocs, *kwargdocs]<EOL>if trailing_comment:<EOL><INDENT>allarg_docs.append(commentdoc(trailing_comment))<EOL><DEDENT>parts = []<EOL>for idx, doc in enumerate(allarg_docs):<EOL><INDENT>last = idx == len(allarg_docs) - <NUM_LIT:1><EOL>if is_commented(doc):<EOL><INDENT>has_comment = True<EOL>comment_str = doc.annotation.value<EOL>doc = doc.doc<EOL><DEDENT>else:<EOL><INDENT>comment_str = None<EOL><DEDENT>part = concat([doc, NIL if last else COMMA])<EOL>if comment_str:<EOL><INDENT>part = group(<EOL>flat_choice(<EOL>when_flat=concat([<EOL>part,<EOL>'<STR_LIT:U+0020>',<EOL>commentdoc(comment_str)<EOL>]),<EOL>when_broken=concat([<EOL>commentdoc(comment_str),<EOL>HARDLINE,<EOL>part,<EOL>]),<EOL>)<EOL>)<EOL><DEDENT>if not last:<EOL><INDENT>part = concat([part, HARDLINE if has_comment else LINE])<EOL><DEDENT>parts.append(part)<EOL><DEDENT>outer = (<EOL>always_break<EOL>if has_comment<EOL>else group<EOL>)<EOL>return outer(<EOL>concat([<EOL>fndoc,<EOL>LPAREN,<EOL>nest(<EOL>ctx.indent,<EOL>concat([<EOL>SOFTLINE,<EOL>concat(parts),<EOL>])<EOL>),<EOL>SOFTLINE,<EOL>RPAREN<EOL>])<EOL>)<EOL>
Builds a doc that looks like a function call,
    from docs that represent the function, arguments
    and keyword arguments.

    If ``hug_sole_arg`` is True, and the represented
    functional call is done with a single non-keyword
    argument, the function call parentheses will hug
    the sole argument doc without newlines and indentation
    in break mode. This makes a difference in calls
    like this::

        > hug_sole_arg = False
        frozenset(
            [
                1,
                2,
                3,
                4,
                5
            ]
        )
        > hug_sole_arg = True
        frozenset([
            1,
            2,
            3,
            4,
            5,
        ])

    If ``trailing_comment`` is provided, the text is
    rendered as a comment after the last argument and
    before the closing parenthesis. This will force
    the function call to be broken to multiple lines.