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