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