-
Notifications
You must be signed in to change notification settings - Fork 0
/
names.go
139 lines (126 loc) · 3.76 KB
/
names.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package names
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"path/filepath"
"regexp"
"secret_path/checkers"
"secret_path/maps"
"strings"
)
type packageNamesChecker struct {
packageImportPath maps.String
}
func NewPackageNamesChecker() checkers.Checker {
return &packageNamesChecker{
packageImportPath: make(maps.String),
}
}
func (c *packageNamesChecker) Setup(dir string, _ string) error {
dir = dir + "/"
c.packageImportPath.Add(dir, filepath.Base(dir))
return nil
}
func (c *packageNamesChecker) Check(fileName string) checkers.Messages {
var output checkers.Messages
if strings.HasSuffix(fileName, "_test.go") {
return nil
}
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, fileName, nil, parser.AllErrors)
if err != nil {
return output.Append(fileName, fmt.Sprintf("Error: FileName checker: %s", err),
checkers.NoLine, checkers.NoColumn)
}
currentPackageName := file.Name.String()
if currentPackageName == "main" {
return nil
}
pathRealFileName, realFileName := filepath.Split(fileName)
wantPackageName := c.packageImportPath[pathRealFileName]
err = checkPackageNames(wantPackageName, currentPackageName, realFileName)
if err != nil {
return output.Append(fileName, err.Error(), checkers.NoLine, checkers.NoColumn)
}
errors, ok := checkIdentName(file, fset)
if !ok {
for _, er := range errors {
return output.Append(fileName, er, checkers.NoLine, checkers.NoColumn)
}
}
return output
}
func checkPackageNames(packageDirName string, packageName string, fileName string) error {
err := checkDirName(packageDirName)
if err != nil {
return err
}
err = checkPackageName(packageName)
if err != nil {
return err
}
if packageDirName != packageName {
return fmt.Errorf("the package name %q must match the name of the target directory%q",
packageName, packageDirName)
//for test
//return fmt.Errorf("the package name must match the name of the target directory")
}
err = checkFileName(fileName)
if err != nil {
return err
}
return nil
}
func checkDirName(s string) error {
varMatcher := regexp.MustCompile(`[^a-z]`)
if len(varMatcher.FindAllString(s, -1)) > 0 {
return fmt.Errorf("the name %q contains invalid characters. (Use only \"a-z\")", s)
//for test
//return fmt.Errorf("the name contains invalid characters. (Use only \"a-z\")")
}
return nil
}
func checkPackageName(s string) error {
varMatcher := regexp.MustCompile(`[^a-z]`)
if len(varMatcher.FindAllString(s, -1)) > 0 {
return fmt.Errorf("the name %q contains invalid characters. (Use only \"a-z\")", s)
//for test
//return fmt.Errorf("The name contains invalid characters. (Use only \"a-z\")")
}
return nil
}
func checkFileName(s string) error {
//delete the suffix ".go"
s = strings.TrimSuffix(s, ".go")
varMatcher := regexp.MustCompile(`[^a-z_0-9]`)
if len(varMatcher.FindAllString(s, -1)) > 0 {
return fmt.Errorf("the name %q contains invalid characters. (Use only \"a-z\", \"_\", \"0-9\")", s)
//for test
//return fmt.Errorf("the name contains invalid characters. (Use only \"a-z\", \"_\", \"0-9\")")
}
return nil
}
func checkIdentName(file *ast.File, fset *token.FileSet) ([]string, bool) {
var (
errors []string
err = true
varMatcher = regexp.MustCompile(`\W`)
)
ast.Inspect(file, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.Ident:
if len(varMatcher.FindAllString(x.String(), -1)) > 0 {
errors = append(errors, fmt.Sprintf("the variable name %q in line %v contains invalid characters. (Use only \"a-z\", \"A-Z\", \"0-9\", \"_\")",
x.Name, fset.Position(n.Pos())))
//for test
//errors = append(errors,
//fmt.Sprintf("the variable name in line contains invalid characters. (Use only \"a-z\", \"A-Z\", \"0-9\", \"_\")"))
err = false
}
}
return true
})
return errors, err
}