Add default map value type

This commit is contained in:
Anton Medvedev
2024-08-28 23:00:18 +02:00
parent a8aece8708
commit 49cbda7b8f
3 changed files with 21 additions and 11 deletions
+2
View File
@@ -1090,9 +1090,11 @@ func TestCheck_types(t *testing.T) {
err string
}{
{`unknown`, noerr},
{`[unknown + 42, another_unknown + "foo"]`, noerr},
{`foo.bar.baz > 0`, `invalid operation: > (mismatched types string and int)`},
{`foo.unknown.baz`, `unknown field unknown (1:5)`},
{`foo.bar.unknown`, noerr},
{`foo.bar.unknown + 42`, `invalid operation: + (mismatched types string and int)`},
{`[foo] | map(.unknown)`, `unknown field unknown`},
{`[foo] | map(.bar) | filter(.baz)`, `predicate should return boolean (got string)`},
{`arr | filter(.value > 0)`, `invalid operation: > (mismatched types string and int)`},
+17 -11
View File
@@ -12,16 +12,17 @@ var (
)
type Nature struct {
Type reflect.Type // Type of the value. If nil, then value is unknown.
Func *builtin.Function // Used to pass function type from callee to CallNode.
ArrayOf *Nature // Elem nature of array type (usually Type is []any, but ArrayOf can be any nature).
PredicateOut *Nature // Out nature of predicate.
Fields map[string]Nature // Fields of map type.
Strict bool // If map is types.StrictMap.
Nil bool // If value is nil.
Method bool // If value retrieved from method. Usually used to determine amount of in arguments.
MethodIndex int // Index of method in type.
FieldIndex []int // Index of field in type.
Type reflect.Type // Type of the value. If nil, then value is unknown.
Func *builtin.Function // Used to pass function type from callee to CallNode.
ArrayOf *Nature // Elem nature of array type (usually Type is []any, but ArrayOf can be any nature).
PredicateOut *Nature // Out nature of predicate.
Fields map[string]Nature // Fields of map type.
DefaultMapValue *Nature // Default value of map type.
Strict bool // If map is types.StrictMap.
Nil bool // If value is nil.
Method bool // If value retrieved from method. Usually used to determine amount of in arguments.
MethodIndex int // Index of method in type.
FieldIndex []int // Index of field in type.
}
func (n Nature) String() string {
@@ -54,7 +55,12 @@ func (n Nature) Key() Nature {
func (n Nature) Elem() Nature {
switch n.Kind() {
case reflect.Map, reflect.Ptr:
case reflect.Ptr:
return Nature{Type: n.Type.Elem()}
case reflect.Map:
if n.DefaultMapValue != nil {
return *n.DefaultMapValue
}
return Nature{Type: n.Type.Elem()}
case reflect.Array, reflect.Slice:
if n.ArrayOf != nil {
+2
View File
@@ -108,6 +108,8 @@ func (m Map) Nature() Nature {
for k, v := range m {
if k == Extra {
nt.Strict = false
natureOfDefaultValue := v.Nature()
nt.DefaultMapValue = &natureOfDefaultValue
continue
}
nt.Fields[k] = v.Nature()