Skip to content

Commit 8624e91

Browse files
committed
move location utils here for now
1 parent b8f9c09 commit 8624e91

File tree

3 files changed

+82
-10
lines changed

3 files changed

+82
-10
lines changed

src/MacroTools.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include("examples/threading.jl")
1717
include("examples/forward.jl")
1818

1919
include("patch/diff.jl")
20+
include("patch/location.jl")
2021
include("patch/cst.jl")
2122

2223
const animals = Symbol[]

src/patch/cst.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using CSTParser
2-
using CSTParser: EXPR, Call, Location, expr_location, charrange
2+
using CSTParser: EXPR, Call
33

44
expridx(x, ii) = (@assert isempty(ii); x)
55
expridx(x::Expr, ii) = isempty(ii) ? x : expridx(x.args[ii[1]], ii[2:end])
66

77
function precedence_level(cst::EXPR, loc::Location)
8-
parent = cst[CSTParser.parent(loc)]
8+
parent = cst[MacroTools.parent(loc)]
99
if parent isa Union{CSTParser.BinaryOpCall,CSTParser.UnaryOpCall,CSTParser.ChainOpCall}
1010
Base.operator_precedence(Expr(parent).args[1])
1111
elseif parent isa Union{CSTParser.BinarySyntaxOpCall,CSTParser.UnarySyntaxOpCall}
@@ -18,29 +18,29 @@ end
1818
# Get the range at loc, including trailing trivia from the previous node.
1919
function separator_range(cst, loc)
2020
i = loc.ii[end]
21-
loc = CSTParser.parent(loc)
22-
start = charrange(cst, CSTParser.child(loc, i-1))[1][1]+1
23-
stop = charrange(cst, CSTParser.child(loc, i))[1][end]
21+
loc = MacroTools.parent(loc)
22+
start = charrange(cst, child(loc, i-1))[1][1]+1
23+
stop = charrange(cst, child(loc, i))[1][end]
2424
return start:stop
2525
end
2626

2727
function separator(cst, loc, x::EXPR{Call}, i)
2828
length(x.args) == 3 && return ""
2929
length(x.args) == 4 && return ", "
30-
separator_range(cst, CSTParser.child(loc, max(i-1,4)))
30+
separator_range(cst, child(loc, max(i-1,4)))
3131
end
3232

3333
function separator(cst, loc, x::EXPR{CSTParser.Block}, i)
34-
out, in = charrange(cst, CSTParser.child(loc, max(i-1,1)))
34+
out, in = charrange(cst, child(loc, max(i-1,1)))
3535
in[end]+1:out[end]
3636
end
3737

3838
function separator(cst, loc, x::CSTParser.BinaryOpCall, i)
39-
separator_range(cst, CSTParser.child(loc, 2))
39+
separator_range(cst, child(loc, 2))
4040
end
4141

4242
function separator(cst::EXPR, loc::Location)
43-
parent = CSTParser.parent(loc)
43+
parent = MacroTools.parent(loc)
4444
separator(cst, parent, cst[parent], loc.ii[end])
4545
end
4646

@@ -68,7 +68,7 @@ function replacement(src::SourceFile, p::Insert)
6868
append && (p.idx[end] -= 1)
6969
loc = expr_location(src.cst, p.idx)
7070
# TODO handle cases like this more generally
71-
src.cst[CSTParser.parent(loc)] isa EXPR{Call} && (loc.ii[end] = max(loc.ii[end], 2))
71+
src.cst[MacroTools.parent(loc)] isa EXPR{Call} && (loc.ii[end] = max(loc.ii[end], 2))
7272
_, span = charrange(src.cst, loc)
7373
point = append ? span[end] : span[1]-1
7474
sep = separator(src.cst, loc)

src/patch/location.jl

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using CSTParser
2+
import CSTParser: EXPR, AbstractEXPR
3+
4+
struct Location
5+
ii::Vector{Int}
6+
end
7+
8+
parent(l::Location) = Location(l.ii[1:end-1])
9+
child(l::Location, i) = Location([l.ii..., i])
10+
11+
Base.getindex(ex::EXPR, i::Integer) = ex.args[i]
12+
Base.getindex(ex::AbstractEXPR, i) = collect(ex)[i]
13+
14+
function Base.getindex(ex::AbstractEXPR, l::Location)
15+
for i in l.ii
16+
ex = ex[i]
17+
end
18+
return ex
19+
end
20+
21+
function charrange(ex::AbstractEXPR, l::Location)
22+
o = 0
23+
for i in l.ii
24+
for j = 1:i-1
25+
o += ex[j].fullspan
26+
end
27+
ex = ex[i]
28+
end
29+
full = o .+ (1:ex.fullspan)
30+
inner = o .+ ex.span
31+
return full, inner
32+
end
33+
34+
function expr_child_index(x::EXPR, n)
35+
for (i, a) in enumerate(x.args)
36+
a isa CSTParser.PUNCTUATION && continue
37+
n -= 1
38+
n == 0 && return i
39+
end
40+
end
41+
42+
function expr_child_index(x::EXPR{CSTParser.Const}, i)
43+
@assert i == 1
44+
return 2
45+
end
46+
47+
expr_child_index(x::CSTParser.UnaryOpCall, i) = i
48+
expr_child_index(x::CSTParser.UnarySyntaxOpCall, _) = x.arg1 isa OPERATOR ? 2 : 1
49+
expr_child_index(x::CSTParser.BinaryOpCall, i) = [2, 1, 3][i]
50+
expr_child_index(x::CSTParser.BinarySyntaxOpCall, i) = i+1
51+
expr_child_index(x::CSTParser.ConditionalOpCall, i) = i
52+
expr_child_index(x::EXPR{CSTParser.ChainOpCall}, i) = i == 1 ? 2 : 2(i-1)-1
53+
54+
function expr_child!(ii, ex, i)
55+
j = expr_child_index(ex, i)
56+
push!(ii, j)
57+
return ex[j]
58+
end
59+
60+
function expr_child!(ii, x::EXPR{<:Union{CSTParser.Begin,CSTParser.InvisBrackets}}, i)
61+
push!(ii, 2, i)
62+
return x[2][i]
63+
end
64+
65+
function expr_location(ex::AbstractEXPR, ii)
66+
jj = []
67+
for i in ii
68+
ex = expr_child!(jj, ex, i)
69+
end
70+
return Location(jj)
71+
end

0 commit comments

Comments
 (0)