mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-30 10:45:18 -06:00
Add Map codegen
This commit is contained in:
60
nomgen/map.tmpl
Normal file
60
nomgen/map.tmpl
Normal file
@@ -0,0 +1,60 @@
|
||||
// {{.StructName}}
|
||||
|
||||
type {{.StructName}} struct {
|
||||
m types.Map
|
||||
}
|
||||
|
||||
type {{.StructName}}IterCallback (func(k {{.KeyName}}, v {{.ValueName}}) (stop bool))
|
||||
|
||||
func New{{.StructName}}() {{.StructName}} {
|
||||
return {{.StructName}}{types.NewMap()}
|
||||
}
|
||||
|
||||
func {{.StructName}}FromVal(p types.Value) {{.StructName}} {
|
||||
return {{.StructName}}{p.(types.Map)}
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) NomsValue() types.Map {
|
||||
return m.m
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Equals(p {{.StructName}}) bool {
|
||||
return m.m.Equals(p.m)
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Ref() ref.Ref {
|
||||
return m.m.Ref()
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Empty() bool {
|
||||
return m.m.Empty()
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Len() uint64 {
|
||||
return m.m.Len()
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Has(p {{.KeyName}}) bool {
|
||||
return m.m.Has(p{{toVal .KeyName}})
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Get(p {{.KeyName}}) {{.ValueName}} {
|
||||
return {{fromVal .ValueName}}(m.m.Get(p{{toVal .KeyName}}))
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Set(k {{.KeyName}}, v {{.ValueName}}) {{.StructName}} {
|
||||
return {{fromVal .StructName}}(m.m.Set(k{{toVal .KeyName}}, v{{toVal .ValueName}}))
|
||||
}
|
||||
|
||||
// TODO: Implement SetM?
|
||||
|
||||
func (m {{.StructName}}) Remove(p {{.KeyName}}) {{.StructName}} {
|
||||
return {{fromVal .StructName}}(m.m.Remove(p{{toVal .KeyName}}))
|
||||
}
|
||||
|
||||
func (m {{.StructName}}) Iter(cb {{.StructName}}IterCallback) {
|
||||
m.m.Iter(func(k, v types.Value) bool {
|
||||
return cb({{fromVal .KeyName}}(k), {{fromVal .ValueName}}(v))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ var (
|
||||
fieldTempl = readTemplate("field.tmpl")
|
||||
headerTmpl = readTemplate("header.tmpl")
|
||||
listTempl = readTemplate("list.tmpl")
|
||||
mapTempl = readTemplate("map.tmpl")
|
||||
setTempl = readTemplate("set.tmpl")
|
||||
structTempl = readTemplate("struct.tmpl")
|
||||
)
|
||||
@@ -92,14 +93,17 @@ func readTemplate(name string) *template.Template {
|
||||
func (ng *NG) writeType(val types.Map) {
|
||||
typ := val.Get(types.NewString("$type")).(types.String).String()
|
||||
switch typ {
|
||||
case "noms.StructDef":
|
||||
ng.writeStruct(val)
|
||||
case "noms.ListDef":
|
||||
ng.writeList(val)
|
||||
return
|
||||
case "noms.MapDef":
|
||||
ng.writeMap(val)
|
||||
return
|
||||
case "noms.SetDef":
|
||||
ng.writeSet(val)
|
||||
return
|
||||
case "noms.ListDef":
|
||||
ng.writeList(val)
|
||||
case "noms.StructDef":
|
||||
ng.writeStruct(val)
|
||||
return
|
||||
}
|
||||
Chk.Fail(fmt.Sprintf("Unexpected typedef: %+v", val))
|
||||
@@ -135,6 +139,25 @@ func (ng *NG) writeList(val types.Map) {
|
||||
listTempl.Execute(ng.w, data)
|
||||
}
|
||||
|
||||
func (ng *NG) writeMap(val types.Map) {
|
||||
key := val.Get(types.NewString("key"))
|
||||
ng.addType(key)
|
||||
valueName := val.Get(types.NewString("value"))
|
||||
ng.addType(valueName)
|
||||
|
||||
data := struct {
|
||||
StructName string
|
||||
KeyName string
|
||||
ValueName string
|
||||
}{
|
||||
getGoTypeName(val),
|
||||
getGoTypeName(key),
|
||||
getGoTypeName(valueName),
|
||||
}
|
||||
|
||||
mapTempl.Execute(ng.w, data)
|
||||
}
|
||||
|
||||
func (ng *NG) writeStruct(val types.Map) {
|
||||
structName := getGoTypeName(val)
|
||||
structTempl.Execute(ng.w, struct {
|
||||
@@ -171,23 +194,36 @@ func (ng *NG) writeField(structName, fieldName string, typeDef types.Value) {
|
||||
}
|
||||
|
||||
func getGoTypeName(typeDef types.Value) string {
|
||||
typeName := getGoStructName(typeDef)
|
||||
switch typeDef.(type) {
|
||||
case types.String:
|
||||
return fmt.Sprintf("types.%s", typeName)
|
||||
}
|
||||
return typeName
|
||||
}
|
||||
|
||||
func getGoStructName(typeDef types.Value) string {
|
||||
switch typeDef := typeDef.(type) {
|
||||
case types.String:
|
||||
name := typeDef.String()
|
||||
switch name {
|
||||
case "bool", "int16", "int32", "int64", "uint16", "uint32", "uint64", "float32", "float64", "blob", "string", "set", "map", "value":
|
||||
return fmt.Sprintf("types.%s", strings.Title(typeDef.String()))
|
||||
return strings.Title(typeDef.String())
|
||||
}
|
||||
Chk.Fail("unexpected noms type name: %s", name)
|
||||
case types.Map:
|
||||
typ := typeDef.Get(types.NewString("$type")).(types.String).String()
|
||||
switch typ {
|
||||
case "noms.ListDef":
|
||||
return fmt.Sprintf("%sList", getGoStructName(typeDef.Get(types.NewString("elem"))))
|
||||
case "noms.MapDef":
|
||||
return fmt.Sprintf("%s%sMap",
|
||||
getGoStructName(typeDef.Get(types.NewString("key"))),
|
||||
getGoStructName(typeDef.Get(types.NewString("value"))))
|
||||
case "noms.SetDef":
|
||||
return fmt.Sprintf("%sSet", getGoStructName(typeDef.Get(types.NewString("elem"))))
|
||||
case "noms.StructDef":
|
||||
return typeDef.Get(types.NewString("$name")).(types.String).String()
|
||||
case "noms.SetDef":
|
||||
return fmt.Sprintf("%sSet", getGoTypeName(typeDef.Get(types.NewString("elem"))))
|
||||
case "noms.ListDef":
|
||||
return fmt.Sprintf("%sList", getGoTypeName(typeDef.Get(types.NewString("elem"))))
|
||||
}
|
||||
}
|
||||
Chk.Fail("Unexpected typeDef struct: %+v", typeDef)
|
||||
|
||||
@@ -32,6 +32,10 @@ func (l List) Len() uint64 {
|
||||
return uint64(len(l.list))
|
||||
}
|
||||
|
||||
func (l List) Empty() bool {
|
||||
return l.Len() == uint64(0)
|
||||
}
|
||||
|
||||
func (l List) Get(idx uint64) Value {
|
||||
v, err := l.list[idx].Deref(l.cs)
|
||||
// This is the kind of thing that makes me feel like hiding deref'ing is probably not the right idea. But we'll go with it for now.
|
||||
|
||||
@@ -17,6 +17,17 @@ func TestListLen(t *testing.T) {
|
||||
assert.Equal(uint64(3), l.Len())
|
||||
}
|
||||
|
||||
func TestListEmpty(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
l := NewList()
|
||||
assert.True(l.Empty())
|
||||
l = l.Append(Bool(true))
|
||||
assert.False(l.Empty())
|
||||
l = l.Append(Bool(false), Bool(false))
|
||||
assert.False(l.Empty())
|
||||
}
|
||||
|
||||
func TestListGet(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ func (fm Map) Len() uint64 {
|
||||
return uint64(len(fm.m))
|
||||
}
|
||||
|
||||
func (fm Map) Empty() bool {
|
||||
return fm.Len() == uint64(0)
|
||||
}
|
||||
|
||||
func (fm Map) Has(key Value) bool {
|
||||
idx := indexMapData(fm.m, key.Ref())
|
||||
return idx < len(fm.m) && futureEqualsValue(fm.m[idx].key, key)
|
||||
|
||||
@@ -156,3 +156,13 @@ func TestMapNotStringKeys(t *testing.T) {
|
||||
}
|
||||
assert.Nil(m1.Get(Int32(42)))
|
||||
}
|
||||
|
||||
func TestMapEmpty(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
m := NewMap()
|
||||
assert.True(m.Empty())
|
||||
m = m.Set(Bool(false), NewString("hi"))
|
||||
assert.False(m.Empty())
|
||||
m = m.Set(NewList(), NewMap())
|
||||
assert.False(m.Empty())
|
||||
}
|
||||
|
||||
@@ -16,6 +16,16 @@ func TestSetLen(t *testing.T) {
|
||||
assert.Equal(uint64(3), s3.Len())
|
||||
}
|
||||
|
||||
func TestSetEmpty(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
s := NewSet()
|
||||
assert.True(s.Empty())
|
||||
s = s.Insert(Bool(false))
|
||||
assert.False(s.Empty())
|
||||
s = s.Insert(Int32(42))
|
||||
assert.False(s.Empty())
|
||||
}
|
||||
|
||||
// BUG 98
|
||||
func TestSetDuplicateInsert(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
Reference in New Issue
Block a user