Browse Source

Fix <: and >: without LHS

This patch fixes formatting of <: and >: when used without LHS. This is
again an inconsistency compared to other operators.
pull/19/head
Fredrik Ekre 2 years ago
parent
commit
a181b65baa
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 24
      TODO.md
  2. 5
      src/chisels.jl
  3. 15
      src/runestone.jl
  4. 10
      test/runtests.jl

24
TODO.md

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
# TODOs, notes, and various thoughts
## Inconsistencies
- The `spaces_around_operators` rule have the following inconsistencies.
- `:`, `^`, and `::` instead fall under `no_spaces_around_colon_etc`:
```julia
# current formatting # "consistent" formatting
a:b a : b ✖
a^b a ^ b ✖
a::b a :: b ✖
```
- `<:` and `<:` fall under `no_spaces_around_colon_etc` if they have no LHS:
```julia
# current formatting # "consistent" formatting
a <: b a <: b
a >: b a >: b ✔
a{c <: b} a{c <: b}
a{c >: b} a{c >: b} ✔
a{<:b} a{<: b}
a{>:b} a{>: b} ✖
```

5
src/chisels.jl

@ -49,6 +49,11 @@ function first_leaf(node::JuliaSyntax.GreenNode) @@ -49,6 +49,11 @@ function first_leaf(node::JuliaSyntax.GreenNode)
end
end
# Return number of non-whitespace children
function n_children(node::JuliaSyntax.GreenNode)
return is_leaf(node) ? 0 : count(!JuliaSyntax.is_whitespace, verified_children(node))
end
# This function exist so that we can type-assert the return value to narrow it down from
# `Union{Tuple{}, Vector{JuliaSyntax.GreenNode}}` to `Vector{JuliaSyntax.GreenNode}`. Must
# only be called after verifying that the node has children.

15
src/runestone.jl

@ -271,7 +271,7 @@ end @@ -271,7 +271,7 @@ end
function spaces_around_operators(ctx::Context, node::JuliaSyntax.GreenNode)
if !(
(is_infix_op_call(node) && !(JuliaSyntax.kind(infix_op_call_op(node)) in KSet": ^")) ||
(JuliaSyntax.kind(node) in KSet"<: >:" && !is_leaf(node)) ||
(JuliaSyntax.kind(node) in KSet"<: >:" && n_children(node) == 3) ||
(JuliaSyntax.kind(node) === K"comparison" && !JuliaSyntax.is_trivia(node))
)
return nothing
@ -308,9 +308,9 @@ function no_spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) @@ -308,9 +308,9 @@ function no_spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F)
looking_for_x = false
# K"::" is a special case here since it can be used without an LHS in e.g. function
# definitions like `f(::Int) = ...`.
if JuliaSyntax.kind(node) === K"::"
# K"::", K"<:", and K">:" are special cases here since they can be used without an LHS
# in e.g. `f(::Int) = ...` and `Vector{<:Real}`.
if JuliaSyntax.kind(node) in KSet":: <: >:"
looking_for_x = is_x(first_non_whitespace_child(node))::Bool
end
@ -354,11 +354,12 @@ end @@ -354,11 +354,12 @@ end
function no_spaces_around_colon_etc(ctx::Context, node::JuliaSyntax.GreenNode)
if !(
(is_infix_op_call(node) && JuliaSyntax.kind(infix_op_call_op(node)) in KSet": ^") ||
(JuliaSyntax.kind(node) === K"::" && !is_leaf(node))
(JuliaSyntax.kind(node) === K"::" && !is_leaf(node)) ||
(JuliaSyntax.kind(node) in KSet"<: >:" && n_children(node) == 2)
)
return nothing
end
@assert JuliaSyntax.kind(node) in KSet"call ::"
is_x = x -> is_leaf(x) && JuliaSyntax.kind(x) in KSet": ^ ::"
@assert JuliaSyntax.kind(node) in KSet"call :: <: >:"
is_x = x -> is_leaf(x) && JuliaSyntax.kind(x) in KSet": ^ :: <: >:"
return no_spaces_around_x(ctx, node, is_x)
end

10
test/runtests.jl

@ -187,17 +187,23 @@ end @@ -187,17 +187,23 @@ end
end
@testset "whitespace around <: and >:, no whitespace around ::" begin
# K"::"
# K"::" with both LHS and RHS
@test format_string("a::T") == "a::T"
@test format_string("a::T::S") == "a::T::S"
@test format_string("a :: T") == "a::T"
# K"::" with just RHS
@test format_string("f(::T)::T = 1") == "f(::T)::T = 1"
@test format_string("f(:: T) :: T = 1") == "f(::T)::T = 1"
# K"<:" and K">:"
# K"<:" and K">:" with both LHS and RHS
@test format_string("a<:T") == "a <: T"
@test format_string("a>:T") == "a >: T"
@test format_string("a <: T") == "a <: T"
@test format_string("a >: T") == "a >: T"
# K"<:" and K">:" with just RHS
@test format_string("V{<:T}") == "V{<:T}"
@test format_string("V{<: T}") == "V{<:T}"
@test format_string("V{>:T}") == "V{>:T}"
@test format_string("V{>: T}") == "V{>:T}"
# K"comparison" for chains
@test format_string("a<:T<:S") == "a <: T <: S"
@test format_string("a>:T>:S") == "a >: T >: S"

Loading…
Cancel
Save