Skip to content

Commit

Permalink
Drop types.StrictMap and add types.Extra to define additional keys
Browse files Browse the repository at this point in the history
  • Loading branch information
antonmedv committed Aug 28, 2024
1 parent 5e660e7 commit c72da7b
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 64 deletions.
11 changes: 7 additions & 4 deletions checker/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1072,14 +1072,16 @@ func TestCheck_builtin_without_call(t *testing.T) {

func TestCheck_types(t *testing.T) {
env := types.Map{
"foo": types.StrictMap{
"foo": types.Map{
"bar": types.Map{
"baz": types.String,
"baz": types.String,
types.Extra: types.String,
},
},
"arr": types.Array(types.StrictMap{
"arr": types.Array(types.Map{
"value": types.String,
}),
types.Extra: types.Any,
}

noerr := "no error"
Expand All @@ -1102,7 +1104,8 @@ func TestCheck_types(t *testing.T) {
tree, err := parser.Parse(test.code)
require.NoError(t, err)

_, err = checker.Check(tree, conf.New(env))
config := conf.New(env)
_, err = checker.Check(tree, config)
if test.err == noerr {
require.NoError(t, err)
} else {
Expand Down
6 changes: 0 additions & 6 deletions conf/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ func Env(env any) Nature {
switch env := env.(type) {
case types.Map:
return env.Nature()

case types.StrictMap:
return env.Nature()
}

v := reflect.ValueOf(env)
Expand Down Expand Up @@ -53,9 +50,6 @@ func Env(env any) Nature {
case types.Map:
n.Fields[key.String()] = face.(types.Map).Nature()

case types.StrictMap:
n.Fields[key.String()] = face.(types.StrictMap).Nature()

default:
if face == nil {
n.Fields[key.String()] = Nature{Nil: true}
Expand Down
4 changes: 2 additions & 2 deletions expr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2704,7 +2704,7 @@ func TestExpr_nil_op_str(t *testing.T) {

func TestExpr_env_types_map(t *testing.T) {
envTypes := types.Map{
"foo": types.StrictMap{
"foo": types.Map{
"bar": types.String,
},
}
Expand All @@ -2725,7 +2725,7 @@ func TestExpr_env_types_map(t *testing.T) {

func TestExpr_env_types_map_error(t *testing.T) {
envTypes := types.Map{
"foo": types.StrictMap{
"foo": types.Map{
"bar": types.String,
},
}
Expand Down
53 changes: 8 additions & 45 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,22 @@ func (r rtype) String() string {
return r.t.String()
}

// Map returns a type that represents a map of the given type.
// The map is not strict, meaning that it can contain keys not defined in the map.
// Map represents a map[string]any type with defined keys.
type Map map[string]Type

const Extra = "[[__extra_keys__]]"

func (m Map) Nature() Nature {
nt := Nature{
Type: reflect.TypeOf(map[string]any{}),
Fields: make(map[string]Nature, len(m)),
Strict: true,
}
for k, v := range m {
if k == Extra {
nt.Strict = false
continue
}
nt.Fields[k] = v.Nature()
}
return nt
Expand Down Expand Up @@ -136,49 +142,6 @@ func (m Map) String() string {
return fmt.Sprintf("Map{%s}", strings.Join(pairs, ", "))
}

// StrictMap returns a type that represents a map of the given type.
// The map is strict, meaning that it can only contain keys defined in the map.
type StrictMap map[string]Type

func (m StrictMap) Nature() Nature {
nt := Nature{
Type: reflect.TypeOf(map[string]any{}),
Fields: make(map[string]Nature, len(m)),
Strict: true,
}
for k, v := range m {
nt.Fields[k] = v.Nature()
}
return nt
}

func (m StrictMap) Equal(t Type) bool {
if t == Any {
return true
}
mt, ok := t.(StrictMap)
if !ok {
return false
}
if len(m) != len(mt) {
return false
}
for k, v := range m {
if !v.Equal(mt[k]) {
return false
}
}
return true
}

func (m StrictMap) String() string {
pairs := make([]string, 0, len(m))
for k, v := range m {
pairs = append(pairs, fmt.Sprintf("%s: %s", k, v.String()))
}
return fmt.Sprintf("StrictMap{%s}", strings.Join(pairs, ", "))
}

// Array returns a type that represents an array of the given type.
func Array(of Type) Type {
return array{of}
Expand Down
8 changes: 1 addition & 7 deletions types/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

func TestType_Equal(t *testing.T) {
tests := []struct {
index string
index string // Index added for IDEA to show green test marker per test.
a, b Type
want bool
}{
Expand All @@ -22,24 +22,18 @@ func TestType_Equal(t *testing.T) {
{"7", Int, Nil, false},
{"8", Int, Array(Int), false},
{"9", Int, Map{"foo": Int}, false},
{"10", Int, StrictMap{"foo": Int}, false},
{"11", Int, Array(Int), false},
{"12", Array(Int), Array(Int), true},
{"13", Array(Int), Array(Float), false},
{"14", Map{"foo": Int}, Map{"foo": Int}, true},
{"15", Map{"foo": Int}, Map{"foo": Float}, false},
{"16", Map{"foo": Int}, StrictMap{"foo": Int}, false},
{"17", StrictMap{"foo": Int}, StrictMap{"foo": Int}, true},
{"18", StrictMap{"foo": Int}, StrictMap{"foo": Float}, false},
{"19", Map{"foo": Map{"bar": Int}}, Map{"foo": Map{"bar": Int}}, true},
{"20", Map{"foo": Map{"bar": Int}}, Map{"foo": Map{"bar": Float}}, false},
{"21", Any, Any, true},
{"22", Any, Int, true},
{"23", Int, Any, true},
{"24", Any, Map{"foo": Int}, true},
{"25", Map{"foo": Int}, Any, true},
{"26", Any, StrictMap{"foo": Int}, true},
{"27", StrictMap{"foo": Int}, Any, true},
{"28", Any, Array(Int), true},
{"29", Array(Int), Any, true},
}
Expand Down

0 comments on commit c72da7b

Please sign in to comment.