-
Notifications
You must be signed in to change notification settings - Fork 0
/
source.go
82 lines (71 loc) · 1.86 KB
/
source.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package source
import (
"bytes"
"github.com/hashicorp/hcl/v2"
)
type sourceLine struct {
content []byte
rng hcl.Range
}
// Range returns range of the line bytes inc. any trailing end-of-line markers
// The range will span across two lines in most cases
// (other than last line without trailing new line)
func (l sourceLine) Range() hcl.Range {
return l.rng
}
// Bytes returns the line byte inc. any trailing end-of-line markers
func (l sourceLine) Bytes() []byte {
return l.content
}
func MakeSourceLines(filename string, s []byte) []Line {
var ret []Line
lastRng := hcl.Range{
Filename: filename,
Start: hcl.InitialPos,
End: hcl.InitialPos,
}
sc := hcl.NewRangeScanner(s, filename, scanLines)
for sc.Scan() {
ret = append(ret, sourceLine{
content: sc.Bytes(),
rng: sc.Range(),
})
lastRng = sc.Range()
}
// Account for the last (virtual) user-percieved line
ret = append(ret, sourceLine{
content: []byte{},
rng: hcl.Range{
Filename: lastRng.Filename,
Start: lastRng.End,
End: lastRng.End,
},
})
return ret
}
// scanLines is a split function for a Scanner that returns each line of
// text (separated by \n), INCLUDING any trailing end-of-line marker.
// The last non-empty line of input will be returned even if it has no
// newline.
func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, '\n'); i >= 0 {
// We have a full newline-terminated line.
return i + 1, data[0 : i+1], nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}
func StringLines(lines Lines) []string {
strLines := make([]string, len(lines))
for i, l := range lines {
strLines[i] = string(l.Bytes())
}
return strLines
}