xref: /libCEED/julia/LibCEED.jl/.style/ceed_style.jl (revision bf185410af015d53ed6d3b520013ce284095d550)
1ee83402cSWill Paznerusing JuliaFormatter, CSTParser, Tokenize
2ee83402cSWill Pazner
3ee83402cSWill Paznerfor name in names(JuliaFormatter, all=true)
4*bf185410SWill Pazner    if name != :include && name != :eval && name != Base.Docs.META
5ee83402cSWill Pazner        @eval import JuliaFormatter: $name
6ee83402cSWill Pazner    end
7ee83402cSWill Paznerend
8ee83402cSWill Pazner
9ee83402cSWill Pazner# Same as DefaultStyle, but no space in between operators with precedence CSTParser.TimesOp
10ee83402cSWill Paznerstruct CeedStyle <: AbstractStyle end
11ee83402cSWill Pazner
12ee83402cSWill Paznergetstyle(s::CeedStyle) = s
13ee83402cSWill Pazner
14ee83402cSWill Paznerfunction p_binaryopcall(
15ee83402cSWill Pazner    style::CeedStyle,
16ee83402cSWill Pazner    cst::CSTParser.EXPR,
17ee83402cSWill Pazner    s::State;
18ee83402cSWill Pazner    nonest=false,
19ee83402cSWill Pazner    nospace=false,
20ee83402cSWill Pazner)
21ee83402cSWill Pazner    t = FST(cst, nspaces(s))
22ee83402cSWill Pazner    op = cst[2]
23ee83402cSWill Pazner    nonest = nonest || op.kind === Tokens.COLON
24ee83402cSWill Pazner    if cst.parent.typ === CSTParser.Curly &&
25ee83402cSWill Pazner       op.kind in (Tokens.ISSUBTYPE, Tokens.ISSUPERTYPE) &&
26ee83402cSWill Pazner       !s.opts.whitespace_typedefs
27ee83402cSWill Pazner        nospace = true
28ee83402cSWill Pazner    elseif op.kind === Tokens.COLON
29ee83402cSWill Pazner        nospace = true
30ee83402cSWill Pazner    end
31ee83402cSWill Pazner    nospace_args = s.opts.whitespace_ops_in_indices ? false : nospace
32ee83402cSWill Pazner
33ee83402cSWill Pazner    if is_opcall(cst[1])
34ee83402cSWill Pazner        n = pretty(style, cst[1], s, nonest=nonest, nospace=nospace_args)
35ee83402cSWill Pazner    else
36ee83402cSWill Pazner        n = pretty(style, cst[1], s)
37ee83402cSWill Pazner    end
38ee83402cSWill Pazner
39ee83402cSWill Pazner    if op.kind === Tokens.COLON &&
40ee83402cSWill Pazner       s.opts.whitespace_ops_in_indices &&
41ee83402cSWill Pazner       !is_leaf(cst[1]) &&
42ee83402cSWill Pazner       !is_iterable(cst[1])
43ee83402cSWill Pazner        paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, "(")
44ee83402cSWill Pazner        add_node!(t, paren, s)
45ee83402cSWill Pazner        add_node!(t, n, s, join_lines=true)
46ee83402cSWill Pazner        paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, ")")
47ee83402cSWill Pazner        add_node!(t, paren, s, join_lines=true)
48ee83402cSWill Pazner    else
49ee83402cSWill Pazner        add_node!(t, n, s)
50ee83402cSWill Pazner    end
51ee83402cSWill Pazner
52ee83402cSWill Pazner    nrhs = nest_rhs(cst)
53ee83402cSWill Pazner    nrhs && (t.nest_behavior = AlwaysNest)
54ee83402cSWill Pazner    nest = (nestable(style, cst) && !nonest) || nrhs
55ee83402cSWill Pazner
56ee83402cSWill Pazner    if op.fullspan == 0
57ee83402cSWill Pazner        # Do nothing - represents a binary op with no textual representation.
58ee83402cSWill Pazner        # For example: `2a`, which is equivalent to `2 * a`.
59ee83402cSWill Pazner    elseif op.kind === Tokens.EX_OR
60ee83402cSWill Pazner        add_node!(t, Whitespace(1), s)
61ee83402cSWill Pazner        add_node!(t, pretty(style, op, s), s, join_lines=true)
62ee83402cSWill Pazner    elseif (is_number(cst[1]) || op.kind === Tokens.CIRCUMFLEX_ACCENT) && op.dot
63ee83402cSWill Pazner        add_node!(t, Whitespace(1), s)
64ee83402cSWill Pazner        add_node!(t, pretty(style, op, s), s, join_lines=true)
65ee83402cSWill Pazner        nest ? add_node!(t, Placeholder(1), s) : add_node!(t, Whitespace(1), s)
66ee83402cSWill Pazner    elseif op.kind !== Tokens.IN && (
67ee83402cSWill Pazner        nospace || (
68ee83402cSWill Pazner            op.kind !== Tokens.ANON_FUNC && CSTParser.precedence(op) in (
69ee83402cSWill Pazner                CSTParser.ColonOp,
70ee83402cSWill Pazner                CSTParser.PowerOp,
71ee83402cSWill Pazner                CSTParser.DeclarationOp,
72ee83402cSWill Pazner                CSTParser.DotOp,
73ee83402cSWill Pazner                CSTParser.TimesOp,
74ee83402cSWill Pazner            )
75ee83402cSWill Pazner        )
76ee83402cSWill Pazner    )
77ee83402cSWill Pazner        add_node!(t, pretty(style, op, s), s, join_lines=true)
78ee83402cSWill Pazner    else
79ee83402cSWill Pazner        add_node!(t, Whitespace(1), s)
80ee83402cSWill Pazner        add_node!(t, pretty(style, op, s), s, join_lines=true)
81ee83402cSWill Pazner        nest ? add_node!(t, Placeholder(1), s) : add_node!(t, Whitespace(1), s)
82ee83402cSWill Pazner    end
83ee83402cSWill Pazner
84ee83402cSWill Pazner    if is_opcall(cst[3])
85ee83402cSWill Pazner        n = pretty(style, cst[3], s, nonest=nonest, nospace=nospace_args)
86ee83402cSWill Pazner    else
87ee83402cSWill Pazner        n = pretty(style, cst[3], s)
88ee83402cSWill Pazner    end
89ee83402cSWill Pazner
90ee83402cSWill Pazner    if op.kind === Tokens.COLON &&
91ee83402cSWill Pazner       s.opts.whitespace_ops_in_indices &&
92ee83402cSWill Pazner       !is_leaf(cst[3]) &&
93ee83402cSWill Pazner       !is_iterable(cst[3])
94ee83402cSWill Pazner        paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, "(")
95ee83402cSWill Pazner        add_node!(t, paren, s, join_lines=true)
96ee83402cSWill Pazner        add_node!(t, n, s, join_lines=true)
97ee83402cSWill Pazner        paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, ")")
98ee83402cSWill Pazner        add_node!(t, paren, s, join_lines=true)
99ee83402cSWill Pazner    else
100ee83402cSWill Pazner        add_node!(t, n, s, join_lines=true)
101ee83402cSWill Pazner    end
102ee83402cSWill Pazner
103ee83402cSWill Pazner    if nest
104ee83402cSWill Pazner        # for indent, will be converted to `indent` if needed
105ee83402cSWill Pazner        insert!(t.nodes, length(t.nodes), Placeholder(0))
106ee83402cSWill Pazner    end
107ee83402cSWill Pazner
108ee83402cSWill Pazner    t
109ee83402cSWill Paznerend
110ee83402cSWill Pazner
111ee83402cSWill Paznerfunction p_chainopcall(
112ee83402cSWill Pazner    style::CeedStyle,
113ee83402cSWill Pazner    cst::CSTParser.EXPR,
114ee83402cSWill Pazner    s::State;
115ee83402cSWill Pazner    nonest=false,
116ee83402cSWill Pazner    nospace=false,
117ee83402cSWill Pazner)
118ee83402cSWill Pazner    t = FST(cst, nspaces(s))
119ee83402cSWill Pazner
120ee83402cSWill Pazner    # Check if there's a number literal on the LHS of a dot operator.
121ee83402cSWill Pazner    # In this case we need to surround the dot operator with whitespace
122ee83402cSWill Pazner    # in order to avoid ambiguity.
123ee83402cSWill Pazner    for (i, a) in enumerate(cst)
124ee83402cSWill Pazner        if a.typ === CSTParser.OPERATOR && a.dot && is_number(cst[i-1])
125ee83402cSWill Pazner            nospace = false
126ee83402cSWill Pazner            break
127ee83402cSWill Pazner        end
128ee83402cSWill Pazner    end
129ee83402cSWill Pazner
130ee83402cSWill Pazner    nws = nospace ? 0 : 1
131ee83402cSWill Pazner    for (i, a) in enumerate(cst)
132ee83402cSWill Pazner        if a.typ === CSTParser.OPERATOR
133ee83402cSWill Pazner            nws_op = (CSTParser.precedence(a) == CSTParser.TimesOp) ? 0 : nws
134ee83402cSWill Pazner            add_node!(t, Whitespace(nws_op), s)
135ee83402cSWill Pazner            add_node!(t, pretty(style, a, s), s, join_lines=true)
136ee83402cSWill Pazner            if nonest
137ee83402cSWill Pazner                add_node!(t, Whitespace(nws_op), s)
138ee83402cSWill Pazner            else
139ee83402cSWill Pazner                add_node!(t, Placeholder(nws_op), s)
140ee83402cSWill Pazner            end
141ee83402cSWill Pazner        elseif is_opcall(a)
142ee83402cSWill Pazner            add_node!(
143ee83402cSWill Pazner                t,
144ee83402cSWill Pazner                pretty(style, a, s, nospace=nospace, nonest=nonest),
145ee83402cSWill Pazner                s,
146ee83402cSWill Pazner                join_lines=true,
147ee83402cSWill Pazner            )
148ee83402cSWill Pazner        elseif i == length(cst) - 1 && is_punc(a) && is_punc(cst[i+1])
149ee83402cSWill Pazner            add_node!(t, pretty(style, a, s), s, join_lines=true)
150ee83402cSWill Pazner        else
151ee83402cSWill Pazner            add_node!(t, pretty(style, a, s), s, join_lines=true)
152ee83402cSWill Pazner        end
153ee83402cSWill Pazner    end
154ee83402cSWill Pazner    t
155ee83402cSWill Paznerend
156ee83402cSWill Pazner
157ee83402cSWill Paznerprefix_path(fname) = joinpath(@__DIR__, "..", fname)
158ee83402cSWill Paznerformat(
159ee83402cSWill Pazner    prefix_path.(["src", "test", "examples", ".style"]),
160ee83402cSWill Pazner    style=CeedStyle(),
161ee83402cSWill Pazner    indent=4,
162ee83402cSWill Pazner    margin=92,
163ee83402cSWill Pazner    remove_extra_newlines=true,
164ee83402cSWill Pazner    whitespace_in_kwargs=false,
165ee83402cSWill Pazner)
166