Skip to content

Commit

Permalink
address comment
Browse files Browse the repository at this point in the history
  • Loading branch information
vvakame committed Mar 6, 2019
1 parent 6ea48ff commit eb45367
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 70 deletions.
6 changes: 3 additions & 3 deletions codegen/generated!.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type DirectiveRoot struct {
type ComplexityRoot struct {
{{ range $object := .Objects }}
{{ if not $object.IsReserved -}}
{{ $object.Name|toCamel }} struct {
{{ $object.Name|go }} struct {
{{ range $field := $object.Fields -}}
{{ if not $field.IsReserved -}}
{{ $field.GoFieldName }} {{ $field.ComplexitySignature }}
Expand Down Expand Up @@ -87,7 +87,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
{{ range $field := $object.Fields }}
{{ if not $field.IsReserved }}
case "{{$object.Name}}.{{$field.GoFieldName}}":
if e.complexity.{{$object.Name|toCamel}}.{{$field.GoFieldName}} == nil {
if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil {
break
}
{{ if $field.Args }}
Expand All @@ -96,7 +96,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false
}
{{ end }}
return e.complexity.{{$object.Name|toCamel}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true
return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true
{{ end }}
{{ end }}
{{ end }}
Expand Down
128 changes: 80 additions & 48 deletions codegen/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ func Funcs() template.FuncMap {
"lcFirst": lcFirst,
"quote": strconv.Quote,
"rawQuote": rawQuote,
"toCamel": ToCamel,
"dump": Dump,
"ref": ref,
"ts": TypeIdentifier,
Expand Down Expand Up @@ -228,64 +227,97 @@ func Call(p *types.Func) string {
return pkg + p.Name()
}

func ToCamel(s string) string {
if s == "_" {
return "_"
}
buf := bytes.NewBuffer(make([]byte, 0, len(s)))
upper := true
lastWasUpper := false
var maxCommonInitialismsLen int
for word := range commonInitialisms {
if l := len(word); maxCommonInitialismsLen < l {
maxCommonInitialismsLen = l
func ToGo(name string) string {
runes := make([]rune, 0, len(name))

wordWalker(name, func(word string, hasCommonInitial bool) {
if !hasCommonInitial {
word = ucFirst(strings.ToLower(word))
}
}
runes = append(runes, []rune(word)...)
})

outer:
for i, rs := 0, []rune(s); i < len(rs); i++ {
c := rs[i]
if isDelimiter(c) {
upper = true
continue
return string(runes)
}

func ToGoPrivate(name string) string {
runes := make([]rune, 0, len(name))

first := true
wordWalker(name, func(word string, hasCommonInitial bool) {
if first {
word = strings.ToLower(word)
first = false
} else if !hasCommonInitial {
word = ucFirst(strings.ToLower(word))
}
if !lastWasUpper && unicode.IsUpper(c) {
tail := len(rs) - i
if maxCommonInitialismsLen < tail {
tail = maxCommonInitialismsLen
runes = append(runes, []rune(word)...)
})

return sanitizeKeywords(string(runes))
}

func wordWalker(str string, f func(word string, hasCommonInitial bool)) {

skipRune := func(r rune) bool {
switch r {
case '-', '_':
return true
default:
return false
}
}

runes := []rune(str)
w, i := 0, 0 // index of start of word, scan
hasCommonInitial := false
for i+1 <= len(runes) {
eow := false // whether we hit the end of a word
if i+1 == len(runes) {
eow = true
} else if skipRune(runes[i+1]) {
// underscore; shift the remainder forward over any run of underscores
eow = true
n := 1
for i+n+1 < len(runes) && skipRune(runes[i+n+1]) {
n++
}
for j := tail; j != 0; j-- {
word := string(rs[i : i+j])
if commonInitialisms[word] {
buf.WriteString(word)
i += j - 1
upper = false
lastWasUpper = false // IDFoo will be IDFoo, not IDfoo
continue outer
}

// Leave at most one underscore if the underscore is between two digits
if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
n--
}

upper = true
copy(runes[i+1:], runes[i+n+1:])
runes = runes[:len(runes)-n]
} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
// lower->non-lower
eow = true
}
i++

if upper {
buf.WriteRune(unicode.ToUpper(c))
} else {
buf.WriteRune(unicode.ToLower(c))
// [w,i) is a word.
word := string(runes[w:i])
if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) {
// through
// split IDFoo → ID, Foo
// but URLs → URLs
} else if !eow {
if commonInitialisms[word] {
hasCommonInitial = true
}
continue
}
upper = false
lastWasUpper = unicode.IsUpper(c)
}

return buf.String()
}

func ToGo(name string) string {
return lintName(ToCamel(name))
}
if u := strings.ToUpper(word); commonInitialisms[u] {
hasCommonInitial = true
word = u
}

func ToGoPrivate(name string) string {
return lintName(sanitizeKeywords(lcFirst(ToCamel(name))))
f(word, hasCommonInitial)
hasCommonInitial = false
w = i
}
}

var keywords = []string{
Expand Down
102 changes: 83 additions & 19 deletions codegen/templates/templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,89 @@ import (
"github.com/stretchr/testify/require"
)

func TestToCamel(t *testing.T) {
require.Equal(t, "ToCamel", ToCamel("TO_CAMEL"))
require.Equal(t, "ToCamel", ToCamel("to_camel"))
require.Equal(t, "ToCamel", ToCamel("toCamel"))
require.Equal(t, "ToCamel", ToCamel("ToCamel"))
require.Equal(t, "ToCamel", ToCamel("to-camel"))

require.Equal(t, "RelatedURLs", ToCamel("RelatedURLs"))
require.Equal(t, "ImageIDs", ToCamel("ImageIDs"))
require.Equal(t, "FooID", ToCamel("FooID"))
require.Equal(t, "IDFoo", ToCamel("IDFoo"))
require.Equal(t, "FooASCII", ToCamel("FooASCII"))
require.Equal(t, "ASCIIFoo", ToCamel("ASCIIFoo"))
require.Equal(t, "FooUTF8", ToCamel("FooUTF8"))
require.Equal(t, "UTF8Foo", ToCamel("UTF8Foo"))

require.Equal(t, "A", ToCamel("A"))
require.Equal(t, "ID", ToCamel("ID"))
require.Equal(t, "", ToCamel(""))
func TestToGo(t *testing.T) {
require.Equal(t, "ToCamel", ToGo("TO_CAMEL"))
require.Equal(t, "ToCamel", ToGo("to_camel"))
require.Equal(t, "ToCamel", ToGo("toCamel"))
require.Equal(t, "ToCamel", ToGo("ToCamel"))
require.Equal(t, "ToCamel", ToGo("to-camel"))

require.Equal(t, "RelatedURLs", ToGo("RelatedURLs"))
require.Equal(t, "ImageIDs", ToGo("ImageIDs"))
require.Equal(t, "FooID", ToGo("FooID"))
require.Equal(t, "IDFoo", ToGo("IDFoo"))
require.Equal(t, "FooASCII", ToGo("FooASCII"))
require.Equal(t, "ASCIIFoo", ToGo("ASCIIFoo"))
require.Equal(t, "FooUTF8", ToGo("FooUTF8"))
require.Equal(t, "UTF8Foo", ToGo("UTF8Foo"))
require.Equal(t, "JSONEncoding", ToGo("JSONEncoding"))

require.Equal(t, "A", ToGo("A"))
require.Equal(t, "ID", ToGo("ID"))
require.Equal(t, "", ToGo(""))

require.Equal(t, "RelatedUrls", ToGo("RelatedUrls"))
}

func TestToGoPrivate(t *testing.T) {
require.Equal(t, "toCamel", ToGoPrivate("TO_CAMEL"))
require.Equal(t, "toCamel", ToGoPrivate("to_camel"))
require.Equal(t, "toCamel", ToGoPrivate("toCamel"))
require.Equal(t, "toCamel", ToGoPrivate("ToCamel"))
require.Equal(t, "toCamel", ToGoPrivate("to-camel"))

require.Equal(t, "relatedURLs", ToGoPrivate("RelatedURLs"))
require.Equal(t, "imageIDs", ToGoPrivate("ImageIDs"))
require.Equal(t, "fooID", ToGoPrivate("FooID"))
require.Equal(t, "idFoo", ToGoPrivate("IDFoo"))
require.Equal(t, "fooASCII", ToGoPrivate("FooASCII"))
require.Equal(t, "asciiFoo", ToGoPrivate("ASCIIFoo"))
require.Equal(t, "fooUTF8", ToGoPrivate("FooUTF8"))
require.Equal(t, "utf8Foo", ToGoPrivate("UTF8Foo"))
require.Equal(t, "jsonEncoding", ToGoPrivate("JSONEncoding"))

require.Equal(t, "rangeArg", ToGoPrivate("Range"))

require.Equal(t, "a", ToGoPrivate("A"))
require.Equal(t, "id", ToGoPrivate("ID"))
require.Equal(t, "", ToGoPrivate(""))
}

func Test_wordWalker(t *testing.T) {

type Result struct {
Value string
HasCommonInitial bool
}
helper := func(str string) []*Result {
resultList := []*Result{}
wordWalker(str, func(word string, hasCommonInitial bool) {
resultList = append(resultList, &Result{word, hasCommonInitial})
})
return resultList
}

require.Equal(t, []*Result{{Value: "TO"}, {Value: "CAMEL"}}, helper("TO_CAMEL"))
require.Equal(t, []*Result{{Value: "to"}, {Value: "camel"}}, helper("to_camel"))
require.Equal(t, []*Result{{Value: "to"}, {Value: "Camel"}}, helper("toCamel"))
require.Equal(t, []*Result{{Value: "To"}, {Value: "Camel"}}, helper("ToCamel"))
require.Equal(t, []*Result{{Value: "to"}, {Value: "camel"}}, helper("to-camel"))

require.Equal(t, []*Result{{Value: "Related"}, {Value: "URLs", HasCommonInitial: true}}, helper("RelatedURLs"))
require.Equal(t, []*Result{{Value: "Image"}, {Value: "IDs", HasCommonInitial: true}}, helper("ImageIDs"))
require.Equal(t, []*Result{{Value: "Foo"}, {Value: "ID", HasCommonInitial: true}}, helper("FooID"))
require.Equal(t, []*Result{{Value: "ID", HasCommonInitial: true}, {Value: "Foo"}}, helper("IDFoo"))
require.Equal(t, []*Result{{Value: "Foo"}, {Value: "ASCII", HasCommonInitial: true}}, helper("FooASCII"))
require.Equal(t, []*Result{{Value: "ASCII", HasCommonInitial: true}, {Value: "Foo"}}, helper("ASCIIFoo"))
require.Equal(t, []*Result{{Value: "Foo"}, {Value: "UTF8", HasCommonInitial: true}}, helper("FooUTF8"))
require.Equal(t, []*Result{{Value: "UTF8", HasCommonInitial: true}, {Value: "Foo"}}, helper("UTF8Foo"))

require.Equal(t, []*Result{{Value: "A"}}, helper("A"))
require.Equal(t, []*Result{{Value: "ID", HasCommonInitial: true}}, helper("ID"))
require.Equal(t, []*Result{{Value: "ID", HasCommonInitial: true}}, helper("id"))
require.Equal(t, []*Result{}, helper(""))

require.Equal(t, []*Result{{Value: "Related"}, {Value: "Urls"}}, helper("RelatedUrls"))
}

func TestCenter(t *testing.T) {
Expand Down

0 comments on commit eb45367

Please sign in to comment.