Skip to content

Commit

Permalink
Make more lint friendly
Browse files Browse the repository at this point in the history
  • Loading branch information
vvakame committed Jul 31, 2018
1 parent 69eab93 commit f7f6f91
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 26 deletions.
7 changes: 1 addition & 6 deletions codegen/models_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,7 @@ func (cfg *Config) obj2Model(obj *Object) Model {
if field.GoVarName != "" {
mf.GoVarName = field.GoVarName
} else {
mf.GoVarName = ucFirst(field.GQLName)
if mf.IsScalar {
if mf.GoVarName == "Id" {
mf.GoVarName = "ID"
}
}
mf.GoVarName = field.GoNameExported()
}

model.Fields = append(model.Fields, mf)
Expand Down
148 changes: 141 additions & 7 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,37 +69,57 @@ func (f *Field) IsConcurrent() bool {
return f.IsResolver() && !f.Object.DisableConcurrency
}

func (f *Field) GoNameExported() string {
return lintName(ucFirst(f.GQLName))
}

func (f *Field) GoNameUnexported() string {
return lintName(f.GQLName)
}

func (f *Field) ShortInvocation() string {
if !f.IsResolver() {
return ""
}
shortName := strings.ToUpper(f.GQLName[:1]) + f.GQLName[1:]

return fmt.Sprintf("%s().%s(%s)", f.Object.GQLType, shortName, f.CallArgs())
return fmt.Sprintf("%s().%s(%s)", f.Object.GQLType, f.GoNameExported(), f.CallArgs())
}

func (f *Field) ResolverType() string {
if !f.IsResolver() {
return ""
}
shortName := strings.ToUpper(f.GQLName[:1]) + f.GQLName[1:]

return fmt.Sprintf("%s().%s(%s)", f.Object.GQLType, shortName, f.CallArgs())
return fmt.Sprintf("%s().%s(%s)", f.Object.GQLType, f.GoNameExported(), f.CallArgs())
}

func (f *Field) ShortResolverDeclaration() string {
if !f.IsResolver() {
return ""
}
decl := strings.TrimPrefix(f.ResolverDeclaration(), f.Object.GQLType+"_")
return strings.ToUpper(decl[:1]) + decl[1:]
res := fmt.Sprintf("%s(ctx context.Context", f.GoNameExported())

if !f.Object.Root {
res += fmt.Sprintf(", obj *%s", f.Object.FullName())
}
for _, arg := range f.Args {
res += fmt.Sprintf(", %s %s", arg.GoVarName, arg.Signature())
}

result := f.Signature()
if f.Object.Stream {
result = "<-chan " + result
}

res += fmt.Sprintf(") (%s, error)", result)
return res
}

func (f *Field) ResolverDeclaration() string {
if !f.IsResolver() {
return ""
}
res := fmt.Sprintf("%s_%s(ctx context.Context", f.Object.GQLType, f.GQLName)
res := fmt.Sprintf("%s_%s(ctx context.Context", f.Object.GQLType, f.GoNameUnexported())

if !f.Object.Root {
res += fmt.Sprintf(", obj *%s", f.Object.FullName())
Expand Down Expand Up @@ -209,3 +229,117 @@ func ucFirst(s string) string {
r[0] = unicode.ToUpper(r[0])
return string(r)
}

// copy from https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679

// lintName returns a different name if it should be different.
func lintName(name string) (should string) {
// Fast path for simple cases: "_" and all lowercase.
if name == "_" {
return name
}
allLower := true
for _, r := range name {
if !unicode.IsLower(r) {
allLower = false
break
}
}
if allLower {
return name
}

// Split camelCase at any lower->upper transition, and split on underscores.
// Check each word for common initialisms.
runes := []rune(name)
w, i := 0, 0 // index of start of word, scan
for i+1 <= len(runes) {
eow := false // whether we hit the end of a word
if i+1 == len(runes) {
eow = true
} else if runes[i+1] == '_' {
// underscore; shift the remainder forward over any run of underscores
eow = true
n := 1
for i+n+1 < len(runes) && runes[i+n+1] == '_' {
n++
}

// 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--
}

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 !eow {
continue
}

// [w,i) is a word.
word := string(runes[w:i])
if u := strings.ToUpper(word); commonInitialisms[u] {
// Keep consistent case, which is lowercase only at the start.
if w == 0 && unicode.IsLower(runes[w]) {
u = strings.ToLower(u)
}
// All the common initialisms are ASCII,
// so we can replace the bytes exactly.
copy(runes[w:], []rune(u))
} else if w > 0 && strings.ToLower(word) == word {
// already all lowercase, and not the first word, so uppercase the first character.
runes[w] = unicode.ToUpper(runes[w])
}
w = i
}
return string(runes)
}

// commonInitialisms is a set of common initialisms.
// Only add entries that are highly unlikely to be non-initialisms.
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}
2 changes: 2 additions & 0 deletions example/config/.gqlgen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ resolver:
models:
Todo: # Object
fields:
id:
resolver: true
text:
govarname: Description
NewTodo: # Input
Expand Down
42 changes: 38 additions & 4 deletions example/config/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example/config/model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package config

type User struct {
ID string
ID string
FullName string
}
1 change: 1 addition & 0 deletions example/config/models_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 19 additions & 4 deletions example/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ func New() Config {
c := Config{
Resolvers: &Resolver{
todos: []Todo{
{ID: "TODO:1", Description: "A todo not to forget", Done: false},
{ID: "TODO:2", Description: "This is the most important", Done: false},
{ID: "TODO:3", Description: "Please do this or else", Done: false},
{DatabaseID: 1, Description: "A todo not to forget", Done: false},
{DatabaseID: 2, Description: "This is the most important", Done: false},
{DatabaseID: 3, Description: "Please do this or else", Done: false},
},
nextID: 3,
},
Expand All @@ -32,6 +32,9 @@ func (r *Resolver) Mutation() MutationResolver {
func (r *Resolver) Query() QueryResolver {
return &queryResolver{r}
}
func (r *Resolver) Todo() TodoResolver {
return &todoResolver{r}
}

type mutationResolver struct{ *Resolver }

Expand All @@ -40,7 +43,7 @@ func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (Todo,
r.nextID++

newTodo := Todo{
ID: fmt.Sprintf("TODO:%d", newID),
DatabaseID: newID,
Description: input.Text,
}

Expand All @@ -54,3 +57,15 @@ type queryResolver struct{ *Resolver }
func (r *queryResolver) Todos(ctx context.Context) ([]Todo, error) {
return r.todos, nil
}

type todoResolver struct{ *Resolver }

func (r *todoResolver) ID(ctx context.Context, obj *Todo) (string, error) {
if obj.ID != "" {
return obj.ID, nil
}

obj.ID = fmt.Sprintf("TODO:%d", obj.DatabaseID)

return obj.ID, nil
}
3 changes: 2 additions & 1 deletion example/config/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

type Todo {
id: ID!
databaseId: Int!
text: String!
done: Boolean!
user: User!
Expand All @@ -25,4 +26,4 @@ input NewTodo {

type Mutation {
createTodo(input: NewTodo!): Todo!
}
}
4 changes: 2 additions & 2 deletions test/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f7f6f91

Please sign in to comment.