mirror of https://github.com/fredrikekre/Runic.jl
2 changed files with 103 additions and 80 deletions
@ -0,0 +1,89 @@ |
|||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
# This is the runestone where all the formatting transformations are implemented. |
||||||
|
|
||||||
|
function trim_trailing_whitespace(ctx::Context, node::JuliaSyntax.GreenNode) |
||||||
|
JuliaSyntax.kind(node) === K"NewlineWs" || return nothing |
||||||
|
@assert !JuliaSyntax.haschildren(node) |
||||||
|
str = String(node_bytes(ctx, node)) |
||||||
|
str′ = replace(str, r"\h*(\r\n|\r|\n)" => '\n') |
||||||
|
# If the next sibling is also a NewlineWs we can trim trailing |
||||||
|
# whitespace from this node too |
||||||
|
next_kind = next_sibling_kind(ctx) |
||||||
|
if next_kind === K"NewlineWs" |
||||||
|
# str′ = replace(str′, r"(\r\n|\r|\n)\h*" => '\n') |
||||||
|
str′ = replace(str′, r"\n\h*" => '\n') |
||||||
|
end |
||||||
|
if str == str′ |
||||||
|
return nothing |
||||||
|
end |
||||||
|
# Write new bytes and reset the stream |
||||||
|
nb = write_and_reset(ctx, str′) |
||||||
|
@assert nb != JuliaSyntax.span(node) |
||||||
|
# Create new node and return it |
||||||
|
node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), nb, ()) |
||||||
|
return node′ |
||||||
|
end |
||||||
|
|
||||||
|
function format_hex_literals(ctx::Context, node::JuliaSyntax.GreenNode) |
||||||
|
JuliaSyntax.kind(node) === K"HexInt" || return nothing |
||||||
|
@assert JuliaSyntax.flags(node) == 0 |
||||||
|
@assert !JuliaSyntax.haschildren(node) |
||||||
|
span = JuliaSyntax.span(node) |
||||||
|
@assert span > 2 # 0x prefix + something more |
||||||
|
# Target spans(0x + maximum chars for formatted UInt8, UInt16, UInt32, UInt64, UInt128) |
||||||
|
target_spans = 2 .+ (2, 4, 8, 16, 32) |
||||||
|
if span >= 34 || span in target_spans |
||||||
|
# Do nothing: correctly formatted or a BigInt hex literal |
||||||
|
return nothing |
||||||
|
end |
||||||
|
# Insert leading zeros |
||||||
|
i = findfirst(x -> x > span, target_spans)::Int |
||||||
|
bytes = node_bytes(ctx, node) |
||||||
|
while length(bytes) < target_spans[i] |
||||||
|
insert!(bytes, 3, '0') |
||||||
|
end |
||||||
|
nb = write_and_reset(ctx, bytes) |
||||||
|
@assert nb == length(bytes) == target_spans[i] |
||||||
|
# Create new node and return it |
||||||
|
node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), nb, ()) |
||||||
|
return node′ |
||||||
|
end |
||||||
|
|
||||||
|
function format_oct_literals(ctx::Context, node::JuliaSyntax.GreenNode) |
||||||
|
JuliaSyntax.kind(node) === K"OctInt" || return nothing |
||||||
|
@assert JuliaSyntax.flags(node) == 0 |
||||||
|
@assert !JuliaSyntax.haschildren(node) |
||||||
|
span = JuliaSyntax.span(node) |
||||||
|
@assert span > 2 # 0o prefix + something more |
||||||
|
# Padding depends on the value of the literal... |
||||||
|
str = String(node_bytes(ctx, node)) |
||||||
|
n = tryparse(UInt128, str) |
||||||
|
if n === nothing |
||||||
|
# Do nothing: BigInt oct literal |
||||||
|
return nothing |
||||||
|
end |
||||||
|
# Compute the target span |
||||||
|
target_span_from_value = |
||||||
|
n <= typemax(UInt8) ? 5 : n <= typemax(UInt16) ? 8 : |
||||||
|
n <= typemax(UInt32) ? 13 : n <= typemax(UInt64) ? 24 : |
||||||
|
n <= typemax(UInt128) ? 45 : error("unreachable") |
||||||
|
target_spans = (5, 8, 13, 24, 45) |
||||||
|
i = findfirst(x -> x >= span, target_spans)::Int |
||||||
|
target_span_from_source = target_spans[i] |
||||||
|
target_span = max(target_span_from_value, target_span_from_source) |
||||||
|
if span == target_span |
||||||
|
# Do nothing: correctly formatted oct literal |
||||||
|
return nothing |
||||||
|
end |
||||||
|
# Insert leading zeros |
||||||
|
bytes = node_bytes(ctx, node) |
||||||
|
while length(bytes) < target_span |
||||||
|
insert!(bytes, 3, '0') |
||||||
|
end |
||||||
|
nb = write_and_reset(ctx, bytes) |
||||||
|
@assert nb == length(bytes) == target_span |
||||||
|
# Create new node and return it |
||||||
|
node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), nb, ()) |
||||||
|
return node′ |
||||||
|
end |
||||||
Loading…
Reference in new issue