-
-
Notifications
You must be signed in to change notification settings - Fork 560
/
goify.go
129 lines (117 loc) Β· 2.89 KB
/
goify.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
package codegen
import (
"strings"
"goa.design/goa/v3/expr"
)
// Goify makes a valid Go identifier out of any string. It does that by removing
// any non letter and non digit character and by making sure the first character
// is a letter or "_". Goify produces a "CamelCase" version of the string, if
// firstUpper is true the first character of the identifier is uppercase
// otherwise it's lowercase.
func Goify(str string, firstUpper bool) string {
// Optimize trivial case
if str == "" {
return ""
}
// Remove optional suffix that defines corresponding transport specific
// name.
idx := strings.Index(str, ":")
if idx > 0 {
str = str[:idx]
}
str = CamelCase(str, firstUpper, true)
if str == "" {
// All characters are invalid. Produce a default value.
if firstUpper {
return "Val"
}
return "val"
}
return fixReservedGo(str)
}
// GoifyAtt honors any struct:field:name meta set on the attribute and calls
// Goify with the tag value if present or the given name otherwise.
func GoifyAtt(att *expr.AttributeExpr, name string, upper bool) string {
if tname, ok := att.Meta["struct:field:name"]; ok {
if len(tname) > 0 {
name = tname[0]
}
}
return Goify(name, upper)
}
// UnionValTypeName returns the Go type name of the interface and method used to
// type the union.
func UnionValTypeName(unionName string) string {
return Goify(unionName+"Val", false)
}
// fixReservedGo appends an underscore on to Go reserved keywords.
func fixReservedGo(w string) string {
if reservedGo[w] {
w += "_"
}
return w
}
var (
// reserved golang keywords and package names
reservedGo = map[string]bool{
// predeclared types
"bool": true,
"byte": true,
"complex128": true,
"complex64": true,
"float32": true,
"float64": true,
"int": true,
"int16": true,
"int32": true,
"int64": true,
"int8": true,
"rune": true,
"string": true,
"uint": true,
"uint16": true,
"uint32": true,
"uint64": true,
"uint8": true,
"uintptr": true,
// reserved keywords
"break": true,
"case": true,
"chan": true,
"const": true,
"continue": true,
"default": true,
"defer": true,
"delete": true,
"else": true,
"fallthrough": true,
"for": true,
"func": true,
"go": true,
"goto": true,
"if": true,
"import": true,
"interface": true,
"map": true,
"package": true,
"range": true,
"return": true,
"select": true,
"struct": true,
"switch": true,
"type": true,
"var": true,
// predeclared constants
"true": true,
"false": true,
"iota": true,
"nil": true,
// stdlib and goa packages used by generated code
"fmt": true,
"http": true,
"json": true,
"os": true,
"url": true,
"time": true,
}
)