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