Code generate all kind of resolvers.

このコミットが含まれているのは:
Cory Slep 2019-01-26 12:48:06 +01:00
コミット 929831f6e2
2個のファイルの変更439行の追加178行の削除

ファイルの表示

@ -14,6 +14,7 @@ import (
const ( const (
interfacePkg = "vocab" interfacePkg = "vocab"
resolverPkg = "resolver"
) )
// File is a code-generated file. // File is a code-generated file.
@ -362,6 +363,12 @@ func (c Converter) convertToFiles(v vocabulary) (f []*File, e error) {
FileName: "gen_doc.go", FileName: "gen_doc.go",
Directory: pub.WriteDir(), Directory: pub.WriteDir(),
}) })
// Resolvers
files, e = c.resolverFiles(c.GenRoot.Sub(resolverPkg).PublicPackage(), v)
if e != nil {
return
}
f = append(f, files...)
return return
} }
@ -1078,6 +1085,59 @@ func (c Converter) propertyPackageFiles(pg *gen.PropertyGenerator, vocabName str
return return
} }
// resolverFiles creates the files necessary for the resolvers.
func (c Converter) resolverFiles(pkg gen.Package, root vocabulary) (files []*File, e error) {
rg := gen.NewResolverGenerator(root.allTypeArray(), pkg)
typeRes, intRes, typePredRes, intPredRes, errDefs, isUnFn, iFaces := rg.Definition()
// Utils
file := jen.NewFilePath(pkg.Path())
for _, errDef := range errDefs {
file.Add(errDef).Line()
}
for _, iFace := range iFaces {
file.Add(iFace.Definition()).Line()
}
file.Add(isUnFn.Definition())
files = append(files, &File{
F: file,
FileName: "gen_resolver_utils.go",
Directory: pkg.WriteDir(),
})
// Type, not predicated
file = jen.NewFilePath(pkg.Path())
file.Add(typeRes.Definition())
files = append(files, &File{
F: file,
FileName: "gen_type_resolver.go",
Directory: pkg.WriteDir(),
})
// Interface, not predicated
file = jen.NewFilePath(pkg.Path())
file.Add(intRes.Definition())
files = append(files, &File{
F: file,
FileName: "gen_interface_resolver.go",
Directory: pkg.WriteDir(),
})
// Type, Predicated
file = jen.NewFilePath(pkg.Path())
file.Add(typePredRes.Definition())
files = append(files, &File{
F: file,
FileName: "gen_type_predicated_resolver.go",
Directory: pkg.WriteDir(),
})
// Interface, Predicated
file = jen.NewFilePath(pkg.Path())
file.Add(intPredRes.Definition())
files = append(files, &File{
F: file,
FileName: "gen_interface_predicated_resolver.go",
Directory: pkg.WriteDir(),
})
return
}
// allExtendsAreIn determines if a VocabularyType's parents are all already // allExtendsAreIn determines if a VocabularyType's parents are all already
// converted to a TypeGenerator. // converted to a TypeGenerator.
func (c Converter) allExtendsAreIn(registry *rdf.RDFRegistry, t rdf.VocabularyType, v map[string]*gen.TypeGenerator, genRefs map[string]*vocabulary) bool { func (c Converter) allExtendsAreIn(registry *rdf.RDFRegistry, t rdf.VocabularyType, v map[string]*gen.TypeGenerator, genRefs map[string]*vocabulary) bool {

ファイルの表示

@ -9,13 +9,16 @@ import (
const ( const (
typeResolverStructName = "TypeResolver" typeResolverStructName = "TypeResolver"
predicateResolverStructName = "PredicateResolver" interfaceResolverStructName = "InterfaceResolver"
typePredicatedResolverStructName = "TypePredicatedResolver"
interfacePredicatedResolverStructName = "InterfacePredicatedResolver"
resolveMethod = "Resolve" resolveMethod = "Resolve"
resolveMethodPrivate = "resolve"
applyMethod = "Apply" applyMethod = "Apply"
activityStreamInterface = "ActivityStreamsInterface" activityStreamInterface = "ActivityStreamsInterface"
resolverInterface = "Resolver"
callbackMember = "callbacks" callbackMember = "callbacks"
predicateMember = "predicate" predicateMember = "predicate"
delegateMember = "delegate"
errorNoMatch = "ErrNoCallbackMatch" errorNoMatch = "ErrNoCallbackMatch"
errorUnhandled = "ErrUnknownType" errorUnhandled = "ErrUnknownType"
errorPredicateUnmatched = "ErrPredicateUnmatched" errorPredicateUnmatched = "ErrPredicateUnmatched"
@ -27,13 +30,15 @@ const (
// TODO: Interface-driven resolvers. For hierarchy. // TODO: Interface-driven resolvers. For hierarchy.
// ResolverGenerator generates the code required for the TypeResolver and the // ResolverGenerator generates the code required for the TypeResolver and the
// PredicateResolver. // PredicateTypeResolver.
type ResolverGenerator struct { type ResolverGenerator struct {
pkg Package pkg Package
types []*TypeGenerator types []*TypeGenerator
cacheOnce sync.Once cacheOnce sync.Once
cachedPredicate *codegen.Struct cachedTypePredicate *codegen.Struct
cachedInterfacePredicate *codegen.Struct
cachedType *codegen.Struct cachedType *codegen.Struct
cachedInterface *codegen.Struct
cachedErrNoMatch jen.Code cachedErrNoMatch jen.Code
cachedErrUnhandled jen.Code cachedErrUnhandled jen.Code
cachedErrPredicateUnmatched jen.Code cachedErrPredicateUnmatched jen.Code
@ -41,6 +46,7 @@ type ResolverGenerator struct {
cachedErrCannotTypeAssertPredicate jen.Code cachedErrCannotTypeAssertPredicate jen.Code
cachedIsUnFn *codegen.Function cachedIsUnFn *codegen.Function
cachedASInterface *codegen.Interface cachedASInterface *codegen.Interface
cachedResolverInterface *codegen.Interface
} }
// Creates a new ResolverGenerator for generating all the methods, functions, // Creates a new ResolverGenerator for generating all the methods, functions,
@ -56,22 +62,36 @@ func NewResolverGenerator(
} }
} }
// Definition returns the TypeResolver and PredicateResolver. // Definition returns the TypeResolver and PredicateTypeResolver.
func (r *ResolverGenerator) Definition() (types, predicates *codegen.Struct, errs []jen.Code, isUnFn *codegen.Function, asInterface *codegen.Interface) { func (r *ResolverGenerator) Definition() (typeRes, interfaceRes, typePredRes, interfacePredRes *codegen.Struct, errs []jen.Code, isUnFn *codegen.Function, iFaces []*codegen.Interface) {
r.cacheOnce.Do(func() { r.cacheOnce.Do(func() {
r.cachedType = codegen.NewStruct( r.cachedType = codegen.NewStruct(
// TODO: Comment // TODO: Comment
fmt.Sprintf("", typeResolverStructName), fmt.Sprintf("%s", typeResolverStructName),
typeResolverStructName, typeResolverStructName,
r.typeResolverMethods(), r.typeResolverMethods(),
r.typeResolverFunctions(), r.resolverFunctions(typeResolverStructName),
r.typeResolverMembers()) r.resolverMembers())
r.cachedPredicate = codegen.NewStruct( r.cachedInterface = codegen.NewStruct(
// TODO: Comment // TODO: Comment
fmt.Sprintf("", predicateResolverStructName), fmt.Sprintf("%s", interfaceResolverStructName),
predicateResolverStructName, interfaceResolverStructName,
r.predicateResolverMethods(), r.interfaceResolverMethods(),
r.predicateResolverFunctions(), r.resolverFunctions(interfaceResolverStructName),
r.resolverMembers())
r.cachedTypePredicate = codegen.NewStruct(
// TODO: Comment
fmt.Sprintf("%s", typePredicatedResolverStructName),
typePredicatedResolverStructName,
r.typePredicatedResolverMethods(),
r.predicateResolverFunctions(typePredicatedResolverStructName),
r.predicateResolverMembers())
r.cachedInterfacePredicate = codegen.NewStruct(
// TODO: Comment
fmt.Sprintf("%s", interfacePredicatedResolverStructName),
interfacePredicatedResolverStructName,
r.interfacePredicatedResolverMethods(),
r.predicateResolverFunctions(interfacePredicatedResolverStructName),
r.predicateResolverMembers()) r.predicateResolverMembers())
r.cachedErrNoMatch = r.errorNoMatch() r.cachedErrNoMatch = r.errorNoMatch()
r.cachedErrUnhandled = r.errorUnhandled() r.cachedErrUnhandled = r.errorUnhandled()
@ -80,14 +100,18 @@ func (r *ResolverGenerator) Definition() (types, predicates *codegen.Struct, err
r.cachedErrCannotTypeAssertPredicate = r.errorCannotTypeAssertPredicate() r.cachedErrCannotTypeAssertPredicate = r.errorCannotTypeAssertPredicate()
r.cachedIsUnFn = r.isUnFn() r.cachedIsUnFn = r.isUnFn()
r.cachedASInterface = r.asInterface() r.cachedASInterface = r.asInterface()
r.cachedResolverInterface = r.resolverInterface()
}) })
return r.cachedType, r.cachedPredicate, []jen.Code{ return r.cachedType, r.cachedInterface, r.cachedTypePredicate, r.cachedInterfacePredicate, []jen.Code{
r.cachedErrNoMatch, r.cachedErrNoMatch,
r.cachedErrUnhandled, r.cachedErrUnhandled,
r.cachedErrPredicateUnmatched, r.cachedErrPredicateUnmatched,
r.cachedErrCannotTypeAssert, r.cachedErrCannotTypeAssert,
r.cachedErrCannotTypeAssertPredicate, r.cachedErrCannotTypeAssertPredicate,
}, r.cachedIsUnFn, r.cachedASInterface }, r.cachedIsUnFn, []*codegen.Interface{
r.cachedASInterface,
r.cachedResolverInterface,
}
} }
// errorNoMatch returns the declaration for the ErrNoMatch global value. // errorNoMatch returns the declaration for the ErrNoMatch global value.
@ -151,120 +175,6 @@ func (r *ResolverGenerator) isUnFn() *codegen.Function {
// typeResolverMethods returns the methods for the TypeResolver. // typeResolverMethods returns the methods for the TypeResolver.
func (r *ResolverGenerator) typeResolverMethods() (m []*codegen.Method) { func (r *ResolverGenerator) typeResolverMethods() (m []*codegen.Method) {
m = append(m, r.resolveMethod(resolveMethod, typeResolverStructName))
return
}
// predicateResolverMethods returns the methods for the PredicateResolver.
func (r *ResolverGenerator) predicateResolverMethods() (m []*codegen.Method) {
m = append(m, r.applyMethod())
m = append(m, r.resolveMethod(resolveMethodPrivate, predicateResolverStructName))
return
}
// typeResolverFunctions returns the functions for the TypeResolver.
func (r *ResolverGenerator) typeResolverFunctions() (f []*codegen.Function) {
f = append(f, codegen.NewCommentedFunction(
r.pkg.Path(),
fmt.Sprintf("%s%s", constructorName, typeResolverStructName),
[]jen.Code{
jen.Id("callbacks").Index().Interface(),
},
[]jen.Code{
jen.Op("*").Id(typeResolverStructName),
jen.Error(),
},
[]jen.Code{
jen.For(
jen.List(
jen.Id("_"),
jen.Id("cb"),
).Op(":=").Range().Id("callbacks"),
).Block(
jen.Commentf("Each callback function must satisfy one known function signature, or else we will generate a runtime error instead of silently fail."),
jen.Switch(
jen.Id("cb").Assert(jen.Type()),
).Block(
r.mustAssertToKnownTypes("cb"),
),
),
jen.Return(
jen.Op("&").Id(typeResolverStructName).Values(
jen.Dict{
jen.Id(callbackMember): jen.Id("callbacks"),
},
),
jen.Nil(),
),
},
// TODO: Comment
fmt.Sprintf("%s%s", constructorName, typeResolverStructName)))
return
}
// predicateResolverFunctions returns the functions for the PredicateResolver.
func (r *ResolverGenerator) predicateResolverFunctions() (f []*codegen.Function) {
f = append(f, codegen.NewCommentedFunction(
r.pkg.Path(),
fmt.Sprintf("%s%s", constructorName, predicateResolverStructName),
[]jen.Code{
jen.Id("callbacks").Index().Interface(),
jen.Id("predicate").Interface(),
},
[]jen.Code{
jen.Op("*").Id(predicateResolverStructName),
jen.Error(),
},
[]jen.Code{
jen.For(
jen.List(
jen.Id("_"),
jen.Id("cb"),
).Op(":=").Range().Id("callbacks"),
).Block(
jen.Commentf("Each callback function must satisfy one known function signature, or else we will generate a runtime error instead of silently fail."),
jen.Switch(
jen.Id("cb").Assert(jen.Type()),
).Block(
r.mustAssertToKnownTypes("cb"),
),
),
jen.Commentf("The predicate must satisfy one known predicate function signature, or else we will generate a runtime error instead of silently fail."),
jen.Switch(
jen.Id("predicate").Assert(jen.Type()),
).Block(
r.mustAssertToKnownPredicate("predicate"),
),
jen.Return(
jen.Op("&").Id(typeResolverStructName).Values(
jen.Dict{
jen.Id(callbackMember): jen.Id("callbacks"),
jen.Id(predicateMember): jen.Id("predicate"),
},
),
jen.Nil(),
),
},
// TODO: Comment
fmt.Sprintf("%s%s", constructorName, predicateResolverStructName)))
return
}
// typeResolverMembers returns the members for the TypeResolver.
func (r *ResolverGenerator) typeResolverMembers() (m []jen.Code) {
m = append(m, jen.Id(callbackMember).Index().Interface())
return
}
// predicateResolverMembers returns the members for the PredicateResolver.
func (r *ResolverGenerator) predicateResolverMembers() (m []jen.Code) {
m = append(m, jen.Id(callbackMember).Index().Interface())
m = append(m, jen.Id(predicateMember).Interface())
return
}
// resolveMethod returns the Resolve method.
func (r *ResolverGenerator) resolveMethod(name, structName string) *codegen.Method {
impl := jen.Empty() impl := jen.Empty()
for _, t := range r.types { for _, t := range r.types {
impl = impl.Case( impl = impl.Case(
@ -305,10 +215,10 @@ func (r *ResolverGenerator) resolveMethod(name, structName string) *codegen.Meth
), ),
).Line() ).Line()
} }
return codegen.NewCommentedValueMethod( m = append(m, codegen.NewCommentedValueMethod(
r.pkg.Path(), r.pkg.Path(),
name, resolveMethod,
structName, typeResolverStructName,
[]jen.Code{ []jen.Code{
jen.Id("ctx").Qual("context", "Context"), jen.Id("ctx").Qual("context", "Context"),
jen.Id("o").Id(activityStreamInterface), jen.Id("o").Id(activityStreamInterface),
@ -321,7 +231,7 @@ func (r *ResolverGenerator) resolveMethod(name, structName string) *codegen.Meth
jen.List( jen.List(
jen.Id("_"), jen.Id("_"),
jen.Id("i"), jen.Id("i"),
).Op(":=").Range().Id(codegen.This()).Id(callbackMember), ).Op(":=").Range().Id(codegen.This()).Dot(callbackMember),
).Block( ).Block(
jen.Switch(jen.Id("o").Dot(typeNameMethod).Call()).Block( jen.Switch(jen.Id("o").Dot(typeNameMethod).Call()).Block(
impl.Default().Block( impl.Default().Block(
@ -336,37 +246,182 @@ func (r *ResolverGenerator) resolveMethod(name, structName string) *codegen.Meth
), ),
}, },
// TODO: Comment // TODO: Comment
fmt.Sprintf("", resolveMethod)) fmt.Sprintf("%s", resolveMethod)))
return
} }
// mustAssertToKnownTypes creates the type assertion switch statement that will // interfaceResolverMethods returns the methods for the TypeResolver.
// return an error if the parameter named does not match any of the expected func (r *ResolverGenerator) interfaceResolverMethods() (m []*codegen.Method) {
// function signatures. impl := jen.Empty()
func (r *ResolverGenerator) mustAssertToKnownTypes(paramName string) jen.Code {
c := jen.Empty()
for _, t := range r.types { for _, t := range r.types {
c = c.Case( impl = impl.If(
jen.List(
jen.Id("v"),
jen.Id("ok"),
).Op(":=").Id("o").Assert(
jen.Qual(t.PublicPackage().Path(), t.InterfaceName()),
),
jen.Id("ok"),
).Block(
jen.If(
jen.List(
jen.Id("fn"),
jen.Id("ok"),
).Op(":=").Id("i").Assert(
jen.Func().Parens( jen.Func().Parens(
jen.List( jen.List(
jen.Qual("context", "Context"), jen.Qual("context", "Context"),
jen.Qual(t.PublicPackage().Path(), t.InterfaceName()), jen.Qual(t.PublicPackage().Path(), t.InterfaceName()),
), ),
).Error(), ).Error(),
),
jen.Id("ok"),
).Block( ).Block(
jen.Commentf("Do nothing, this callback has a correct signature."), jen.Return(
jen.Id("fn").Call(jen.Id("ctx"), jen.Id("v")),
),
),
jen.Commentf("Else: this callback function doesn't support this duck-typed interface."),
).Line() ).Line()
} }
c = c.Default().Block( m = append(m, codegen.NewCommentedValueMethod(
jen.Return( r.pkg.Path(),
jen.Nil(), resolveMethod,
jen.Qual("errors", "New").Call(jen.Lit("a callback function is of the wrong signature and would never be called")), interfaceResolverStructName,
[]jen.Code{
jen.Id("ctx").Qual("context", "Context"),
jen.Id("o").Id(activityStreamInterface),
},
[]jen.Code{
jen.Error(),
},
[]jen.Code{
jen.For(
jen.List(
jen.Id("_"),
jen.Id("i"),
).Op(":=").Range().Id(codegen.This()).Dot(callbackMember),
).Block(
impl,
), ),
) jen.Return(
return c jen.Id(errorNoMatch),
),
},
// TODO: Comment
fmt.Sprintf("%s", resolveMethod)))
return
} }
// applyMethod generates the code required for the Apply method. // typePredicatedResolverMethods returns the methods for the TypePredicatedResolver.
func (r *ResolverGenerator) applyMethod() *codegen.Method { func (r *ResolverGenerator) typePredicatedResolverMethods() (m []*codegen.Method) {
impl := jen.Empty()
for _, t := range r.types {
impl = impl.Case(
jen.Lit(t.TypeName()),
).Block(
jen.If(
jen.List(
jen.Id("fn"),
jen.Id("ok"),
).Op(":=").Id(codegen.This()).Dot(predicateMember).Assert(
jen.Func().Parens(
jen.List(
jen.Qual("context", "Context"),
jen.Qual(t.PublicPackage().Path(), t.InterfaceName()),
),
).Parens(
jen.List(
jen.Bool(),
jen.Error(),
),
),
),
jen.Id("ok"),
).Block(
jen.If(
jen.List(
jen.Id("v"),
jen.Id("ok"),
).Op(":=").Id("o").Assert(
jen.Qual(t.PublicPackage().Path(), t.InterfaceName()),
),
jen.Id("ok"),
).Block(
jen.List(
jen.Id("predicatePasses"),
jen.Err(),
).Op("=").Id("fn").Call(jen.Id("ctx"), jen.Id("v")),
).Else().Block(
jen.Commentf("This occurs when the implementation is either not a go-fed type and is improperly satisfying various interfaces, or there is a bug in the go-fed generated code."),
jen.Return(
jen.False(),
jen.Id(errorCannotTypeAssert),
),
),
).Else().Block(
jen.Return(
jen.False(),
jen.Id(errorPredicateUnmatched),
),
),
).Line()
}
m = append(m, codegen.NewCommentedValueMethod(
r.pkg.Path(),
applyMethod,
typePredicatedResolverStructName,
[]jen.Code{
jen.Id("ctx").Qual("context", "Context"),
jen.Id("o").Id(activityStreamInterface),
},
[]jen.Code{
jen.Bool(),
jen.Error(),
},
[]jen.Code{
jen.Var().Id("predicatePasses").Bool(),
jen.Var().Err().Error(),
jen.Switch(jen.Id("o").Dot(typeNameMethod).Call()).Block(
impl.Default().Block(
jen.Return(
jen.False(),
jen.Id(errorUnhandled),
),
),
),
jen.If(
jen.Err().Op("!=").Nil(),
).Block(
jen.Return(
jen.Id("predicatePasses"),
jen.Err(),
),
),
jen.If(
jen.Id("predicatePasses"),
).Block(
jen.Return(
jen.True(),
jen.Id(codegen.This()).Dot(delegateMember).Dot(resolveMethod).Call(
jen.Id("ctx"),
jen.Id("o"),
),
),
).Else().Block(
jen.Return(
jen.False(),
jen.Nil(),
),
),
},
// TODO: Comment
fmt.Sprintf("%s", applyMethod)))
return
}
// interfacePredicatedResolverMethods returns the methods for the PredicateTypeResolver.
func (r *ResolverGenerator) interfacePredicatedResolverMethods() (m []*codegen.Method) {
impl := jen.Empty() impl := jen.Empty()
for _, t := range r.types { for _, t := range r.types {
impl = impl.Case( impl = impl.Case(
@ -403,10 +458,10 @@ func (r *ResolverGenerator) applyMethod() *codegen.Method {
), ),
).Line() ).Line()
} }
return codegen.NewCommentedValueMethod( m = append(m, codegen.NewCommentedValueMethod(
r.pkg.Path(), r.pkg.Path(),
applyMethod, applyMethod,
predicateResolverStructName, interfacePredicatedResolverStructName,
[]jen.Code{ []jen.Code{
jen.Id("ctx").Qual("context", "Context"), jen.Id("ctx").Qual("context", "Context"),
jen.Id("o").Id(activityStreamInterface), jen.Id("o").Id(activityStreamInterface),
@ -427,12 +482,20 @@ func (r *ResolverGenerator) applyMethod() *codegen.Method {
), ),
), ),
), ),
jen.If(
jen.Err().Op("!=").Nil(),
).Block(
jen.Return(
jen.Id("predicatePasses"),
jen.Err(),
),
),
jen.If( jen.If(
jen.Id("predicatePasses"), jen.Id("predicatePasses"),
).Block( ).Block(
jen.Return( jen.Return(
jen.True(), jen.True(),
jen.Id(codegen.This()).Dot(resolveMethodPrivate).Call( jen.Id(codegen.This()).Dot(delegateMember).Dot(resolveMethod).Call(
jen.Id("ctx"), jen.Id("ctx"),
jen.Id("o"), jen.Id("o"),
), ),
@ -445,7 +508,122 @@ func (r *ResolverGenerator) applyMethod() *codegen.Method {
), ),
}, },
// TODO: Comment // TODO: Comment
fmt.Sprintf("%s", applyMethod)) fmt.Sprintf("%s", applyMethod)))
return
}
// resolverFunctions returns the functions for the TypeResolver.
func (r *ResolverGenerator) resolverFunctions(name string) (f []*codegen.Function) {
f = append(f, codegen.NewCommentedFunction(
r.pkg.Path(),
fmt.Sprintf("%s%s", constructorName, name),
[]jen.Code{
jen.Id("callbacks").Index().Interface(),
},
[]jen.Code{
jen.Op("*").Id(name),
jen.Error(),
},
[]jen.Code{
jen.For(
jen.List(
jen.Id("_"),
jen.Id("cb"),
).Op(":=").Range().Id("callbacks"),
).Block(
jen.Commentf("Each callback function must satisfy one known function signature, or else we will generate a runtime error instead of silently fail."),
jen.Switch(
jen.Id("cb").Assert(jen.Type()),
).Block(
r.mustAssertToKnownTypes("cb"),
),
),
jen.Return(
jen.Op("&").Id(name).Values(
jen.Dict{
jen.Id(callbackMember): jen.Id("callbacks"),
},
),
jen.Nil(),
),
},
// TODO: Comment
fmt.Sprintf("%s%s", constructorName, name)))
return
}
// predicateResolverFunctions returns the functions for the PredicateTypeResolver.
func (r *ResolverGenerator) predicateResolverFunctions(name string) (f []*codegen.Function) {
f = append(f, codegen.NewCommentedFunction(
r.pkg.Path(),
fmt.Sprintf("%s%s", constructorName, name),
[]jen.Code{
jen.Id("delegate").Id(resolverInterface),
jen.Id("predicate").Interface(),
},
[]jen.Code{
jen.Op("*").Id(name),
jen.Error(),
},
[]jen.Code{
jen.Commentf("The predicate must satisfy one known predicate function signature, or else we will generate a runtime error instead of silently fail."),
jen.Switch(
jen.Id("predicate").Assert(jen.Type()),
).Block(
r.mustAssertToKnownPredicate("predicate"),
),
jen.Return(
jen.Op("&").Id(name).Values(
jen.Dict{
jen.Id(delegateMember): jen.Id("delegate"),
jen.Id(predicateMember): jen.Id("predicate"),
},
),
jen.Nil(),
),
},
// TODO: Comment
fmt.Sprintf("%s%s", constructorName, name)))
return
}
// resolverMembers returns the members for the TypeResolver.
func (r *ResolverGenerator) resolverMembers() (m []jen.Code) {
m = append(m, jen.Id(callbackMember).Index().Interface())
return
}
// predicateResolverMembers returns the members for the PredicateTypResolver.
func (r *ResolverGenerator) predicateResolverMembers() (m []jen.Code) {
m = append(m, jen.Id(delegateMember).Id(resolverInterface))
m = append(m, jen.Id(predicateMember).Interface())
return
}
// mustAssertToKnownTypes creates the type assertion switch statement that will
// return an error if the parameter named does not match any of the expected
// function signatures.
func (r *ResolverGenerator) mustAssertToKnownTypes(paramName string) jen.Code {
c := jen.Empty()
for _, t := range r.types {
c = c.Case(
jen.Func().Parens(
jen.List(
jen.Qual("context", "Context"),
jen.Qual(t.PublicPackage().Path(), t.InterfaceName()),
),
).Error(),
).Block(
jen.Commentf("Do nothing, this callback has a correct signature."),
).Line()
}
c = c.Default().Block(
jen.Return(
jen.Nil(),
jen.Qual("errors", "New").Call(jen.Lit("a callback function is of the wrong signature and would never be called")),
),
)
return c
} }
// mustAssertToKnownPredicate ensures the parameter name types-asserts to a // mustAssertToKnownPredicate ensures the parameter name types-asserts to a
@ -495,3 +673,26 @@ func (r *ResolverGenerator) asInterface() *codegen.Interface {
// TODO: Comment // TODO: Comment
fmt.Sprintf("%s", activityStreamInterface)) fmt.Sprintf("%s", activityStreamInterface))
} }
// resolverInterface returns the Resolver interface.
func (r *ResolverGenerator) resolverInterface() *codegen.Interface {
return codegen.NewInterface(
r.pkg.Path(),
resolverInterface,
[]codegen.FunctionSignature{
{
Name: resolveMethod,
Params: []jen.Code{
jen.Id("ctx").Qual("context", "Context"),
jen.Id("o").Id(activityStreamInterface),
},
Ret: []jen.Code{
jen.Error(),
},
// TODO: Comment
Comment: fmt.Sprintf("%s", resolveMethod),
},
},
//TODO: Comment
fmt.Sprintf("%s", resolverInterface))
}