Commit d2f22711 authored by Eric Myhre's avatar Eric Myhre

Correctly generate all rejection branches in kinded union node accessors.

This template munging business got nastier as time proceded.
I think we could drastically reduce the amount of redundancy in the
arugments to `kindedUnionNodeMethodTemplateMunge` if we re-did that
function with a more structural understanding of what's going on,
and made some basic understanding of what zero values are per golang
type, etc.

That can be future work, though.  Today, I want working kinded unions,
and I just want them done enough to use; kludge tolerance high.
parent 792f8937
...@@ -56,7 +56,7 @@ What mechanism of extraction should be used? ...@@ -56,7 +56,7 @@ What mechanism of extraction should be used?
- (for gen-side dry) sub-templates - (for gen-side dry) sub-templates
- we currently don't really use this at all - we currently don't really use this at all
- (for gen-side dry) template concatenation - (for gen-side dry) template concatenation
- we currently don't really use this at all either - some of this: kinded union representations do this
- (for output-side dry) output side functions - (for output-side dry) output side functions
- some of this: see "minima" file. - some of this: see "minima" file.
- (for output-side dry) output side embeds - (for output-side dry) output side embeds
......
...@@ -102,11 +102,24 @@ func (g unionReprKindedReprGenerator) EmitNodeMethodReprKind(w io.Writer) { ...@@ -102,11 +102,24 @@ func (g unionReprKindedReprGenerator) EmitNodeMethodReprKind(w io.Writer) {
// Regardless, the gsloc is reducable. (Slightly. There are also bigger gains to be made elsewhere, I'm sure.) // Regardless, the gsloc is reducable. (Slightly. There are also bigger gains to be made elsewhere, I'm sure.)
func kindedUnionNodeMethodTemplateMunge( func kindedUnionNodeMethodTemplateMunge(
methodSig string, condClause string, retClause string, methodName string, // for error messages
methodSig string, // output literally
condClause string, // template condition for the member this should match on
retClause string, // clause returning the thing (how to delegate methodsig, generally)
appropriateKind string, // for error messages
nopeSentinel string, // for error return paths; generally the zero value for the first return type.
nopeSentinelOnly bool, // true if this method has no error return, just the sentinel.
) string { ) string {
// We really could just... call the methods directly (and elide the switch entirely all the time), in the case of the "interface" implementation strategy. // We really could just... call the methods directly (and elide the switch entirely all the time), in the case of the "interface" implementation strategy.
// We don't, though, because that would deprive us of getting the union type's name in the wrong-kind errors... // We don't, though, because that would deprive us of getting the union type's name in the wrong-kind errors...
// and in addition to that being sadface in general, it would be downright unacceptable if that behavior varied based on implementation strategy. // and in addition to that being sadface in general, it would be downright unacceptable if that behavior varied based on implementation strategy.
//
// This error text doesn't tell us what the member kind is. This might read weirdly.
// It's possible we could try to cram a description of the inhabitant into the "TypeName" since it's stringy; but unclear if that's a good idea either.
errorClause := `return ` + nopeSentinel
if !nopeSentinelOnly {
errorClause += `, ipld.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}.Repr", MethodName: "` + methodName + `", AppropriateKind: ` + appropriateKind + `, ActualKind: n.ReprKind()}`
}
return ` return `
func (n *_{{ .Type | TypeSymbol }}__Repr) ` + methodSig + ` { func (n *_{{ .Type | TypeSymbol }}__Repr) ` + methodSig + ` {
{{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }}
...@@ -127,66 +140,93 @@ func kindedUnionNodeMethodTemplateMunge( ...@@ -127,66 +140,93 @@ func kindedUnionNodeMethodTemplateMunge(
{{- end}} {{- end}}
{{- end}} {{- end}}
default: default:
return nil, ipld.ErrWrongKind{doozy} // ... is this a good example of where ErrFoo.TypeName should indeed be freetext, so it can say "ThisUnion.Repr(inhabitant not FooMap)" ...? ` + errorClause + `
} }
} }
` `
// TODO damnit I need the method name again for error messages. ... maybe make the error be a clause, hm.
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodLookupByString(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodLookupByString(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`LookupByString`,
`LookupByString(key string) (ipld.Node, error)`, `LookupByString(key string) (ipld.Node, error)`,
`{{- if eq $member.RepresentationBehavior.String "map" }}`, `{{- if eq $member.RepresentationBehavior.String "map" }}`,
`.LookupByString(key)`, `.LookupByString(key)`,
`ipld.ReprKindSet_JustMap`,
`nil`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodLookupByIndex(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodLookupByIndex(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`LookupByIndex`,
`LookupByIndex(idx int) (ipld.Node, error)`, `LookupByIndex(idx int) (ipld.Node, error)`,
`{{- if eq $member.RepresentationBehavior.String "list" }}`, `{{- if eq $member.RepresentationBehavior.String "list" }}`,
`.LookupByIndex(idx)`, `.LookupByIndex(idx)`,
`ipld.ReprKindSet_JustList`,
`nil`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`LookupByNode`,
`LookupByNode(key ipld.Node) (ipld.Node, error)`, `LookupByNode(key ipld.Node) (ipld.Node, error)`,
`{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`, `{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`,
`.LookupByNode(key)`, `.LookupByNode(key)`,
`ipld.ReprKindSet_Recursive`,
`nil`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodLookupBySegment(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodLookupBySegment(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`LookupBySegment`,
`LookupBySegment(seg ipld.PathSegment) (ipld.Node, error)`, `LookupBySegment(seg ipld.PathSegment) (ipld.Node, error)`,
`{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`, `{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`,
`.LookupBySegment(seg)`, `.LookupBySegment(seg)`,
`ipld.ReprKindSet_Recursive`,
`nil`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodMapIterator(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodMapIterator(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`MapIterator`,
`MapIterator() ipld.MapIterator`, `MapIterator() ipld.MapIterator`,
`{{- if eq $member.RepresentationBehavior.String "map" }}`, `{{- if eq $member.RepresentationBehavior.String "map" }}`,
`.MapIterator()`, `.MapIterator()`,
`ipld.ReprKindSet_JustMap`,
`nil`,
true,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodListIterator(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodListIterator(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`ListIterator`,
`ListIterator() ipld.ListIterator`, `ListIterator() ipld.ListIterator`,
`{{- if eq $member.RepresentationBehavior.String "list" }}`, `{{- if eq $member.RepresentationBehavior.String "list" }}`,
`.ListIterator()`, `.ListIterator()`,
`ipld.ReprKindSet_JustList`,
`nil`,
true,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodLength(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodLength(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`Length`,
`Length() int`, `Length() int`,
`{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`, `{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`,
`.Length()`, `.Length()`,
`ipld.ReprKindSet_Recursive`,
`-1`,
true,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
...@@ -208,49 +248,73 @@ func (g unionReprKindedReprGenerator) EmitNodeMethodIsNull(w io.Writer) { ...@@ -208,49 +248,73 @@ func (g unionReprKindedReprGenerator) EmitNodeMethodIsNull(w io.Writer) {
func (g unionReprKindedReprGenerator) EmitNodeMethodAsBool(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodAsBool(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`AsBool`,
`AsBool() (bool, error)`, `AsBool() (bool, error)`,
`{{- if eq $member.RepresentationBehavior.String "bool" }}`, `{{- if eq $member.RepresentationBehavior.String "bool" }}`,
`.AsBool()`, `.AsBool()`,
`ipld.ReprKindSet_JustBool`,
`false`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodAsInt(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodAsInt(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`AsInt`,
`AsInt() (int, error)`, `AsInt() (int, error)`,
`{{- if eq $member.RepresentationBehavior.String "int" }}`, `{{- if eq $member.RepresentationBehavior.String "int" }}`,
`.AsInt()`, `.AsInt()`,
`ipld.ReprKindSet_JustInt`,
`0`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodAsFloat(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodAsFloat(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`AsFloat`,
`AsFloat() (float64, error)`, `AsFloat() (float64, error)`,
`{{- if eq $member.RepresentationBehavior.String "float" }}`, `{{- if eq $member.RepresentationBehavior.String "float" }}`,
`.AsFloat()`, `.AsFloat()`,
`ipld.ReprKindSet_JustFloat`,
`0`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodAsString(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodAsString(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`AsString`,
`AsString() (string, error)`, `AsString() (string, error)`,
`{{- if eq $member.RepresentationBehavior.String "string" }}`, `{{- if eq $member.RepresentationBehavior.String "string" }}`,
`.AsString()`, `.AsString()`,
`ipld.ReprKindSet_JustString`,
`""`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodAsBytes(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodAsBytes(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`AsBytes`,
`AsBytes() ([]byte, error)`, `AsBytes() ([]byte, error)`,
`{{- if eq $member.RepresentationBehavior.String "bytes" }}`, `{{- if eq $member.RepresentationBehavior.String "bytes" }}`,
`.AsBytes()`, `.AsBytes()`,
`ipld.ReprKindSet_JustBytes`,
`nil`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
func (g unionReprKindedReprGenerator) EmitNodeMethodAsLink(w io.Writer) { func (g unionReprKindedReprGenerator) EmitNodeMethodAsLink(w io.Writer) {
doTemplate(kindedUnionNodeMethodTemplateMunge( doTemplate(kindedUnionNodeMethodTemplateMunge(
`AsLink`,
`AsLink() (ipld.Link, error)`, `AsLink() (ipld.Link, error)`,
`{{- if eq $member.RepresentationBehavior.String "link" }}`, `{{- if eq $member.RepresentationBehavior.String "link" }}`,
`.AsLink()`, `.AsLink()`,
`ipld.ReprKindSet_JustLink`,
`nil`,
false,
), w, g.AdjCfg, g) ), w, g.AdjCfg, g)
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment