1
1
"""
2
- SourceFile(code [; filename=nothing])
2
+ SourceFile(code [; filename=nothing, first_line=1 ])
3
3
4
- A UTF-8 source code string with associated file name and indexing structures.
4
+ A UTF-8 source code string with associated file name and line number.
5
+
6
+ `SourceFile` stores the character positions of line starts to facilitate indexing.
5
7
"""
6
8
struct SourceFile
7
9
# We use `code::String` for now but it could be some other UTF-8 based
@@ -11,11 +13,12 @@ struct SourceFile
11
13
# https://en.wikipedia.org/wiki/Rope_(data_structure)
12
14
code:: String
13
15
filename:: Union{Nothing,String}
16
+ first_line:: Int
14
17
# String index of start of every line
15
18
line_starts:: Vector{Int}
16
19
end
17
20
18
- function SourceFile (code:: AbstractString ; filename= nothing )
21
+ function SourceFile (code:: AbstractString ; filename= nothing , first_line = 1 )
19
22
line_starts = Int[1 ]
20
23
for i in eachindex (code)
21
24
# The line is considered to start after the `\n`
@@ -25,31 +28,33 @@ function SourceFile(code::AbstractString; filename=nothing)
25
28
if isempty (code) || last (code) != ' \n '
26
29
push! (line_starts, ncodeunits (code)+ 1 )
27
30
end
28
- SourceFile (code, filename, line_starts)
31
+ SourceFile (code, filename, first_line, line_starts)
29
32
end
30
33
31
- function SourceFile (; filename)
32
- SourceFile (read (filename, String); filename= filename)
34
+ function SourceFile (; filename, kwargs ... )
35
+ SourceFile (read (filename, String); filename= filename, kwargs ... )
33
36
end
34
37
35
38
# Get line number of the given byte within the code
36
- function source_line (source:: SourceFile , byte_index)
37
- line = searchsortedlast (source. line_starts, byte_index)
38
- return (line < lastindex (source. line_starts)) ? line : line - 1
39
+ function source_line_index (source:: SourceFile , byte_index)
40
+ lineidx = searchsortedlast (source. line_starts, byte_index)
41
+ return (lineidx < lastindex (source. line_starts)) ? lineidx : lineidx - 1
39
42
end
43
+ _source_line (source:: SourceFile , lineidx) = lineidx + source. first_line - 1
44
+ source_line (source:: SourceFile , byte_index) = _source_line (source, source_line_index (source, byte_index))
40
45
41
46
"""
42
47
Get line number and character within the line at the given byte index.
43
48
"""
44
49
function source_location (source:: SourceFile , byte_index)
45
- line = source_line (source, byte_index)
46
- i = source. line_starts[line ]
50
+ lineidx = source_line_index (source, byte_index)
51
+ i = source. line_starts[lineidx ]
47
52
column = 1
48
53
while i < byte_index
49
54
i = nextind (source. code, i)
50
55
column += 1
51
56
end
52
- line , column
57
+ _source_line (source, lineidx) , column
53
58
end
54
59
55
60
"""
@@ -58,9 +63,9 @@ Get byte range of the source line at byte_index, buffered by
58
63
"""
59
64
function source_line_range (source:: SourceFile , byte_index;
60
65
context_lines_before= 0 , context_lines_after= 0 )
61
- line = source_line (source, byte_index)
62
- fbyte = source. line_starts[max (line - context_lines_before, 1 )]
63
- lbyte = source. line_starts[min (line + 1 + context_lines_after, end )] - 1
66
+ lineidx = source_line_index (source, byte_index)
67
+ fbyte = source. line_starts[max (lineidx - context_lines_before, 1 )]
68
+ lbyte = source. line_starts[min (lineidx + 1 + context_lines_after, end )] - 1
64
69
fbyte,lbyte
65
70
end
66
71
0 commit comments