-
Notifications
You must be signed in to change notification settings - Fork 8
/
read.go
75 lines (64 loc) · 1.63 KB
/
read.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
package gogroup
import (
"go/parser"
"go/token"
"io"
"strconv"
)
// An import statement with a group.
type groupedImport struct {
// The zero-based starting and ending lines in the file.
// The endLine is the last line of this statement, not the line after.
startLine, endLine int
// The import package path.
path string
// The import group.
group int
}
// Allow sorting grouped imports.
type groupedImports []*groupedImport
func (gs groupedImports) Len() int {
return len(gs)
}
func (gs groupedImports) Swap(i, j int) {
gs[i], gs[j] = gs[j], gs[i]
}
func (gs groupedImports) Less(i, j int) bool {
if gs[i].group < gs[j].group {
return true
}
if gs[i].group == gs[j].group && gs[i].path < gs[j].path {
return true
}
return false
}
// Read import statements from a file, and assign them groups.
func (p *Processor) readImports(fileName string, r io.Reader) (groupedImports, error) {
fset := token.NewFileSet()
tree, err := parser.ParseFile(fset, fileName, r, parser.ImportsOnly|parser.ParseComments)
if err != nil {
return nil, err
}
gs := groupedImports{}
for _, ispec := range tree.Imports {
var path string
path, err = strconv.Unquote(ispec.Path.Value)
if err != nil {
return nil, err
}
startPos, endPos := ispec.Pos(), ispec.End()
if ispec.Doc != nil {
// Comments go with the following import statement.
startPos = ispec.Doc.Pos()
}
file := fset.File(startPos)
gs = append(gs, &groupedImport{
path: path,
// Line numbers are one-based in token.File.
startLine: file.Line(startPos) - 1,
endLine: file.Line(endPos) - 1,
group: p.grouper.Group(path),
})
}
return gs, nil
}