Repository: JuliaLang/julia
File: JuliaSyntax/src/julia/parser.jl (Julia)

Code before:
        #
        # (The flisp parser only considers commas before `;` and thus gets this
        # last case wrong)
        op_pos = bump_dotted(ps, op_dotted, emit_dot_node=true, remap_kind=K"Identifier")

        space_before_paren = preceding_whitespace(t2)
        if space_before_paren
            # Setup possible whitespace error between operator and (
            ws_mark = position(ps)
            bump_trivia(ps)
            ws_error_pos = emit(ps, ws_mark, K"TOMBSTONE")
            ws_mark_end = position(ps)
        end

        mark_before_paren = position(ps)
        bump(ps, TRIVIA_FLAG) # (
        initial_semi = peek(ps, skip_newlines=true) == K";"
        opts = parse_brackets(ps, K")") do had_commas, had_splat, num_semis, num_subexprs
            is_paren_call = had_commas || had_splat               ||
                            (initial_semi && num_subexprs > 0)    ||
                            (initial_semi && num_semis == 1)      ||
                            (num_semis == 0 && num_subexprs == 0)
            return (needs_parameters=is_paren_call,
                    is_paren_call=is_paren_call,
                    is_block=!is_paren_call && num_semis > 0)
        end

        # The precedence between unary + and any following infix ^ depends on
        # whether the parens are a function call or not
        if opts.is_paren_call
            if space_before_paren
                # Whitespace not allowed before prefix function call bracket
                # + (a,b)   ==> (call + (error) a b)
                reset_node!(ps, ws_error_pos, kind=K"error")
                emit_diagnostic(ps, ws_mark, ws_mark_end,
                                error="whitespace not allowed between prefix function call and argument list")
            end
            # Prefix function calls for operators which are both binary and unary
            # +(a,b)    ==>  (call + a b)
            # +(a=1,)   ==>  (call + (= a 1))
            # +(a...)   ==>  (call + (... a))
            # +(a;b,c)  ==>  (call + a (parameters b c))
            # +(;a)     ==>  (call + (parameters a))
            # +()       ==>  (call +)
            # Prefix calls have higher precedence than ^
            # +(a,b)^2  ==>  (call-i (call + a b) ^ 2)
            # +(a,b)(x)^2  ==>  (call-i (call (call + a b) x) ^ 2)
            if is_type_operator(op_t, op_dotted)
                # <:(a,)  ==>  (<: a)
                emit(ps, mark, op_k, opts.delim_flags)
                reset_node!(ps, op_pos, flags=TRIVIA_FLAG, kind=op_k)

Review comment (suggestion):
Possibly neater?

```suggestion
        end
        opts::NamedTuple{(:needs_parameters, :is_paren_call, :is_block, :delim_flags), Tuple{Bool, Bool, Bool, RawFlags}}
```

Code after:
        #
        # (The flisp parser only considers commas before `;` and thus gets this
        # last case wrong)
        op_pos = bump_dotted(ps, op_dotted, emit_dot_node=true, remap_kind=K"Identifier")

        space_before_paren = preceding_whitespace(t2)
        if space_before_paren
            # Setup possible whitespace error between operator and (
            ws_mark = position(ps)
            bump_trivia(ps)
            ws_error_pos = emit(ps, ws_mark, K"TOMBSTONE")
            ws_mark_end = position(ps)
        end

        mark_before_paren = position(ps)
        bump(ps, TRIVIA_FLAG) # (
        initial_semi = peek(ps, skip_newlines=true) == K";"
        opts = parse_brackets(ps, K")") do had_commas, had_splat, num_semis, num_subexprs
            is_paren_call = had_commas || had_splat               ||
                            (initial_semi && num_subexprs > 0)    ||
                            (initial_semi && num_semis == 1)      ||
                            (num_semis == 0 && num_subexprs == 0)
            return (needs_parameters=is_paren_call,
                    is_paren_call=is_paren_call,
                    is_block=!is_paren_call && num_semis > 0)
        end::NamedTuple{(:needs_parameters, :is_paren_call, :is_block, :delim_flags), Tuple{Bool, Bool, Bool, RawFlags}}

        # The precedence between unary + and any following infix ^ depends on
        # whether the parens are a function call or not
        if opts.is_paren_call
            if space_before_paren
                # Whitespace not allowed before prefix function call bracket
                # + (a,b)   ==> (call + (error) a b)
                reset_node!(ps, ws_error_pos, kind=K"error")
                emit_diagnostic(ps, ws_mark, ws_mark_end,
                                error="whitespace not allowed between prefix function call and argument list")
            end
            # Prefix function calls for operators which are both binary and unary
            # +(a,b)    ==>  (call + a b)
            # +(a=1,)   ==>  (call + (= a 1))
            # +(a...)   ==>  (call + (... a))
            # +(a;b,c)  ==>  (call + a (parameters b c))
            # +(;a)     ==>  (call + (parameters a))
            # +()       ==>  (call +)
            # Prefix calls have higher precedence than ^
            # +(a,b)^2  ==>  (call-i (call + a b) ^ 2)
            # +(a,b)(x)^2  ==>  (call-i (call (call + a b) x) ^ 2)
            if is_type_operator(op_t, op_dotted)
                # <:(a,)  ==>  (<: a)
                emit(ps, mark, op_k, opts.delim_flags)
                reset_node!(ps, op_pos, flags=TRIVIA_FLAG, kind=op_k)