Drop types.StrictMap and add types.Extra to define additional keys

This commit is contained in:
Anton Medvedev
2024-08-28 22:47:47 +02:00
parent 95c433cd06
commit a8aece8708
5 changed files with 18 additions and 64 deletions
+7 -4
View File
@@ -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"
@@ -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 {
-6
View File
@@ -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)
@@ -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}
+2 -2
View File
@@ -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,
},
}
@@ -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,
},
}
+8 -45
View File
@@ -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
@@ -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}
+1 -7
View File
@@ -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
}{
@@ -22,15 +22,11 @@ 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},
@@ -38,8 +34,6 @@ func TestType_Equal(t *testing.T) {
{"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},
}