clean up various TODOs and comments

This commit is contained in:
Ben Kraft
2021-03-22 18:11:51 -07:00
parent 463e3ed319
commit a42c9b8166
12 changed files with 62 additions and 59 deletions
+2 -2
View File
@@ -21,8 +21,8 @@ type Config struct {
Package string `yaml:"package"`
// The filename with the GraphQL schema (in SDL format); defaults to
// schema.graphql
// TODO: allow other formats
// TODO: allow URLs
// TODO: Allow fetching a schema via introspection (will need to figure out
// how to convert that to SDL).
Schema string `yaml:"schema"`
// The filename with the queries; defaults to queries.graphql
Queries string `yaml:"queries"`
+13 -7
View File
@@ -56,14 +56,20 @@ func newGenerator(config *Config, schema *ast.Schema) *generator {
}
func (g *generator) Types() string {
names := make([]string, 0, len(g.typeMap))
for name := range g.typeMap {
names = append(names, name)
}
// Sort alphabetically by type-name. Sorting somehow deterministically is
// important to ensure generated code is deterministic. Alphabetical is
// nice because it's easy, and in the current naming scheme, it's even
// vaguely aligned to the structure of the queries.
sort.Strings(names)
defs := make([]string, 0, len(g.typeMap))
for _, def := range g.typeMap {
defs = append(defs, def)
for _, name := range names {
defs = append(defs, g.typeMap[name])
}
// Make sure we have a stable order. (It's somewhat
// arbitrary but in practice mostly alphabetical.)
// TODO: ideally we'd do a nice semantic ordering.
sort.Strings(defs)
return strings.Join(defs, "\n\n")
}
@@ -84,7 +90,7 @@ func (g *generator) getArgument(arg *ast.VariableDefinition) (argument, error) {
func (g *generator) getDocComment(op *ast.OperationDefinition) string {
var commentLines []string
var sourceLines = strings.Split(op.Position.Src.Input, "\n")
sourceLines := strings.Split(op.Position.Src.Input, "\n")
for i := op.Position.Line - 1; i > 0; i-- {
line := sourceLines[i-1]
if strings.HasPrefix(line, "#") {
-3
View File
@@ -11,9 +11,6 @@ import (
)
func getSchema(filename string) (*ast.Schema, error) {
// TODO: IRL we have to get the schema from GraphQL (maybe we can generate
// that once we can bootstrap) where it comes as JSON, not SDL, so we have
// to convert (or add gqlparser support to convert)
text, err := ioutil.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("unreadable schema file %v: %v", filename, err)
+5 -2
View File
@@ -7,8 +7,11 @@ import (
)
// TODO: package templates into the binary using one of those asset thingies
var _, thisFilename, _, _ = runtime.Caller(0)
var thisDir = filepath.Dir(thisFilename)
// (e.g. embed, if we wait until 1.16 to do this)
var (
_, thisFilename, _, _ = runtime.Caller(0)
thisDir = filepath.Dir(thisFilename)
)
func mustTemplate(relFilename string) *template.Template {
return template.Must(template.ParseFiles(filepath.Join(thisDir, relFilename)))
+14 -18
View File
@@ -29,12 +29,11 @@ func (g *generator) baseTypeForOperation(operation ast.Operation) *ast.Definitio
func (g *generator) getTypeForOperation(operation *ast.OperationDefinition) (name string, err error) {
// TODO: configure ResponseName format
namePrefix := upperFirst(operation.Name)
name = namePrefix + "Response"
name = operation.Name + "Response"
if def, ok := g.typeMap[name]; ok {
// TODO: check for and handle conflicts a better way
return "", fmt.Errorf("%s already defined:\n%s", name, def)
return "", fmt.Errorf("%s defined twice:\n%s", name, def)
}
fields, err := selections(operation.SelectionSet)
@@ -43,15 +42,16 @@ func (g *generator) getTypeForOperation(operation *ast.OperationDefinition) (nam
}
return g.addTypeForDefinition(
namePrefix, name, g.baseTypeForOperation(operation.Operation), fields)
operation.Name, name, g.baseTypeForOperation(operation.Operation), fields)
}
var builtinTypes = map[string]string{
"Int": "int", // TODO: technically int32 is always enough, use that?
// GraphQL guarantees int32 is enough, but using int seems more idiomatic
"Int": "int",
"Float": "float64",
"String": "string",
"Boolean": "bool",
"ID": "string", // TODO: named type for IDs?
"ID": "string",
}
func (g *generator) addTypeForDefinition(namePrefix, nameOverride string, typ *ast.Definition, fields []field) (name string, err error) {
@@ -117,11 +117,9 @@ type field interface {
type outputField struct{ field *ast.Field }
func (s outputField) Alias() string {
if s.field.Alias != "" {
return s.field.Alias
}
// TODO: is this case needed? tests don't seem to get here.
return s.field.Name
// gqlparser sets Alias even if the field is not aliased, see e.g.
// https://github.com/vektah/gqlparser/blob/c06d8e0d135f285e37e7f1ff397f10e049733eb3/parser/query.go#L150
return s.field.Alias
}
func (s outputField) Type() *ast.Type {
@@ -192,11 +190,11 @@ func (builder *typeBuilder) writeField(field field) error {
}
err = builder.writeType(
// Note we don't deduplicate here -- if our prefix is GetUser and the
// field name is User, we do GetUserUser. This is important because if
// you have a field called user on a type called User we need
// `query q { user { user { id } } }` to generate two types, QUser and
// QUserUser.
// Note we don't deduplicate suffixes here -- if our prefix is GetUser
// and the field name is User, we do GetUserUser. This is important
// because if you have a field called user on a type called User we
// need `query q { user { user { id } } }` to generate two types, QUser
// and QUserUser.
// Note also this is the alias, not the field-name, because if we have
// `query q { a: f { b }, c: f { d } }` we need separate types for a
// and c, even though they are the same type in GraphQL, because they
@@ -273,7 +271,6 @@ func (builder *typeBuilder) writeTypedef(typedef *ast.Definition, fields []field
return err
}
// HACK HACK HACK
builder.typeMap[name] += fmt.Sprintf(
"\nfunc (v %v) %v() {}", name, implementsMethodName)
}
@@ -285,7 +282,6 @@ func (builder *typeBuilder) writeTypedef(typedef *ast.Definition, fields []field
builder.WriteString("string\n")
builder.WriteString("const (\n")
for _, val := range typedef.EnumValues {
// TODO: casing should be configurable
fmt.Fprintf(builder, "%s %s = \"%s\"\n",
builder.typeNamePrefix+goConstName(val.Name),
builder.typeName, val.Name)
+1 -1
View File
@@ -33,7 +33,7 @@ func (builder *typeBuilder) maybeWriteUnmarshal(fields []field) error {
for _, typedef := range builder.schema.GetPossibleTypes(typedef) {
fieldInfo.ConcreteTypes = append(fieldInfo.ConcreteTypes,
concreteType{
// TODO: this is quite fragile (and maybe wrong if the
// TODO: this is quite fragile (and wrong if the
// field name + type name are the same)
GoName: builder.typeNamePrefix + fieldInfo.GoName + upperFirst(typedef.Name),
GraphQLName: typedef.Name,