diff --git a/src/runestone.jl b/src/runestone.jl index 127717e..e9001ec 100644 --- a/src/runestone.jl +++ b/src/runestone.jl @@ -151,10 +151,6 @@ end function spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) where F # TODO: So much boilerplate here... @assert JuliaSyntax.haschildren(node) - # TODO: Can't handle NewlineWs here right now - if any(JuliaSyntax.kind(c) === K"NewlineWs" for c in JuliaSyntax.children(node)) - return nothing - end children = verified_children(node) children′ = children @@ -172,12 +168,14 @@ function spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) whe for (i, child) in pairs(children) span_sum += JuliaSyntax.span(child) - if i == 1 && JuliaSyntax.kind(child) === K"Whitespace" - # If the first child is whitespace it will be accepted as is even if the span is - # larger than one since we don't look behind. The whitespace pass for the parent - # node should trim it later (if not already done). + if JuliaSyntax.kind(child) === K"NewlineWs" || + (i == 1 && JuliaSyntax.kind(child) === K"Whitespace") + # NewlineWs are accepted as is by this pass. + # Whitespace is accepted as is if this is the first child even if the span is + # larger than we expect since we don't look backwards. It should be cleaned up + # by some other pass. accept_node!(ctx, child) - @assert !any_changes + any_changes && push!(children′, child) looking_for_whitespace = false elseif looking_for_whitespace if JuliaSyntax.kind(child) === K"Whitespace" && JuliaSyntax.span(child) == 1 @@ -225,6 +223,14 @@ function spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) whe end push!(children′, child′) end + elseif JuliaSyntax.haschildren(child) && + JuliaSyntax.kind(first_leaf(child)) === K"NewlineWs" + # NewlineWs have to be accepted as is + accept_node!(ctx, child) + any_changes && push!(children′, child) + looking_for_whitespace = JuliaSyntax.kind(last_leaf(child)) !== K"Whitespace" + @assert !is_x(child)::Bool + looking_for_x = true else # Not a whitespace node, insert one any_changes = true @@ -244,7 +250,8 @@ function spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) whe if looking_for_x @assert is_x(child)::Bool end - looking_for_x = !looking_for_x + # Flip the switch, unless child is a comment + looking_for_x = JuliaSyntax.kind(child) === K"Comment" ? looking_for_x : !looking_for_x end else # !expect_ws if looking_for_x @@ -254,7 +261,8 @@ function spaces_around_x(ctx::Context, node::JuliaSyntax.GreenNode, is_x::F) whe any_changes && push!(children′, child) accept_node!(ctx, child) looking_for_whitespace = JuliaSyntax.kind(last_leaf(child)) !== K"Whitespace" - looking_for_x = !looking_for_x + # Flip the switch, unless child is a comment + looking_for_x = JuliaSyntax.kind(child) === K"Comment" ? looking_for_x : !looking_for_x end end # Reset stream diff --git a/test/runtests.jl b/test/runtests.jl index c4884c9..ccc88eb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -42,7 +42,7 @@ end ("0o" * z(n) * "1" => "0o001" for n in 0:2)..., "0o377" => "0o377", # typemax(UInt8) # Octal UInt16 - "0o400" => "0o000400", # typemax(UInt8) + 1 + "0o400" => "0o000400", # typemax(UInt8) + 1 ("0o" * z(n) * "1" => "0o000001" for n in 3:5)..., "0o177777" => "0o177777", # typemax(UInt16) # Octal UInt32 @@ -126,6 +126,12 @@ end # call() op call() op call() @test format_string("$(sp)sin(α)$(sp)$(op)$(sp)cos(β)$(sp)$(op)$(sp)tan(γ)$(sp)") == "$(sp)sin(α) $(op) cos(β) $(op) tan(γ)$(sp)" + # a op \n b + @test format_string("$(sp)a$(sp)$(op)$(sp)\nb$(sp)") == + "$(sp)a $(op)\nb$(sp)" + # a op # comment \n b + @test format_string("$(sp)a$(sp)$(op)$(sp)# comment\nb$(sp)") == + "$(sp)a $(op) # comment\nb$(sp)" end # Exceptions to the rule: `:` and `^` # a:b @@ -146,6 +152,9 @@ end # Edgecase when using whitespace from the next leaf but the call chain continues # after with more children. @test format_string("$(sp)z$(sp)+$(sp)2x$(sp)+$(sp)z$(sp)") == "$(sp)z + 2x + z$(sp)" + # Edgecase where the NewlineWs ends up inside the second call in a chain + @test format_string("$(sp)a$(sp)\\$(sp)b$(sp)≈ $(sp)\n$(sp)c$(sp)\\$(sp)d$(sp)") == + "$(sp)a \\ b ≈\n$(sp)c \\ d$(sp)" end end