Skip to content

Commit

Permalink
Fix <: and >: without LHS
Browse files Browse the repository at this point in the history
This patch fixes formatting of <: and >: when used without LHS. This is
again an inconsistency compared to other operators.
  • Loading branch information
fredrikekre committed May 29, 2024
1 parent a0b7eb2 commit a181b65
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
24 changes: 24 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions src/chisels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 8 additions & 7 deletions src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 changes: 8 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit a181b65

Please sign in to comment.