-
Notifications
You must be signed in to change notification settings - Fork 1
/
ast.go
110 lines (89 loc) · 2.03 KB
/
ast.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package utils
import (
"bytes"
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"log"
"regexp"
"strconv"
"strings"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/imports"
)
type StringLiteral struct {
Value string
Comment string
}
func ExtractCommentedStringLiterals(filePath string, re *regexp.Regexp) ([]StringLiteral, error) {
fset := token.NewFileSet()
src, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
file, err := parser.ParseFile(fset, filePath, src, parser.ParseComments)
if err != nil {
log.Printf("Parse error %+v", err)
return nil, nil
}
var results []StringLiteral
astutil.Apply(file, func(cr *astutil.Cursor) bool {
switch v := cr.Node().(type) {
case *ast.BasicLit:
if v.Kind == token.STRING {
str, err := strconv.Unquote(v.Value)
if err != nil {
break
}
line := fset.Position(v.Pos()).Line
var comment string
for _, cg := range file.Comments {
for _, c := range cg.List {
if fset.Position(c.Pos()).Line == line-1 {
comment = c.Text
}
}
}
if re.MatchString(comment) {
results = append(results, StringLiteral{Value: str, Comment: comment})
}
}
}
return true
}, nil)
return results, nil
}
func Format(filename string, buf bytes.Buffer) []byte {
src, err := imports.Process(filename, buf.Bytes(), nil)
if err != nil {
log.Printf("format failed: %+v", err)
return buf.Bytes()
}
return src
}
func Comment(str string) string {
return "/*\n" + indentMultiLine(strip(str), 1) + "\n*/\n"
}
func strip(str string) string {
lines := strings.Split(str, "\n")
var result []string
for _, line := range lines {
s := strings.TrimSpace(line)
if s != "" {
result = append(result, s)
}
}
return strings.Join(result, "\n")
}
func indentMultiLine(str string, indent int) string {
lines := strings.Split(str, "\n")
var result []string
for _, line := range lines {
for i := 0; i < indent; i++ {
line = "\t" + line
}
result = append(result, line)
}
return strings.Join(result, "\n")
}