Replace interface{} with any

This commit is contained in:
Anton Medvedev
2023-08-30 11:25:15 +02:00
parent 688b914fa6
commit 32f5fde2eb
44 changed files with 469 additions and 469 deletions
+2 -2
View File
@@ -4,8 +4,8 @@ import "reflect"
type Function struct {
Name string
Func func(args ...interface{}) (interface{}, error)
Fast func(arg interface{}) interface{}
Func func(args ...any) (any, error)
Fast func(arg any) any
Types []reflect.Type
Validate func(args []reflect.Type) (reflect.Type, error)
Predicate bool
+1 -1
View File
@@ -77,7 +77,7 @@ type StringNode struct {
type ConstantNode struct {
base
Value interface{}
Value any
}
type UnaryNode struct {
+1 -1
View File
@@ -91,7 +91,7 @@ func TestPrint_MemberNode(t *testing.T) {
func TestPrint_ConstantNode(t *testing.T) {
tests := []struct {
input interface{}
input any
want string
}{
{nil, `nil`},
+34 -34
View File
@@ -9,7 +9,7 @@ import (
)
func Benchmark_expr(b *testing.B) {
params := make(map[string]interface{})
params := make(map[string]any)
params["Origin"] = "MOW"
params["Country"] = "RU"
params["Adults"] = 1
@@ -18,7 +18,7 @@ func Benchmark_expr(b *testing.B) {
program, err := expr.Compile(`(Origin == "MOW" || Country == "RU") && (Value >= 100 || Adults == 1)`, expr.Env(params))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
@@ -31,7 +31,7 @@ func Benchmark_expr(b *testing.B) {
}
func Benchmark_expr_reuseVm(b *testing.B) {
params := make(map[string]interface{})
params := make(map[string]any)
params["Origin"] = "MOW"
params["Country"] = "RU"
params["Adults"] = 1
@@ -40,7 +40,7 @@ func Benchmark_expr_reuseVm(b *testing.B) {
program, err := expr.Compile(`(Origin == "MOW" || Country == "RU") && (Value >= 100 || Adults == 1)`, expr.Env(params))
require.NoError(b, err)
var out interface{}
var out any
v := vm.VM{}
b.ResetTimer()
@@ -54,14 +54,14 @@ func Benchmark_expr_reuseVm(b *testing.B) {
}
func Benchmark_len(b *testing.B) {
env := map[string]interface{}{
env := map[string]any{
"arr": make([]int, 100),
}
program, err := expr.Compile(`len(arr)`, expr.Env(env))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -86,7 +86,7 @@ func Benchmark_filter(b *testing.B) {
program, err := expr.Compile(`filter(Ints, # % 7 == 0)`, expr.Env(Env{}))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -94,7 +94,7 @@ func Benchmark_filter(b *testing.B) {
b.StopTimer()
require.NoError(b, err)
require.Len(b, out.([]interface{}), 142)
require.Len(b, out.([]any), 142)
}
func Benchmark_filterLen(b *testing.B) {
@@ -111,7 +111,7 @@ func Benchmark_filterLen(b *testing.B) {
program, err := expr.Compile(`len(filter(Ints, # % 7 == 0))`, expr.Env(Env{}))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -136,7 +136,7 @@ func Benchmark_filterFirst(b *testing.B) {
program, err := expr.Compile(`filter(Ints, # % 7 == 0)[0]`, expr.Env(Env{}))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -161,7 +161,7 @@ func Benchmark_filterLast(b *testing.B) {
program, err := expr.Compile(`filter(Ints, # % 7 == 0)[-1]`, expr.Env(Env{}))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -187,7 +187,7 @@ func Benchmark_filterMap(b *testing.B) {
program, err := expr.Compile(`map(filter(Ints, # % 7 == 0), # * 2)`, expr.Env(Env{}))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -195,12 +195,12 @@ func Benchmark_filterMap(b *testing.B) {
b.StopTimer()
require.NoError(b, err)
require.Len(b, out.([]interface{}), 14)
require.Equal(b, 14, out.([]interface{})[0])
require.Len(b, out.([]any), 14)
require.Equal(b, 14, out.([]any)[0])
}
func Benchmark_arrayIndex(b *testing.B) {
env := map[string]interface{}{
env := map[string]any{
"arr": make([]int, 100),
}
for i := 0; i < 100; i++ {
@@ -210,7 +210,7 @@ func Benchmark_arrayIndex(b *testing.B) {
program, err := expr.Compile(`arr[50]`, expr.Env(env))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -234,7 +234,7 @@ func Benchmark_envStruct(b *testing.B) {
env := Env{Price: Price{Value: 1}}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -249,14 +249,14 @@ func Benchmark_envMap(b *testing.B) {
type Price struct {
Value int
}
env := map[string]interface{}{
env := map[string]any{
"price": Price{Value: 1},
}
program, err := expr.Compile(`price.Value > 0`, expr.Env(env))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -272,7 +272,7 @@ type CallEnv struct {
B int
C int
Fn func() bool
FnFast func(...interface{}) interface{}
FnFast func(...any) any
Foo CallFoo
}
@@ -296,7 +296,7 @@ func Benchmark_callFunc(b *testing.B) {
env := CallEnv{}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -313,7 +313,7 @@ func Benchmark_callMethod(b *testing.B) {
env := CallEnv{}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -334,7 +334,7 @@ func Benchmark_callField(b *testing.B) {
},
}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -352,12 +352,12 @@ func Benchmark_callFast(b *testing.B) {
}
env := CallEnv{
FnFast: func(s ...interface{}) interface{} {
FnFast: func(s ...any) any {
return "fn_fast"
},
}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -374,7 +374,7 @@ func Benchmark_callConstExpr(b *testing.B) {
env := CallEnv{}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, env)
@@ -396,7 +396,7 @@ func Benchmark_largeStructAccess(b *testing.B) {
env := Env{Field: 21}
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, &env)
@@ -421,7 +421,7 @@ func Benchmark_largeNestedStructAccess(b *testing.B) {
env := Env{}
env.Inner.Field = 21
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, &env)
@@ -443,7 +443,7 @@ func Benchmark_largeNestedArrayAccess(b *testing.B) {
env := Env{}
env.Data[0][0] = 1
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, err = vm.Run(program, &env)
@@ -455,14 +455,14 @@ func Benchmark_largeNestedArrayAccess(b *testing.B) {
}
func Benchmark_sort(b *testing.B) {
env := map[string]interface{}{
env := map[string]any{
"arr": []any{55, 58, 42, 61, 75, 52, 64, 62, 16, 79, 40, 14, 50, 76, 23, 2, 5, 80, 89, 51, 21, 96, 91, 13, 71, 82, 65, 63, 11, 17, 94, 81, 74, 4, 97, 1, 39, 3, 28, 8, 84, 90, 47, 85, 7, 56, 49, 93, 33, 12, 19, 60, 86, 100, 44, 45, 36, 72, 95, 77, 34, 92, 24, 73, 18, 38, 43, 26, 41, 69, 67, 57, 9, 27, 66, 87, 46, 35, 59, 70, 10, 20, 53, 15, 32, 98, 68, 31, 54, 25, 83, 88, 22, 48, 29, 37, 6, 78, 99, 30},
}
program, err := expr.Compile(`sort(arr)`, expr.Env(env))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, _ = vm.Run(program, env)
@@ -478,7 +478,7 @@ func Benchmark_sortBy(b *testing.B) {
Value int
}
arr := []any{55, 58, 42, 61, 75, 52, 64, 62, 16, 79, 40, 14, 50, 76, 23, 2, 5, 80, 89, 51, 21, 96, 91, 13, 71, 82, 65, 63, 11, 17, 94, 81, 74, 4, 97, 1, 39, 3, 28, 8, 84, 90, 47, 85, 7, 56, 49, 93, 33, 12, 19, 60, 86, 100, 44, 45, 36, 72, 95, 77, 34, 92, 24, 73, 18, 38, 43, 26, 41, 69, 67, 57, 9, 27, 66, 87, 46, 35, 59, 70, 10, 20, 53, 15, 32, 98, 68, 31, 54, 25, 83, 88, 22, 48, 29, 37, 6, 78, 99, 30}
env := map[string]interface{}{
env := map[string]any{
"arr": make([]Foo, len(arr)),
}
for i, v := range arr {
@@ -488,7 +488,7 @@ func Benchmark_sortBy(b *testing.B) {
program, err := expr.Compile(`sortBy(arr, "Value")`, expr.Env(env))
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, _ = vm.Run(program, env)
@@ -503,7 +503,7 @@ func Benchmark_groupBy(b *testing.B) {
program, err := expr.Compile(`groupBy(1..100, # % 7)[6]`)
require.NoError(b, err)
var out interface{}
var out any
b.ResetTimer()
for n := 0; n < b.N; n++ {
out, _ = vm.Run(program, nil)
+50 -50
View File
@@ -31,57 +31,57 @@ var Builtins = []*ast.Function{
{
Name: "all",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) bool)),
Types: types(new(func([]any, func(any) bool) bool)),
},
{
Name: "none",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) bool)),
Types: types(new(func([]any, func(any) bool) bool)),
},
{
Name: "any",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) bool)),
Types: types(new(func([]any, func(any) bool) bool)),
},
{
Name: "one",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) bool)),
Types: types(new(func([]any, func(any) bool) bool)),
},
{
Name: "filter",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) []interface{})),
Types: types(new(func([]any, func(any) bool) []any)),
},
{
Name: "map",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) interface{}) []interface{})),
Types: types(new(func([]any, func(any) any) []any)),
},
{
Name: "count",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) int)),
Types: types(new(func([]any, func(any) bool) int)),
},
{
Name: "find",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) interface{})),
Types: types(new(func([]any, func(any) bool) any)),
},
{
Name: "findIndex",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) int)),
Types: types(new(func([]any, func(any) bool) int)),
},
{
Name: "findLast",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) interface{})),
Types: types(new(func([]any, func(any) bool) any)),
},
{
Name: "findLastIndex",
Predicate: true,
Types: types(new(func([]interface{}, func(interface{}) bool) int)),
Types: types(new(func([]any, func(any) bool) int)),
},
{
Name: "len",
@@ -100,7 +100,7 @@ var Builtins = []*ast.Function{
{
Name: "type",
Fast: Type,
Types: types(new(func(interface{}) string)),
Types: types(new(func(any) string)),
},
{
Name: "abs",
@@ -155,11 +155,11 @@ var Builtins = []*ast.Function{
{
Name: "string",
Fast: String,
Types: types(new(func(any interface{}) string)),
Types: types(new(func(any any) string)),
},
{
Name: "trim",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) == 1 {
return strings.TrimSpace(args[0].(string)), nil
} else if len(args) == 2 {
@@ -175,7 +175,7 @@ var Builtins = []*ast.Function{
},
{
Name: "trimPrefix",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
s := " "
if len(args) == 2 {
s = args[1].(string)
@@ -189,7 +189,7 @@ var Builtins = []*ast.Function{
},
{
Name: "trimSuffix",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
s := " "
if len(args) == 2 {
s = args[1].(string)
@@ -203,21 +203,21 @@ var Builtins = []*ast.Function{
},
{
Name: "upper",
Fast: func(arg interface{}) interface{} {
Fast: func(arg any) any {
return strings.ToUpper(arg.(string))
},
Types: types(strings.ToUpper),
},
{
Name: "lower",
Fast: func(arg interface{}) interface{} {
Fast: func(arg any) any {
return strings.ToLower(arg.(string))
},
Types: types(strings.ToLower),
},
{
Name: "split",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) == 2 {
return strings.Split(args[0].(string), args[1].(string)), nil
} else if len(args) == 3 {
@@ -233,7 +233,7 @@ var Builtins = []*ast.Function{
},
{
Name: "splitAfter",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) == 2 {
return strings.SplitAfter(args[0].(string), args[1].(string)), nil
} else if len(args) == 3 {
@@ -249,7 +249,7 @@ var Builtins = []*ast.Function{
},
{
Name: "replace",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) == 4 {
return strings.Replace(args[0].(string), args[1].(string), args[2].(string), runtime.ToInt(args[3])), nil
} else if len(args) == 3 {
@@ -265,7 +265,7 @@ var Builtins = []*ast.Function{
},
{
Name: "repeat",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
n := runtime.ToInt(args[1])
if n > 1e6 {
panic("memory budget exceeded")
@@ -276,7 +276,7 @@ var Builtins = []*ast.Function{
},
{
Name: "join",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
glue := ""
if len(args) == 2 {
glue = args[1].(string)
@@ -284,9 +284,9 @@ var Builtins = []*ast.Function{
switch args[0].(type) {
case []string:
return strings.Join(args[0].([]string), glue), nil
case []interface{}:
case []any:
var s []string
for _, arg := range args[0].([]interface{}) {
for _, arg := range args[0].([]any) {
s = append(s, arg.(string))
}
return strings.Join(s, glue), nil
@@ -295,36 +295,36 @@ var Builtins = []*ast.Function{
},
Types: types(
strings.Join,
new(func([]interface{}, string) string),
new(func([]interface{}) string),
new(func([]any, string) string),
new(func([]any) string),
new(func([]string, string) string),
new(func([]string) string),
),
},
{
Name: "indexOf",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return strings.Index(args[0].(string), args[1].(string)), nil
},
Types: types(strings.Index),
},
{
Name: "lastIndexOf",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return strings.LastIndex(args[0].(string), args[1].(string)), nil
},
Types: types(strings.LastIndex),
},
{
Name: "hasPrefix",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return strings.HasPrefix(args[0].(string), args[1].(string)), nil
},
Types: types(strings.HasPrefix),
},
{
Name: "hasSuffix",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return strings.HasSuffix(args[0].(string), args[1].(string)), nil
},
Types: types(strings.HasSuffix),
@@ -369,37 +369,37 @@ var Builtins = []*ast.Function{
},
{
Name: "toJSON",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
b, err := json.MarshalIndent(args[0], "", " ")
if err != nil {
return nil, err
}
return string(b), nil
},
Types: types(new(func(interface{}) string)),
Types: types(new(func(any) string)),
},
{
Name: "fromJSON",
Func: func(args ...interface{}) (interface{}, error) {
var v interface{}
Func: func(args ...any) (any, error) {
var v any
err := json.Unmarshal([]byte(args[0].(string)), &v)
if err != nil {
return nil, err
}
return v, nil
},
Types: types(new(func(string) interface{})),
Types: types(new(func(string) any)),
},
{
Name: "toBase64",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return base64.StdEncoding.EncodeToString([]byte(args[0].(string))), nil
},
Types: types(new(func(string) string)),
},
{
Name: "fromBase64",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
b, err := base64.StdEncoding.DecodeString(args[0].(string))
if err != nil {
return nil, err
@@ -410,21 +410,21 @@ var Builtins = []*ast.Function{
},
{
Name: "now",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return time.Now(), nil
},
Types: types(new(func() time.Time)),
},
{
Name: "duration",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
return time.ParseDuration(args[0].(string))
},
Types: types(time.ParseDuration),
},
{
Name: "date",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
date := args[0].(string)
if len(args) == 2 {
layout := args[1].(string)
@@ -469,7 +469,7 @@ var Builtins = []*ast.Function{
},
{
Name: "first",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
defer func() {
if r := recover(); r != nil {
return
@@ -492,7 +492,7 @@ var Builtins = []*ast.Function{
},
{
Name: "last",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
defer func() {
if r := recover(); r != nil {
return
@@ -515,7 +515,7 @@ var Builtins = []*ast.Function{
},
{
Name: "get",
Func: func(args ...interface{}) (out interface{}, err error) {
Func: func(args ...any) (out any, err error) {
defer func() {
if r := recover(); r != nil {
return
@@ -526,7 +526,7 @@ var Builtins = []*ast.Function{
},
{
Name: "keys",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
}
@@ -535,7 +535,7 @@ var Builtins = []*ast.Function{
return nil, fmt.Errorf("cannot get keys from %s", v.Kind())
}
keys := v.MapKeys()
out := make([]interface{}, len(keys))
out := make([]any, len(keys))
for i, key := range keys {
out[i] = key.Interface()
}
@@ -556,7 +556,7 @@ var Builtins = []*ast.Function{
},
{
Name: "values",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
}
@@ -565,7 +565,7 @@ var Builtins = []*ast.Function{
return nil, fmt.Errorf("cannot get values from %s", v.Kind())
}
keys := v.MapKeys()
out := make([]interface{}, len(keys))
out := make([]any, len(keys))
for i, key := range keys {
out[i] = v.MapIndex(key).Interface()
}
@@ -586,7 +586,7 @@ var Builtins = []*ast.Function{
},
{
Name: "sort",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) != 1 && len(args) != 2 {
return nil, fmt.Errorf("invalid number of arguments (expected 1 or 2, got %d)", len(args))
}
@@ -633,7 +633,7 @@ var Builtins = []*ast.Function{
},
{
Name: "sortBy",
Func: func(args ...interface{}) (interface{}, error) {
Func: func(args ...any) (any, error) {
if len(args) != 2 && len(args) != 3 {
return nil, fmt.Errorf("invalid number of arguments (expected 2 or 3, got %d)", len(args))
}
+18 -18
View File
@@ -20,7 +20,7 @@ import (
func TestBuiltin(t *testing.T) {
var tests = []struct {
input string
want interface{}
want any
}{
{`len(1..10)`, 10},
{`len({foo: 1, bar: 2})`, 2},
@@ -63,7 +63,7 @@ func TestBuiltin(t *testing.T) {
{`min(1, 2, 3)`, 1},
{`min(1.5, 2.5, 3.5)`, 1.5},
{`toJSON({foo: 1, bar: 2})`, "{\n \"bar\": 2,\n \"foo\": 1\n}"},
{`fromJSON("[1, 2, 3]")`, []interface{}{1.0, 2.0, 3.0}},
{`fromJSON("[1, 2, 3]")`, []any{1.0, 2.0, 3.0}},
{`toBase64("hello")`, "aGVsbG8="},
{`fromBase64("aGVsbG8=")`, "hello"},
{`now().Format("2006-01-02T15:04Z")`, time.Now().Format("2006-01-02T15:04Z")},
@@ -89,10 +89,10 @@ func TestBuiltin(t *testing.T) {
{`1 in values({foo: 1, bar: 2})`, true},
}
env := map[string]interface{}{
env := map[string]any{
"ArrayOfString": []string{"foo", "bar", "baz"},
"ArrayOfInt": []int{1, 2, 3},
"ArrayOfAny": []interface{}{1, "2", true},
"ArrayOfAny": []any{1, "2", true},
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
@@ -171,7 +171,7 @@ func TestBuiltin_errors(t *testing.T) {
}
func TestBuiltin_types(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"num": 42,
"str": "foo",
"ArrayOfString": []string{"foo", "bar", "baz"},
@@ -223,7 +223,7 @@ func TestBuiltin_memory_limits(t *testing.T) {
func TestBuiltin_disallow_builtins_override(t *testing.T) {
t.Run("via env", func(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"len": func() int { return 42 },
"repeat": func(a string) string {
return a
@@ -235,13 +235,13 @@ func TestBuiltin_disallow_builtins_override(t *testing.T) {
})
t.Run("via expr.Function", func(t *testing.T) {
length := expr.Function("len",
func(params ...interface{}) (interface{}, error) {
func(params ...any) (any, error) {
return 42, nil
},
new(func() int),
)
repeat := expr.Function("repeat",
func(params ...interface{}) (interface{}, error) {
func(params ...any) (any, error) {
return params[0], nil
},
new(func(string) string),
@@ -259,7 +259,7 @@ func TestBuiltin_DisableBuiltin(t *testing.T) {
continue // TODO: allow to disable predicates
}
t.Run(b.Name, func(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
b.Name: func() int { return 42 },
}
program, err := expr.Compile(b.Name+"()", expr.Env(env), expr.DisableBuiltin(b.Name))
@@ -278,7 +278,7 @@ func TestBuiltin_DisableBuiltin(t *testing.T) {
}
t.Run(b.Name, func(t *testing.T) {
fn := expr.Function(b.Name,
func(params ...interface{}) (interface{}, error) {
func(params ...any) (any, error) {
return 42, nil
},
new(func() int),
@@ -302,7 +302,7 @@ func TestBuiltin_DisableAllBuiltins(t *testing.T) {
func TestBuiltin_EnableBuiltin(t *testing.T) {
t.Run("via env", func(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"repeat": func() string { return "repeat" },
}
program, err := expr.Compile(`len(repeat())`, expr.Env(env), expr.DisableAllBuiltins(), expr.EnableBuiltin("len"))
@@ -314,7 +314,7 @@ func TestBuiltin_EnableBuiltin(t *testing.T) {
})
t.Run("via expr.Function", func(t *testing.T) {
fn := expr.Function("repeat",
func(params ...interface{}) (interface{}, error) {
func(params ...any) (any, error) {
return "repeat", nil
},
new(func() string),
@@ -330,10 +330,10 @@ func TestBuiltin_EnableBuiltin(t *testing.T) {
func TestBuiltin_type(t *testing.T) {
type Foo struct{}
var b interface{} = 1
var a interface{} = &b
var b any = 1
var a any = &b
tests := []struct {
obj interface{}
obj any
want string
}{
{nil, "nil"},
@@ -345,7 +345,7 @@ func TestBuiltin_type(t *testing.T) {
{float32(1.0), "float"},
{"string", "string"},
{[]string{"foo", "bar"}, "array"},
{map[string]interface{}{"foo": "bar"}, "map"},
{map[string]any{"foo": "bar"}, "map"},
{func() {}, "func"},
{time.Now(), "time.Time"},
{time.Second, "time.Duration"},
@@ -355,7 +355,7 @@ func TestBuiltin_type(t *testing.T) {
}
for _, test := range tests {
t.Run(test.want, func(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"obj": test.obj,
}
program, err := expr.Compile(`type(obj)`, expr.Env(env))
@@ -369,7 +369,7 @@ func TestBuiltin_type(t *testing.T) {
}
func TestBuiltin_sort(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"ArrayOfString": []string{"foo", "bar", "baz"},
"ArrayOfInt": []int{3, 2, 1},
"ArrayOfFoo": []mock.Foo{{Value: "c"}, {Value: "a"}, {Value: "b"}},
+10 -10
View File
@@ -8,7 +8,7 @@ import (
"github.com/antonmedv/expr/vm/runtime"
)
func Len(x interface{}) interface{} {
func Len(x any) any {
v := reflect.ValueOf(x)
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
@@ -18,7 +18,7 @@ func Len(x interface{}) interface{} {
}
}
func Type(arg interface{}) interface{} {
func Type(arg any) any {
if arg == nil {
return "nil"
}
@@ -60,7 +60,7 @@ func Type(arg interface{}) interface{} {
return "unknown"
}
func Abs(x interface{}) interface{} {
func Abs(x any) any {
switch x.(type) {
case float32:
if x.(float32) < 0 {
@@ -138,7 +138,7 @@ func Abs(x interface{}) interface{} {
panic(fmt.Sprintf("invalid argument for abs (type %T)", x))
}
func Int(x interface{}) interface{} {
func Int(x any) any {
switch x := x.(type) {
case float32:
return int(x)
@@ -175,7 +175,7 @@ func Int(x interface{}) interface{} {
}
}
func Float(x interface{}) interface{} {
func Float(x any) any {
switch x := x.(type) {
case float32:
return float64(x)
@@ -212,12 +212,12 @@ func Float(x interface{}) interface{} {
}
}
func String(arg interface{}) interface{} {
func String(arg any) any {
return fmt.Sprintf("%v", arg)
}
func Max(args ...interface{}) (interface{}, error) {
var max interface{}
func Max(args ...any) (any, error) {
var max any
for _, arg := range args {
if max == nil || runtime.Less(max, arg) {
max = arg
@@ -226,8 +226,8 @@ func Max(args ...interface{}) (interface{}, error) {
return max, nil
}
func Min(args ...interface{}) (interface{}, error) {
var min interface{}
func Min(args ...any) (any, error) {
var min any
for _, arg := range args {
if min == nil || runtime.More(min, arg) {
min = arg
+3 -3
View File
@@ -6,11 +6,11 @@ import (
)
var (
anyType = reflect.TypeOf(new(interface{})).Elem()
anyType = reflect.TypeOf(new(any)).Elem()
integerType = reflect.TypeOf(0)
floatType = reflect.TypeOf(float64(0))
stringType = reflect.TypeOf("")
arrayType = reflect.TypeOf([]interface{}{})
arrayType = reflect.TypeOf([]any{})
)
func kind(t reflect.Type) reflect.Kind {
@@ -20,7 +20,7 @@ func kind(t reflect.Type) reflect.Kind {
return t.Kind()
}
func types(types ...interface{}) []reflect.Type {
func types(types ...any) []reflect.Type {
ts := make([]reflect.Type, len(types))
for i, t := range types {
t := reflect.TypeOf(t)
+1 -1
View File
@@ -130,7 +130,7 @@ func (v *checker) visit(node ast.Node) (reflect.Type, info) {
return t, i
}
func (v *checker) error(node ast.Node, format string, args ...interface{}) (reflect.Type, info) {
func (v *checker) error(node ast.Node, format string, args ...any) (reflect.Type, info) {
if v.err == nil { // show first error
v.err = &file.Error{
Location: node.Location(),
+13 -13
View File
@@ -709,7 +709,7 @@ func TestCheck_AllowUndefinedVariables_OptionalChaining(t *testing.T) {
func TestCheck_OperatorOverload(t *testing.T) {
type Date struct{}
env := map[string]interface{}{
env := map[string]any{
"a": Date{},
"b": Date{},
"add": func(a, b Date) bool {
@@ -738,7 +738,7 @@ func TestCheck_PointerNode(t *testing.T) {
}
func TestCheck_TypeWeights(t *testing.T) {
types := map[string]interface{}{
types := map[string]any{
"Uint": uint(1),
"Uint8": uint8(2),
"Uint16": uint16(3),
@@ -766,8 +766,8 @@ func TestCheck_TypeWeights(t *testing.T) {
}
func TestCheck_CallFastTyped(t *testing.T) {
env := map[string]interface{}{
"fn": func([]interface{}, string) string {
env := map[string]any{
"fn": func([]any, string) string {
return "foo"
},
}
@@ -809,7 +809,7 @@ func TestCheck_CallTyped_excludes_named_functions(t *testing.T) {
}
func TestCheck_works_with_nil_types(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"null": nil,
}
@@ -823,7 +823,7 @@ func TestCheck_works_with_nil_types(t *testing.T) {
func TestCheck_cast_to_expected_works_with_interface(t *testing.T) {
t.Run("float64", func(t *testing.T) {
type Env struct {
Any interface{}
Any any
}
tree, err := parser.Parse("Any")
@@ -838,8 +838,8 @@ func TestCheck_cast_to_expected_works_with_interface(t *testing.T) {
})
t.Run("kind", func(t *testing.T) {
env := map[string]interface{}{
"Any": interface{}("foo"),
env := map[string]any{
"Any": any("foo"),
}
tree, err := parser.Parse("Any")
@@ -867,7 +867,7 @@ func TestCheck_operator_in_works_with_interfaces(t *testing.T) {
func TestCheck_Function_types_are_checked(t *testing.T) {
add := expr.Function(
"add",
func(p ...interface{}) (interface{}, error) {
func(p ...any) (any, error) {
out := 0
for _, each := range p {
out += each.(int)
@@ -914,7 +914,7 @@ func TestCheck_Function_types_are_checked(t *testing.T) {
func TestCheck_Function_without_types(t *testing.T) {
add := expr.Function(
"add",
func(p ...interface{}) (interface{}, error) {
func(p ...any) (any, error) {
out := 0
for _, each := range p {
out += each.(int)
@@ -954,7 +954,7 @@ func TestCheck_dont_panic_on_nil_arguments_for_builtins(t *testing.T) {
}
func TestCheck_do_not_override_params_for_functions(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"foo": func(p string) string {
return "foo"
},
@@ -962,7 +962,7 @@ func TestCheck_do_not_override_params_for_functions(t *testing.T) {
config := conf.New(env)
expr.Function(
"bar",
func(p ...interface{}) (interface{}, error) {
func(p ...any) (any, error) {
return p[0].(string), nil
},
new(func(string) string),
@@ -989,7 +989,7 @@ func TestCheck_do_not_override_params_for_functions(t *testing.T) {
}
func TestCheck_env_keyword(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"num": 42,
"str": "foo",
"name": "str",
+4 -4
View File
@@ -13,12 +13,12 @@ var (
integerType = reflect.TypeOf(0)
floatType = reflect.TypeOf(float64(0))
stringType = reflect.TypeOf("")
arrayType = reflect.TypeOf([]interface{}{})
mapType = reflect.TypeOf(map[string]interface{}{})
anyType = reflect.TypeOf(new(interface{})).Elem()
arrayType = reflect.TypeOf([]any{})
mapType = reflect.TypeOf(map[string]any{})
anyType = reflect.TypeOf(new(any)).Elem()
timeType = reflect.TypeOf(time.Time{})
durationType = reflect.TypeOf(time.Duration(0))
functionType = reflect.TypeOf(new(func(...interface{}) (interface{}, error))).Elem()
functionType = reflect.TypeOf(new(func(...any) (any, error))).Elem()
)
func combined(a, b reflect.Type) reflect.Type {
+6 -6
View File
@@ -26,7 +26,7 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
c := &compiler{
locations: make([]file.Location, 0),
constantsIndex: make(map[interface{}]int),
constantsIndex: make(map[any]int),
functionsIndex: make(map[string]int),
debugInfo: make(map[string]string),
}
@@ -64,10 +64,10 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
type compiler struct {
locations []file.Location
bytecode []Opcode
variables []interface{}
variables []any
scopes []scope
constants []interface{}
constantsIndex map[interface{}]int
constants []any
constantsIndex map[any]int
functions []Function
functionsIndex map[string]int
debugInfo map[string]string
@@ -106,11 +106,11 @@ func (c *compiler) emit(op Opcode, args ...int) int {
return c.emitLocation(loc, op, arg)
}
func (c *compiler) emitPush(value interface{}) int {
func (c *compiler) emitPush(value any) int {
return c.emit(OpPush, c.addConstant(value))
}
func (c *compiler) addConstant(constant interface{}) int {
func (c *compiler) addConstant(constant any) int {
indexable := true
hash := constant
switch reflect.TypeOf(constant).Kind() {
+12 -12
View File
@@ -41,7 +41,7 @@ func TestCompile(t *testing.T) {
{
`65535`,
vm.Program{
Constants: []interface{}{
Constants: []any{
math.MaxUint16,
},
Bytecode: []vm.Opcode{
@@ -53,7 +53,7 @@ func TestCompile(t *testing.T) {
{
`.5`,
vm.Program{
Constants: []interface{}{
Constants: []any{
.5,
},
Bytecode: []vm.Opcode{
@@ -74,7 +74,7 @@ func TestCompile(t *testing.T) {
{
`"string"`,
vm.Program{
Constants: []interface{}{
Constants: []any{
"string",
},
Bytecode: []vm.Opcode{
@@ -86,7 +86,7 @@ func TestCompile(t *testing.T) {
{
`"string" == "string"`,
vm.Program{
Constants: []interface{}{
Constants: []any{
"string",
},
Bytecode: []vm.Opcode{
@@ -100,7 +100,7 @@ func TestCompile(t *testing.T) {
{
`1000000 == 1000000`,
vm.Program{
Constants: []interface{}{
Constants: []any{
int64(1000000),
},
Bytecode: []vm.Opcode{
@@ -114,7 +114,7 @@ func TestCompile(t *testing.T) {
{
`-1`,
vm.Program{
Constants: []interface{}{1},
Constants: []any{1},
Bytecode: []vm.Opcode{
vm.OpPush,
vm.OpNegate,
@@ -155,7 +155,7 @@ func TestCompile(t *testing.T) {
{
`A.B.C.D`,
vm.Program{
Constants: []interface{}{
Constants: []any{
&runtime.Field{
Index: []int{0, 1, 2, 3},
Path: []string{"A", "B", "C", "D"},
@@ -170,7 +170,7 @@ func TestCompile(t *testing.T) {
{
`A?.B.C.D`,
vm.Program{
Constants: []interface{}{
Constants: []any{
&runtime.Field{
Index: []int{0},
Path: []string{"A"},
@@ -191,7 +191,7 @@ func TestCompile(t *testing.T) {
{
`A.B?.C.D`,
vm.Program{
Constants: []interface{}{
Constants: []any{
&runtime.Field{
Index: []int{0, 1},
Path: []string{"A", "B"},
@@ -212,7 +212,7 @@ func TestCompile(t *testing.T) {
{
`A.Map["B"].C.D`,
vm.Program{
Constants: []interface{}{
Constants: []any{
&runtime.Field{
Index: []int{0, 2},
Path: []string{"A", "Map"},
@@ -235,7 +235,7 @@ func TestCompile(t *testing.T) {
{
`A ?? 1`,
vm.Program{
Constants: []interface{}{
Constants: []any{
&runtime.Field{
Index: []int{0},
Path: []string{"A"},
@@ -254,7 +254,7 @@ func TestCompile(t *testing.T) {
{
`A.Ptr + 1`,
vm.Program{
Constants: []interface{}{
Constants: []any{
&runtime.Field{
Index: []int{0, 3},
Path: []string{"A", "Ptr"},
+4 -4
View File
@@ -10,7 +10,7 @@ import (
)
type Config struct {
Env interface{}
Env any
Types TypesTable
MapEnv bool
DefaultType reflect.Type
@@ -43,16 +43,16 @@ func CreateNew() *Config {
}
// New creates new config with environment.
func New(env interface{}) *Config {
func New(env any) *Config {
c := CreateNew()
c.WithEnv(env)
return c
}
func (c *Config) WithEnv(env interface{}) {
func (c *Config) WithEnv(env any) {
var mapEnv bool
var mapValueType reflect.Type
if _, ok := env.(map[string]interface{}); ok {
if _, ok := env.(map[string]any); ok {
mapEnv = true
} else {
if reflect.ValueOf(env).Kind() == reflect.Map {
+1 -1
View File
@@ -20,7 +20,7 @@ type TypesTable map[string]Tag
//
// If map is passed, all items will be treated as variables
// (key as name, value as type).
func CreateTypesTable(i interface{}) TypesTable {
func CreateTypesTable(i any) TypesTable {
if i == nil {
return nil
}
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"github.com/rivo/tview"
)
func StartDebugger(program *Program, env interface{}) {
func StartDebugger(program *Program, env any) {
vm := Debug()
app := tview.NewApplication()
table := tview.NewTable()
+1 -1
View File
@@ -76,7 +76,7 @@ var (
}
)
func CreateDoc(i interface{}) *Context {
func CreateDoc(i any) *Context {
c := &Context{
Variables: make(map[Identifier]*Type),
Types: make(map[TypeName]*Type),
+2 -2
View File
@@ -20,7 +20,7 @@ type Env struct {
Config struct {
MaxSize int32
}
Env map[string]interface{}
Env map[string]any
// NOTE: conflicting type name
TimeWeekday time.Weekday
Weekday Weekday
@@ -201,7 +201,7 @@ func TestCreateDoc_Ambiguous(t *testing.T) {
}
func TestCreateDoc_FromMap(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"Tweets": []*Tweet{},
"Config": struct {
MaxSize int
+4 -4
View File
@@ -22,7 +22,7 @@ type Option func(c *conf.Config)
// as well as all fields of embedded structs and struct itself.
// If map is passed, all items will be treated as variables.
// Methods defined on this type will be available as functions.
func Env(env interface{}) Option {
func Env(env any) Option {
return func(c *conf.Config) {
c.WithEnv(env)
}
@@ -108,7 +108,7 @@ func Patch(visitor ast.Visitor) Option {
}
// Function adds function to list of functions what will be available in expressions.
func Function(name string, fn func(params ...interface{}) (interface{}, error), types ...interface{}) Option {
func Function(name string, fn func(params ...any) (any, error), types ...any) Option {
return func(c *conf.Config) {
ts := make([]reflect.Type, len(types))
for i, t := range types {
@@ -207,12 +207,12 @@ func Compile(input string, ops ...Option) (*vm.Program, error) {
}
// Run evaluates given bytecode program.
func Run(program *vm.Program, env interface{}) (interface{}, error) {
func Run(program *vm.Program, env any) (any, error) {
return vm.Run(program, env)
}
// Eval parses, compiles and runs given input.
func Eval(input string, env interface{}) (interface{}, error) {
func Eval(input string, env any) (any, error) {
if _, ok := env.(Option); ok {
return nil, fmt.Errorf("misused expr.Eval: second argument (env) should be passed without expr.Env")
}
+67 -67
View File
@@ -16,7 +16,7 @@ import (
)
func ExampleEval() {
output, err := expr.Eval("greet + name", map[string]interface{}{
output, err := expr.Eval("greet + name", map[string]any{
"greet": "Hello, ",
"name": "world!",
})
@@ -40,7 +40,7 @@ func ExampleEval_runtime_error() {
}
func ExampleCompile() {
env := map[string]interface{}{
env := map[string]any{
"foo": 1,
"bar": 99,
}
@@ -176,7 +176,7 @@ func ExampleAsBool() {
}
func ExampleAsBool_error() {
env := map[string]interface{}{
env := map[string]any{
"foo": 0,
}
@@ -206,7 +206,7 @@ func ExampleAsInt() {
}
func ExampleAsInt64() {
env := map[string]interface{}{
env := map[string]any{
"rating": 5.5,
}
@@ -306,7 +306,7 @@ func fib(n int) int {
func ExampleConstExpr() {
code := `[fib(5), fib(3+3), fib(dyn)]`
env := map[string]interface{}{
env := map[string]any{
"fib": fib,
"dyn": 0,
}
@@ -339,7 +339,7 @@ func ExampleConstExpr() {
func ExampleAllowUndefinedVariables() {
code := `name == nil ? "Hello, world!" : sprintf("Hello, %v!", name)`
env := map[string]interface{}{
env := map[string]any{
"sprintf": fmt.Sprintf,
}
@@ -470,7 +470,7 @@ func ExamplePatch() {
return
}
env := map[string]interface{}{
env := map[string]any{
"greet": "Hello",
"get": func(a, b string) string {
return a + ", " + b
@@ -488,7 +488,7 @@ func ExamplePatch() {
}
func TestExpr_readme_example(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"greet": "Hello, %v!",
"names": []string{"world", "you"},
"sprintf": fmt.Sprintf,
@@ -562,7 +562,7 @@ func TestExpr(t *testing.T) {
tests := []struct {
code string
want interface{}
want any
}{
{
`1`,
@@ -758,11 +758,11 @@ func TestExpr(t *testing.T) {
},
{
`{foo: 0, bar: 1}`,
map[string]interface{}{"foo": 0, "bar": 1},
map[string]any{"foo": 0, "bar": 1},
},
{
`{foo: 0, bar: 1}`,
map[string]interface{}{"foo": 0, "bar": 1},
map[string]any{"foo": 0, "bar": 1},
},
{
`(true ? 0+1 : 2+3) + (false ? -1 : -2)`,
@@ -770,11 +770,11 @@ func TestExpr(t *testing.T) {
},
{
`filter(1..9, {# > 7})`,
[]interface{}{8, 9},
[]any{8, 9},
},
{
`map(1..3, {# * #})`,
[]interface{}{1, 4, 9},
[]any{1, 4, 9},
},
{
`all(1..3, {# > 0})`,
@@ -910,7 +910,7 @@ func TestExpr(t *testing.T) {
},
{
`map(filter(ArrayOfInt, # >= 3), # + 1)`,
[]interface{}{4, 5, 6},
[]any{4, 5, 6},
},
{
`Time < Time + Duration`,
@@ -954,11 +954,11 @@ func TestExpr(t *testing.T) {
},
{
`map(1..3, let x = #; let y = x * x; y * y)`,
[]interface{}{1, 16, 81},
[]any{1, 16, 81},
},
{
`map(1..2, let x = #; map(2..3, let y = #; x + y))`,
[]interface{}{[]interface{}{3, 4}, []interface{}{4, 5}},
[]any{[]any{3, 4}, []any{4, 5}},
},
{
`len(filter(1..99, # % 7 == 0))`,
@@ -1002,11 +1002,11 @@ func TestExpr(t *testing.T) {
},
{
`map(filter(1..9, # % 2 == 0), # * 2)`,
[]interface{}{4, 8, 12, 16},
[]any{4, 8, 12, 16},
},
{
`map(map(filter(1..9, # % 2 == 0), # * 2), # * 2)`,
[]interface{}{8, 16, 24, 32},
[]any{8, 16, 24, 32},
},
{
`first(map(filter(1..9, # % 2 == 0), # * 2))`,
@@ -1120,7 +1120,7 @@ func TestExpr_error(t *testing.T) {
}
func TestExpr_optional_chaining(t *testing.T) {
env := map[string]interface{}{}
env := map[string]any{}
program, err := expr.Compile("foo?.bar.baz", expr.Env(env), expr.AllowUndefinedVariables())
require.NoError(t, err)
@@ -1130,8 +1130,8 @@ func TestExpr_optional_chaining(t *testing.T) {
}
func TestExpr_optional_chaining_property(t *testing.T) {
env := map[string]interface{}{
"foo": map[string]interface{}{},
env := map[string]any{
"foo": map[string]any{},
}
program, err := expr.Compile("foo.bar?.baz", expr.Env(env))
require.NoError(t, err)
@@ -1142,10 +1142,10 @@ func TestExpr_optional_chaining_property(t *testing.T) {
}
func TestExpr_optional_chaining_nested_chains(t *testing.T) {
env := map[string]interface{}{
"foo": map[string]interface{}{
env := map[string]any{
"foo": map[string]any{
"id": 1,
"bar": []map[string]interface{}{
"bar": []map[string]any{
1: {
"baz": "baz",
},
@@ -1161,13 +1161,13 @@ func TestExpr_optional_chaining_nested_chains(t *testing.T) {
}
func TestExpr_eval_with_env(t *testing.T) {
_, err := expr.Eval("true", expr.Env(map[string]interface{}{}))
_, err := expr.Eval("true", expr.Env(map[string]any{}))
assert.Error(t, err)
assert.Contains(t, err.Error(), "misused")
}
func TestExpr_fetch_from_func(t *testing.T) {
_, err := expr.Eval("foo.Value", map[string]interface{}{
_, err := expr.Eval("foo.Value", map[string]any{
"foo": func() {},
})
assert.Error(t, err)
@@ -1175,7 +1175,7 @@ func TestExpr_fetch_from_func(t *testing.T) {
}
func TestExpr_map_default_values(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"foo": map[string]string{},
"bar": map[string]*string{},
}
@@ -1192,7 +1192,7 @@ func TestExpr_map_default_values(t *testing.T) {
func TestExpr_map_default_values_compile_check(t *testing.T) {
tests := []struct {
env interface{}
env any
input string
}{
{
@@ -1211,8 +1211,8 @@ func TestExpr_map_default_values_compile_check(t *testing.T) {
}
func TestExpr_calls_with_nil(t *testing.T) {
env := map[string]interface{}{
"equals": func(a, b interface{}) interface{} {
env := map[string]any{
"equals": func(a, b any) any {
assert.Nil(t, a, "a is not nil")
assert.Nil(t, b, "b is not nil")
return a == b
@@ -1234,8 +1234,8 @@ func TestExpr_calls_with_nil(t *testing.T) {
}
func TestExpr_call_float_arg_func_with_int(t *testing.T) {
env := map[string]interface{}{
"cnv": func(f float64) interface{} {
env := map[string]any{
"cnv": func(f float64) any {
return f
},
}
@@ -1264,7 +1264,7 @@ func TestExpr_call_float_arg_func_with_int(t *testing.T) {
}
func TestConstExpr_error_panic(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"divide": func(a, b int) int { return a / b },
}
@@ -1284,7 +1284,7 @@ func (e divideError) Error() string {
}
func TestConstExpr_error_as_error(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"divide": func(a, b int) (int, error) {
if b == 0 {
return 0, divideError{"integer divide by zero"}
@@ -1304,7 +1304,7 @@ func TestConstExpr_error_as_error(t *testing.T) {
}
func TestConstExpr_error_wrong_type(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"divide": 0,
}
assert.Panics(t, func() {
@@ -1434,7 +1434,7 @@ func TestIssue_nested_closures(t *testing.T) {
}
func TestIssue138(t *testing.T) {
env := map[string]interface{}{}
env := map[string]any{}
_, err := expr.Compile(`1 / (1 - 1)`, expr.Env(env))
require.NoError(t, err)
@@ -1446,9 +1446,9 @@ func TestIssue138(t *testing.T) {
func TestIssue154(t *testing.T) {
type Data struct {
Array *[2]interface{}
Slice *[]interface{}
Map *map[string]interface{}
Array *[2]any
Slice *[]any
Map *map[string]any
String *string
}
@@ -1460,17 +1460,17 @@ func TestIssue154(t *testing.T) {
i := 10
s := "value"
Array := [2]interface{}{
Array := [2]any{
&b,
&i,
}
Slice := []interface{}{
Slice := []any{
&b,
&i,
}
Map := map[string]interface{}{
Map := map[string]any{
"Bool": &b,
"Int": &i,
}
@@ -1505,7 +1505,7 @@ func TestIssue154(t *testing.T) {
}
func TestIssue270(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"int8": int8(1),
"int16": int16(3),
"int32": int32(5),
@@ -1603,7 +1603,7 @@ func (i Issue346Array) Len() int {
func TestIssue346(t *testing.T) {
code := `Foo[0].Bar`
env := map[string]interface{}{
env := map[string]any{
"Foo": Issue346Array{
{Bar: "bar"},
},
@@ -1618,8 +1618,8 @@ func TestIssue346(t *testing.T) {
func TestCompile_allow_to_use_interface_to_get_an_element_from_map(t *testing.T) {
code := `{"value": "ok"}[vars.key]`
env := map[string]interface{}{
"vars": map[string]interface{}{
env := map[string]any{
"vars": map[string]any{
"key": "value",
},
}
@@ -1648,8 +1648,8 @@ func TestCompile_allow_to_use_interface_to_get_an_element_from_map(t *testing.T)
}
func TestFastCall(t *testing.T) {
env := map[string]interface{}{
"func": func(in interface{}) float64 {
env := map[string]any{
"func": func(in any) float64 {
return 8
},
}
@@ -1664,8 +1664,8 @@ func TestFastCall(t *testing.T) {
}
func TestFastCall_OpCallFastErr(t *testing.T) {
env := map[string]interface{}{
"func": func(...interface{}) (interface{}, error) {
env := map[string]any{
"func": func(...any) (any, error) {
return 8, nil
},
}
@@ -1680,7 +1680,7 @@ func TestFastCall_OpCallFastErr(t *testing.T) {
}
func TestRun_custom_func_returns_an_error_as_second_arg(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"semver": func(value string, cmp string) (bool, error) { return true, nil },
}
@@ -1695,7 +1695,7 @@ func TestRun_custom_func_returns_an_error_as_second_arg(t *testing.T) {
func TestFunction(t *testing.T) {
add := expr.Function(
"add",
func(p ...interface{}) (interface{}, error) {
func(p ...any) (any, error) {
out := 0
for _, each := range p {
out += each.(int)
@@ -1715,8 +1715,8 @@ func TestFunction(t *testing.T) {
// Nil coalescing operator
func TestRun_NilCoalescingOperator(t *testing.T) {
env := map[string]interface{}{
"foo": map[string]interface{}{
env := map[string]any{
"foo": map[string]any{
"bar": "value",
},
}
@@ -1743,16 +1743,16 @@ func TestRun_NilCoalescingOperator(t *testing.T) {
p, err := expr.Compile(`foo?.bar ?? "default"`, expr.Env(env))
assert.NoError(t, err)
out, err := expr.Run(p, map[string]interface{}{})
out, err := expr.Run(p, map[string]any{})
assert.NoError(t, err)
assert.Equal(t, "default", out)
})
}
func TestEval_nil_in_maps(t *testing.T) {
env := map[string]interface{}{
"m": map[interface{}]interface{}{nil: "bar"},
"empty": map[interface{}]interface{}{},
env := map[string]any{
"m": map[any]any{nil: "bar"},
"empty": map[any]any{},
}
t.Run("nil key exists", func(t *testing.T) {
p, err := expr.Compile(`m[nil]`, expr.Env(env))
@@ -1791,7 +1791,7 @@ func TestEval_nil_in_maps(t *testing.T) {
// Test the use of env keyword. Forms env[] and env[”] are valid.
// The enclosed identifier must be in the expression env.
func TestEnv_keyword(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"space test": "ok",
"space_test": "not ok", // Seems to be some underscore substituting happening, check that.
"Section 1-2a": "ok",
@@ -1825,7 +1825,7 @@ func TestEnv_keyword(t *testing.T) {
// No error cases
var tests = []struct {
code string
want interface{}
want any
}{
{"$env['space test']", "ok"},
{"$env['Section 1-2a']", "ok"},
@@ -1872,7 +1872,7 @@ func TestEnv_keyword(t *testing.T) {
// error cases
tests = []struct {
code string
want interface{}
want any
}{
{"env()", "bad"},
}
@@ -1891,7 +1891,7 @@ func TestIssue401(t *testing.T) {
program, err := expr.Compile("(a - b + c) / d", expr.AllowUndefinedVariables())
require.NoError(t, err, "compile error")
output, err := expr.Run(program, map[string]interface{}{
output, err := expr.Run(program, map[string]any{
"a": 1,
"b": 2,
"c": 3,
@@ -1904,12 +1904,12 @@ func TestIssue401(t *testing.T) {
func TestEval_slices_out_of_bound(t *testing.T) {
tests := []struct {
code string
want interface{}
want any
}{
{"[1, 2, 3][:99]", []interface{}{1, 2, 3}},
{"[1, 2, 3][99:]", []interface{}{}},
{"[1, 2, 3][:-99]", []interface{}{}},
{"[1, 2, 3][-99:]", []interface{}{1, 2, 3}},
{"[1, 2, 3][:99]", []any{1, 2, 3}},
{"[1, 2, 3][99:]", []any{}},
{"[1, 2, 3][:-99]", []any{}},
{"[1, 2, 3][-99:]", []any{1, 2, 3}},
}
for _, tt := range tests {
+1 -1
View File
@@ -42,7 +42,7 @@ func (c *constExpr) Visit(node *Node) {
in := make([]reflect.Value, len(call.Arguments))
for i := 0; i < len(call.Arguments); i++ {
arg := call.Arguments[i]
var param interface{}
var param any
switch a := arg.(type) {
case *NilNode:
+1 -1
View File
@@ -285,7 +285,7 @@ func (fold *fold) Visit(node *Node) {
return
}
}
value := make([]interface{}, len(n.Nodes))
value := make([]any, len(n.Nodes))
for i, a := range n.Nodes {
switch b := a.(type) {
case *IntegerNode:
+2 -2
View File
@@ -23,7 +23,7 @@ func TestOptimize_constant_folding(t *testing.T) {
require.NoError(t, err)
expected := &ast.MemberNode{
Node: &ast.ConstantNode{Value: []interface{}{1, 2, 3}},
Node: &ast.ConstantNode{Value: []any{1, 2, 3}},
Property: &ast.IntegerNode{Value: 0},
}
@@ -134,7 +134,7 @@ func TestOptimize_const_expr(t *testing.T) {
tree, err := parser.Parse(`toUpper("hello")`)
require.NoError(t, err)
env := map[string]interface{}{
env := map[string]any{
"toUpper": strings.ToUpper,
}
+1 -1
View File
@@ -150,7 +150,7 @@ func (l *lexer) acceptWord(word string) bool {
return true
}
func (l *lexer) error(format string, args ...interface{}) stateFn {
func (l *lexer) error(format string, args ...any) stateFn {
if l.err == nil { // show first error
l.err = &file.Error{
Location: l.loc,
+2 -2
View File
@@ -81,11 +81,11 @@ func ParseWithConfig(input string, config *conf.Config) (*Tree, error) {
}, nil
}
func (p *parser) error(format string, args ...interface{}) {
func (p *parser) error(format string, args ...any) {
p.errorAt(p.current, format, args...)
}
func (p *parser) errorAt(token Token, format string, args ...interface{}) {
func (p *parser) errorAt(token Token, format string, args ...any) {
if p.err == nil { // show first error
p.err = &file.Error{
Location: token.Location,
+1 -1
View File
@@ -36,7 +36,7 @@ func main() {
}
defer rl.Close()
env := map[string]interface{}{
env := map[string]any{
"ENV": os.Environ(),
}
var program *vm.Program
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"net"
)
func DefaultEnv(ctx context.Context, state *Request) map[string]interface{} {
return map[string]interface{}{
func DefaultEnv(ctx context.Context, state *Request) map[string]any {
return map[string]any{
"incidr": func(ipStr, cidrStr string) (bool, error) {
ip := net.ParseIP(ipStr)
if ip == nil {
+16 -16
View File
@@ -5,22 +5,22 @@ import (
)
type Event struct {
Type int `yaml:"Type,omitempty" json:"Type,omitempty"`
ExpectMode int `yaml:"ExpectMode,omitempty" json:"ExpectMode,omitempty"`
Whitelisted bool `yaml:"Whitelisted,omitempty" json:"Whitelisted,omitempty"`
WhitelistReason string `yaml:"WhitelistReason,omitempty" json:"whitelist_reason,omitempty"`
Stage string `yaml:"Stage,omitempty" json:"Stage,omitempty"`
Line Line `yaml:"Line,omitempty" json:"Line,omitempty"`
Parsed map[string]string `yaml:"Parsed,omitempty" json:"Parsed,omitempty"`
Enriched map[string]string `yaml:"Enriched,omitempty" json:"Enriched,omitempty"`
Unmarshaled map[string]interface{} `yaml:"Unmarshaled,omitempty" json:"Unmarshaled,omitempty"`
Overflow RuntimeAlert `yaml:"Overflow,omitempty" json:"Alert,omitempty"`
Time time.Time `yaml:"Time,omitempty" json:"Time,omitempty"`
StrTime string `yaml:"StrTime,omitempty" json:"StrTime,omitempty"`
StrTimeFormat string `yaml:"StrTimeFormat,omitempty" json:"StrTimeFormat,omitempty"`
MarshaledTime string `yaml:"MarshaledTime,omitempty" json:"MarshaledTime,omitempty"`
Process bool `yaml:"Process,omitempty" json:"Process,omitempty"`
Meta map[string]string `yaml:"Meta,omitempty" json:"Meta,omitempty"`
Type int `yaml:"Type,omitempty" json:"Type,omitempty"`
ExpectMode int `yaml:"ExpectMode,omitempty" json:"ExpectMode,omitempty"`
Whitelisted bool `yaml:"Whitelisted,omitempty" json:"Whitelisted,omitempty"`
WhitelistReason string `yaml:"WhitelistReason,omitempty" json:"whitelist_reason,omitempty"`
Stage string `yaml:"Stage,omitempty" json:"Stage,omitempty"`
Line Line `yaml:"Line,omitempty" json:"Line,omitempty"`
Parsed map[string]string `yaml:"Parsed,omitempty" json:"Parsed,omitempty"`
Enriched map[string]string `yaml:"Enriched,omitempty" json:"Enriched,omitempty"`
Unmarshaled map[string]any `yaml:"Unmarshaled,omitempty" json:"Unmarshaled,omitempty"`
Overflow RuntimeAlert `yaml:"Overflow,omitempty" json:"Alert,omitempty"`
Time time.Time `yaml:"Time,omitempty" json:"Time,omitempty"`
StrTime string `yaml:"StrTime,omitempty" json:"StrTime,omitempty"`
StrTimeFormat string `yaml:"StrTimeFormat,omitempty" json:"StrTimeFormat,omitempty"`
MarshaledTime string `yaml:"MarshaledTime,omitempty" json:"MarshaledTime,omitempty"`
Process bool `yaml:"Process,omitempty" json:"Process,omitempty"`
Meta map[string]string `yaml:"Meta,omitempty" json:"Meta,omitempty"`
}
func (e *Event) GetType() string {
+2 -2
View File
@@ -18,7 +18,7 @@ func TestCrowdsec(t *testing.T) {
err = json.Unmarshal(b, &examples)
require.NoError(t, err)
env := map[string]interface{}{
env := map[string]any{
"evt": &crowdsec.Event{},
}
@@ -30,7 +30,7 @@ func TestCrowdsec(t *testing.T) {
opt,
expr.Function(
fn.Name,
func(params ...interface{}) (interface{}, error) {
func(params ...any) (any, error) {
return nil, nil
},
fn.Func...,
+67 -67
View File
@@ -6,347 +6,347 @@ import (
var CustomFunctions = []struct {
Name string
Func []interface{}
Func []any
}{
{
Name: "Distance",
Func: []interface{}{
Func: []any{
new(func(string, string, string, string) (float64, error)),
},
},
{
Name: "GetFromStash",
Func: []interface{}{
Func: []any{
new(func(string, string) (string, error)),
},
},
{
Name: "Atof",
Func: []interface{}{
Func: []any{
new(func(string) float64),
},
},
{
Name: "JsonExtract",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "JsonExtractUnescape",
Func: []interface{}{
Func: []any{
new(func(string, ...string) string),
},
},
{
Name: "JsonExtractLib",
Func: []interface{}{
Func: []any{
new(func(string, ...string) string),
},
},
{
Name: "JsonExtractSlice",
Func: []interface{}{
new(func(string, string) []interface{}),
Func: []any{
new(func(string, string) []any),
},
},
{
Name: "JsonExtractObject",
Func: []interface{}{
new(func(string, string) map[string]interface{}),
Func: []any{
new(func(string, string) map[string]any),
},
},
{
Name: "ToJsonString",
Func: []interface{}{
new(func(interface{}) string),
Func: []any{
new(func(any) string),
},
},
{
Name: "File",
Func: []interface{}{
Func: []any{
new(func(string) []string),
},
},
{
Name: "RegexpInFile",
Func: []interface{}{
Func: []any{
new(func(string, string) bool),
},
},
{
Name: "Upper",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "Lower",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "IpInRange",
Func: []interface{}{
Func: []any{
new(func(string, string) bool),
},
},
{
Name: "TimeNow",
Func: []interface{}{
Func: []any{
new(func() string),
},
},
{
Name: "ParseUri",
Func: []interface{}{
Func: []any{
new(func(string) map[string][]string),
},
},
{
Name: "PathUnescape",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "QueryUnescape",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "PathEscape",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "QueryEscape",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "XMLGetAttributeValue",
Func: []interface{}{
Func: []any{
new(func(string, string, string) string),
},
},
{
Name: "XMLGetNodeValue",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "IpToRange",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "IsIPV6",
Func: []interface{}{
Func: []any{
new(func(string) bool),
},
},
{
Name: "IsIPV4",
Func: []interface{}{
Func: []any{
new(func(string) bool),
},
},
{
Name: "IsIP",
Func: []interface{}{
Func: []any{
new(func(string) bool),
},
},
{
Name: "LookupHost",
Func: []interface{}{
Func: []any{
new(func(string) []string),
},
},
{
Name: "GetDecisionsCount",
Func: []interface{}{
Func: []any{
new(func(string) int),
},
},
{
Name: "GetDecisionsSinceCount",
Func: []interface{}{
Func: []any{
new(func(string, string) int),
},
},
{
Name: "Sprintf",
Func: []interface{}{
new(func(string, ...interface{}) string),
Func: []any{
new(func(string, ...any) string),
},
},
{
Name: "ParseUnix",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "SetInStash",
Func: []interface{}{
Func: []any{
new(func(string, string, string, *time.Duration) error),
},
},
{
Name: "Fields",
Func: []interface{}{
Func: []any{
new(func(string) []string),
},
},
{
Name: "Index",
Func: []interface{}{
Func: []any{
new(func(string, string) int),
},
},
{
Name: "IndexAny",
Func: []interface{}{
Func: []any{
new(func(string, string) int),
},
},
{
Name: "Join",
Func: []interface{}{
Func: []any{
new(func([]string, string) string),
},
},
{
Name: "Split",
Func: []interface{}{
Func: []any{
new(func(string, string) []string),
},
},
{
Name: "SplitAfter",
Func: []interface{}{
Func: []any{
new(func(string, string) []string),
},
},
{
Name: "SplitAfterN",
Func: []interface{}{
Func: []any{
new(func(string, string, int) []string),
},
},
{
Name: "SplitN",
Func: []interface{}{
Func: []any{
new(func(string, string, int) []string),
},
},
{
Name: "Replace",
Func: []interface{}{
Func: []any{
new(func(string, string, string, int) string),
},
},
{
Name: "ReplaceAll",
Func: []interface{}{
Func: []any{
new(func(string, string, string) string),
},
},
{
Name: "Trim",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "TrimLeft",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "TrimRight",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "TrimSpace",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "TrimPrefix",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "TrimSuffix",
Func: []interface{}{
Func: []any{
new(func(string, string) string),
},
},
{
Name: "Get",
Func: []interface{}{
Func: []any{
new(func([]string, int) string),
},
},
{
Name: "ToString",
Func: []interface{}{
new(func(interface{}) string),
Func: []any{
new(func(any) string),
},
},
{
Name: "Match",
Func: []interface{}{
Func: []any{
new(func(string, string) bool),
},
},
{
Name: "KeyExists",
Func: []interface{}{
new(func(string, map[string]interface{}) bool),
Func: []any{
new(func(string, map[string]any) bool),
},
},
{
Name: "LogInfo",
Func: []interface{}{
new(func(string, ...interface{}) bool),
Func: []any{
new(func(string, ...any) bool),
},
},
{
Name: "B64Decode",
Func: []interface{}{
Func: []any{
new(func(string) string),
},
},
{
Name: "UnmarshalJSON",
Func: []interface{}{
new(func(string, map[string]interface{}, string) error),
Func: []any{
new(func(string, map[string]any, string) error),
},
},
{
Name: "ParseKV",
Func: []interface{}{
new(func(string, map[string]interface{}, string) error),
Func: []any{
new(func(string, map[string]any, string) error),
},
},
{
Name: "Hostname",
Func: []interface{}{
Func: []any{
new(func() (string, error)),
},
},
+12 -12
View File
@@ -10,9 +10,9 @@ import (
func TestDeref_binary(t *testing.T) {
i := 1
env := map[string]interface{}{
env := map[string]any{
"i": &i,
"obj": map[string]interface{}{
"obj": map[string]any{
"i": &i,
},
}
@@ -45,9 +45,9 @@ func TestDeref_binary(t *testing.T) {
func TestDeref_unary(t *testing.T) {
i := 1
ok := true
env := map[string]interface{}{
env := map[string]any{
"i": &i,
"obj": map[string]interface{}{
"obj": map[string]any{
"ok": &ok,
},
}
@@ -62,9 +62,9 @@ func TestDeref_unary(t *testing.T) {
func TestDeref_eval(t *testing.T) {
i := 1
env := map[string]interface{}{
env := map[string]any{
"i": &i,
"obj": map[string]interface{}{
"obj": map[string]any{
"i": &i,
},
}
@@ -77,7 +77,7 @@ func TestDeref_emptyCtx(t *testing.T) {
program, err := expr.Compile(`ctx`)
require.NoError(t, err)
output, err := expr.Run(program, map[string]interface{}{
output, err := expr.Run(program, map[string]any{
"ctx": context.Background(),
})
require.NoError(t, err)
@@ -85,7 +85,7 @@ func TestDeref_emptyCtx(t *testing.T) {
}
func TestDeref_emptyCtx_Eval(t *testing.T) {
output, err := expr.Eval(`ctx`, map[string]interface{}{
output, err := expr.Eval(`ctx`, map[string]any{
"ctx": context.Background(),
})
require.NoError(t, err)
@@ -96,7 +96,7 @@ func TestDeref_context_WithValue(t *testing.T) {
program, err := expr.Compile(`ctxWithValue`)
require.NoError(t, err)
output, err := expr.Run(program, map[string]interface{}{
output, err := expr.Run(program, map[string]any{
"ctxWithValue": context.WithValue(context.Background(), "value", "test"),
})
require.NoError(t, err)
@@ -104,7 +104,7 @@ func TestDeref_context_WithValue(t *testing.T) {
}
func TestDeref_method_on_int_pointer(t *testing.T) {
output, err := expr.Eval(`foo.Bar()`, map[string]interface{}{
output, err := expr.Eval(`foo.Bar()`, map[string]any{
"foo": new(foo),
})
require.NoError(t, err)
@@ -122,7 +122,7 @@ func TestDeref_multiple_pointers(t *testing.T) {
b := &a
c := &b
t.Run("returned as is", func(t *testing.T) {
output, err := expr.Eval(`c`, map[string]interface{}{
output, err := expr.Eval(`c`, map[string]any{
"c": c,
})
require.NoError(t, err)
@@ -130,7 +130,7 @@ func TestDeref_multiple_pointers(t *testing.T) {
require.IsType(t, (**int)(nil), output)
})
t.Run("+ works", func(t *testing.T) {
output, err := expr.Eval(`c+2`, map[string]interface{}{
output, err := expr.Eval(`c+2`, map[string]any{
"c": c,
})
require.NoError(t, err)
@@ -35,7 +35,7 @@ func TestInterfaceMethod(t *testing.T) {
require.True(t, BarImpl{}.Aba())
require.True(t, BarImpl{}.Bar() == 42)
env := map[string]interface{}{
env := map[string]any{
"var": FooImpl{},
}
p, err := expr.Compile(`var.Foo().Bar()`, expr.Env(env))
+8 -8
View File
@@ -12,7 +12,7 @@ import (
type Env struct {
Embed
Ambiguous string
Any interface{}
Any any
Bool bool
Float float64
Int64 int64
@@ -30,24 +30,24 @@ type Env struct {
StringPtr *string
Foo Foo
Abstract Abstract
ArrayOfAny []interface{}
ArrayOfAny []any
ArrayOfInt []int
ArrayOfString []string
ArrayOfFoo []*Foo
MapOfFoo map[string]Foo
MapOfAny map[string]interface{}
MapOfAny map[string]any
MapIntAny map[int]string
FuncParam func(_ bool, _ int, _ string) bool
FuncParamAny func(_ interface{}) bool
FuncParamAny func(_ any) bool
FuncTooManyReturns func() (int, int, error)
FuncNamed MyFunc
NilAny interface{}
NilAny any
NilInt *int
NilFn func()
NilStruct *Foo
NilSlice []interface{}
NilSlice []any
Variadic func(_ int, _ ...int) bool
Fast func(...interface{}) interface{}
Fast func(...any) any
Time time.Time
TimePlusDay time.Time
Duration time.Duration
@@ -172,6 +172,6 @@ type MapStringIntEnv map[string]int
type Is struct{}
func (Is) Nil(a interface{}) bool {
func (Is) Nil(a any) bool {
return a == nil
}
+3 -3
View File
@@ -9,13 +9,13 @@ import (
)
func TestPipes(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"sprintf": fmt.Sprintf,
}
tests := []struct {
input string
want interface{}
want any
}{
{
`-1 | abs()`,
@@ -53,5 +53,5 @@ func TestPipes_map_filter(t *testing.T) {
out, err := expr.Run(program, nil)
require.NoError(t, err)
require.Equal(t, []interface{}{2, 4, 6, 8, 10}, out)
require.Equal(t, []any{2, 4, 6, 8, 10}, out)
}
+5 -5
View File
@@ -19,10 +19,10 @@ func TestTime(t *testing.T) {
testDuration := time.Duration(1)
tests := []struct {
a interface{}
b interface{}
a any
b any
op string
want interface{}
want any
wantErr bool
}{
{a: testTime, b: testTime, op: "<", wantErr: false, want: false},
@@ -72,7 +72,7 @@ func TestTime(t *testing.T) {
for _, tt := range tests {
t.Run(fmt.Sprintf("time helper test `%T %s %T`", tt.a, tt.op, tt.b), func(t *testing.T) {
input := fmt.Sprintf("a %v b", tt.op)
env := map[string]interface{}{
env := map[string]any{
"a": tt.a,
"b": tt.b,
}
@@ -103,7 +103,7 @@ func TestTime(t *testing.T) {
}
func TestTime_duration(t *testing.T) {
env := map[string]interface{}{
env := map[string]any{
"foo": time.Date(2000, time.Month(1), 1, 0, 0, 0, 0, time.UTC),
}
program, err := expr.Compile(`now() - duration("1h") < now() && foo + duration("24h") < now()`, expr.Env(env))
+19 -19
View File
@@ -11,21 +11,21 @@ import (
)
// Keep sorted.
var types = []interface{}{
var types = []any{
nil,
new(func() Duration),
new(func() Month),
new(func() Time),
new(func() Weekday),
new(func() []byte),
new(func() []interface{}),
new(func() []any),
new(func() bool),
new(func() byte),
new(func() float64),
new(func() int),
new(func() int64),
new(func() interface{}),
new(func() map[string]interface{}),
new(func() any),
new(func() map[string]any),
new(func() rune),
new(func() string),
new(func() uint),
@@ -34,7 +34,7 @@ var types = []interface{}{
new(func(Duration) Time),
new(func(Time) Duration),
new(func(Time) bool),
new(func([]interface{}, string) string),
new(func([]any, string) string),
new(func([]string, string) string),
new(func(bool) bool),
new(func(bool) float64),
@@ -61,20 +61,20 @@ var types = []interface{}{
new(func(string, rune) int),
new(func(string, string) bool),
new(func(string, string) string),
new(func(interface{}) bool),
new(func(interface{}) float64),
new(func(interface{}) int),
new(func(interface{}) string),
new(func(interface{}) interface{}),
new(func(interface{}) []interface{}),
new(func(interface{}) map[string]interface{}),
new(func([]interface{}) interface{}),
new(func([]interface{}) []interface{}),
new(func([]interface{}) map[string]interface{}),
new(func(interface{}, interface{}) bool),
new(func(interface{}, interface{}) string),
new(func(interface{}, interface{}) interface{}),
new(func(interface{}, interface{}) []interface{}),
new(func(any) bool),
new(func(any) float64),
new(func(any) int),
new(func(any) string),
new(func(any) any),
new(func(any) []any),
new(func(any) map[string]any),
new(func([]any) any),
new(func([]any) []any),
new(func([]any) map[string]any),
new(func(any, any) bool),
new(func(any, any) string),
new(func(any, any) any),
new(func(any, any) []any),
}
func main() {
+42 -42
View File
@@ -7,20 +7,20 @@ import (
"time"
)
var FuncTypes = []interface{}{
var FuncTypes = []any{
1: new(func() time.Duration),
2: new(func() time.Month),
3: new(func() time.Time),
4: new(func() time.Weekday),
5: new(func() []uint8),
6: new(func() []interface{}),
6: new(func() []any),
7: new(func() bool),
8: new(func() uint8),
9: new(func() float64),
10: new(func() int),
11: new(func() int64),
12: new(func() interface{}),
13: new(func() map[string]interface{}),
12: new(func() any),
13: new(func() map[string]any),
14: new(func() int32),
15: new(func() string),
16: new(func() uint),
@@ -29,7 +29,7 @@ var FuncTypes = []interface{}{
19: new(func(time.Duration) time.Time),
20: new(func(time.Time) time.Duration),
21: new(func(time.Time) bool),
22: new(func([]interface{}, string) string),
22: new(func([]any, string) string),
23: new(func([]string, string) string),
24: new(func(bool) bool),
25: new(func(bool) float64),
@@ -56,23 +56,23 @@ var FuncTypes = []interface{}{
46: new(func(string, int32) int),
47: new(func(string, string) bool),
48: new(func(string, string) string),
49: new(func(interface{}) bool),
50: new(func(interface{}) float64),
51: new(func(interface{}) int),
52: new(func(interface{}) string),
53: new(func(interface{}) interface{}),
54: new(func(interface{}) []interface{}),
55: new(func(interface{}) map[string]interface{}),
56: new(func([]interface{}) interface{}),
57: new(func([]interface{}) []interface{}),
58: new(func([]interface{}) map[string]interface{}),
59: new(func(interface{}, interface{}) bool),
60: new(func(interface{}, interface{}) string),
61: new(func(interface{}, interface{}) interface{}),
62: new(func(interface{}, interface{}) []interface{}),
49: new(func(any) bool),
50: new(func(any) float64),
51: new(func(any) int),
52: new(func(any) string),
53: new(func(any) any),
54: new(func(any) []any),
55: new(func(any) map[string]any),
56: new(func([]any) any),
57: new(func([]any) []any),
58: new(func([]any) map[string]any),
59: new(func(any, any) bool),
60: new(func(any, any) string),
61: new(func(any, any) any),
62: new(func(any, any) []any),
}
func (vm *VM) call(fn interface{}, kind int) interface{} {
func (vm *VM) call(fn any, kind int) any {
switch kind {
case 1:
return fn.(func() time.Duration)()
@@ -85,7 +85,7 @@ func (vm *VM) call(fn interface{}, kind int) interface{} {
case 5:
return fn.(func() []uint8)()
case 6:
return fn.(func() []interface{})()
return fn.(func() []any)()
case 7:
return fn.(func() bool)()
case 8:
@@ -97,9 +97,9 @@ func (vm *VM) call(fn interface{}, kind int) interface{} {
case 11:
return fn.(func() int64)()
case 12:
return fn.(func() interface{})()
return fn.(func() any)()
case 13:
return fn.(func() map[string]interface{})()
return fn.(func() map[string]any)()
case 14:
return fn.(func() int32)()
case 15:
@@ -122,8 +122,8 @@ func (vm *VM) call(fn interface{}, kind int) interface{} {
return fn.(func(time.Time) bool)(arg1)
case 22:
arg2 := vm.pop().(string)
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}, string) string)(arg1, arg2)
arg1 := vm.pop().([]any)
return fn.(func([]any, string) string)(arg1, arg2)
case 23:
arg2 := vm.pop().(string)
arg1 := vm.pop().([]string)
@@ -212,50 +212,50 @@ func (vm *VM) call(fn interface{}, kind int) interface{} {
return fn.(func(string, string) string)(arg1, arg2)
case 49:
arg1 := vm.pop()
return fn.(func(interface{}) bool)(arg1)
return fn.(func(any) bool)(arg1)
case 50:
arg1 := vm.pop()
return fn.(func(interface{}) float64)(arg1)
return fn.(func(any) float64)(arg1)
case 51:
arg1 := vm.pop()
return fn.(func(interface{}) int)(arg1)
return fn.(func(any) int)(arg1)
case 52:
arg1 := vm.pop()
return fn.(func(interface{}) string)(arg1)
return fn.(func(any) string)(arg1)
case 53:
arg1 := vm.pop()
return fn.(func(interface{}) interface{})(arg1)
return fn.(func(any) any)(arg1)
case 54:
arg1 := vm.pop()
return fn.(func(interface{}) []interface{})(arg1)
return fn.(func(any) []any)(arg1)
case 55:
arg1 := vm.pop()
return fn.(func(interface{}) map[string]interface{})(arg1)
return fn.(func(any) map[string]any)(arg1)
case 56:
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}) interface{})(arg1)
arg1 := vm.pop().([]any)
return fn.(func([]any) any)(arg1)
case 57:
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}) []interface{})(arg1)
arg1 := vm.pop().([]any)
return fn.(func([]any) []any)(arg1)
case 58:
arg1 := vm.pop().([]interface{})
return fn.(func([]interface{}) map[string]interface{})(arg1)
arg1 := vm.pop().([]any)
return fn.(func([]any) map[string]any)(arg1)
case 59:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) bool)(arg1, arg2)
return fn.(func(any, any) bool)(arg1, arg2)
case 60:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) string)(arg1, arg2)
return fn.(func(any, any) string)(arg1, arg2)
case 61:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) interface{})(arg1, arg2)
return fn.(func(any, any) any)(arg1, arg2)
case 62:
arg2 := vm.pop()
arg1 := vm.pop()
return fn.(func(interface{}, interface{}) []interface{})(arg1, arg2)
return fn.(func(any, any) []any)(arg1, arg2)
}
panic(fmt.Sprintf("unknown function kind (%v)", kind))
+3 -3
View File
@@ -19,8 +19,8 @@ type Program struct {
Node ast.Node
Source *file.Source
Locations []file.Location
Variables []interface{}
Constants []interface{}
Variables []any
Constants []any
Bytecode []Opcode
Arguments []int
Functions []Function
@@ -59,7 +59,7 @@ func (program *Program) Opcodes(w io.Writer) {
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, program.DebugInfo[fmt.Sprintf("%s_%d", prefix, arg)])
}
constant := func(label string) {
var c interface{}
var c any
if arg < len(program.Constants) {
c = program.Constants[arg]
} else {
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func TestProgram_Disassemble(t *testing.T) {
for op := vm.OpPush; op < vm.OpEnd; op++ {
program := vm.Program{
Constants: []interface{}{1, 2},
Constants: []any{1, 2},
Bytecode: []vm.Opcode{op},
Arguments: []int{1},
}
+10 -10
View File
@@ -8,7 +8,7 @@ import (
"time"
)
func Equal(a, b interface{}) bool {
func Equal(a, b any) bool {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -351,7 +351,7 @@ func Equal(a, b interface{}) bool {
return reflect.DeepEqual(a, b)
}
func Less(a, b interface{}) bool {
func Less(a, b any) bool {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -691,7 +691,7 @@ func Less(a, b interface{}) bool {
panic(fmt.Sprintf("invalid operation: %T < %T", a, b))
}
func More(a, b interface{}) bool {
func More(a, b any) bool {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -1031,7 +1031,7 @@ func More(a, b interface{}) bool {
panic(fmt.Sprintf("invalid operation: %T > %T", a, b))
}
func LessOrEqual(a, b interface{}) bool {
func LessOrEqual(a, b any) bool {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -1371,7 +1371,7 @@ func LessOrEqual(a, b interface{}) bool {
panic(fmt.Sprintf("invalid operation: %T <= %T", a, b))
}
func MoreOrEqual(a, b interface{}) bool {
func MoreOrEqual(a, b any) bool {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -1711,7 +1711,7 @@ func MoreOrEqual(a, b interface{}) bool {
panic(fmt.Sprintf("invalid operation: %T >= %T", a, b))
}
func Add(a, b interface{}) interface{} {
func Add(a, b any) any {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -2056,7 +2056,7 @@ func Add(a, b interface{}) interface{} {
panic(fmt.Sprintf("invalid operation: %T + %T", a, b))
}
func Subtract(a, b interface{}) interface{} {
func Subtract(a, b any) any {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -2393,7 +2393,7 @@ func Subtract(a, b interface{}) interface{} {
panic(fmt.Sprintf("invalid operation: %T - %T", a, b))
}
func Multiply(a, b interface{}) interface{} {
func Multiply(a, b any) any {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -2723,7 +2723,7 @@ func Multiply(a, b interface{}) interface{} {
panic(fmt.Sprintf("invalid operation: %T * %T", a, b))
}
func Divide(a, b interface{}) float64 {
func Divide(a, b any) float64 {
switch x := a.(type) {
case uint:
switch y := b.(type) {
@@ -3053,7 +3053,7 @@ func Divide(a, b interface{}) float64 {
panic(fmt.Sprintf("invalid operation: %T / %T", a, b))
}
func Modulo(a, b interface{}) int {
func Modulo(a, b any) int {
switch x := a.(type) {
case uint:
switch y := b.(type) {
+1 -1
View File
@@ -46,7 +46,7 @@ var types = []string{
func cases(op string, noFloat bool) string {
var out string
echo := func(s string, xs ...interface{}) {
echo := func(s string, xs ...any) {
out += fmt.Sprintf(s, xs...) + "\n"
}
for _, a := range types {
+13 -13
View File
@@ -8,7 +8,7 @@ import (
"reflect"
)
func Fetch(from, i interface{}) interface{} {
func Fetch(from, i any) any {
v := reflect.ValueOf(from)
kind := v.Kind()
if kind == reflect.Invalid {
@@ -81,7 +81,7 @@ type Field struct {
Path []string
}
func FetchField(from interface{}, field *Field) interface{} {
func FetchField(from any, field *Field) any {
v := reflect.ValueOf(from)
kind := v.Kind()
if kind != reflect.Invalid {
@@ -125,7 +125,7 @@ type Method struct {
Name string
}
func FetchMethod(from interface{}, method *Method) interface{} {
func FetchMethod(from any, method *Method) any {
v := reflect.ValueOf(from)
kind := v.Kind()
if kind != reflect.Invalid {
@@ -138,7 +138,7 @@ func FetchMethod(from interface{}, method *Method) interface{} {
panic(fmt.Sprintf("cannot fetch %v from %T", method.Name, from))
}
func Deref(i interface{}) interface{} {
func Deref(i any) any {
if i == nil {
return nil
}
@@ -173,7 +173,7 @@ loop:
panic(fmt.Sprintf("cannot dereference %v", i))
}
func Slice(array, from, to interface{}) interface{} {
func Slice(array, from, to any) any {
v := reflect.ValueOf(array)
switch v.Kind() {
@@ -213,7 +213,7 @@ func Slice(array, from, to interface{}) interface{} {
panic(fmt.Sprintf("cannot slice %v", from))
}
func In(needle interface{}, array interface{}) bool {
func In(needle any, array any) bool {
if array == nil {
return false
}
@@ -270,7 +270,7 @@ func In(needle interface{}, array interface{}) bool {
panic(fmt.Sprintf(`operator "in" not defined on %T`, array))
}
func Len(a interface{}) int {
func Len(a any) int {
v := reflect.ValueOf(a)
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
@@ -280,7 +280,7 @@ func Len(a interface{}) int {
}
}
func Negate(i interface{}) interface{} {
func Negate(i any) any {
switch v := i.(type) {
case float32:
return -v
@@ -311,7 +311,7 @@ func Negate(i interface{}) interface{} {
}
}
func Exponent(a, b interface{}) float64 {
func Exponent(a, b any) float64 {
return math.Pow(ToFloat64(a), ToFloat64(b))
}
@@ -327,7 +327,7 @@ func MakeRange(min, max int) []int {
return rng
}
func ToInt(a interface{}) int {
func ToInt(a any) int {
switch x := a.(type) {
case float32:
return int(x)
@@ -358,7 +358,7 @@ func ToInt(a interface{}) int {
}
}
func ToInt64(a interface{}) int64 {
func ToInt64(a any) int64 {
switch x := a.(type) {
case float32:
return int64(x)
@@ -389,7 +389,7 @@ func ToInt64(a interface{}) int64 {
}
}
func ToFloat64(a interface{}) float64 {
func ToFloat64(a any) float64 {
switch x := a.(type) {
case float32:
return float64(x)
@@ -420,7 +420,7 @@ func ToFloat64(a interface{}) float64 {
}
}
func IsNil(v interface{}) bool {
func IsNil(v any) bool {
if v == nil {
return true
}
+15 -15
View File
@@ -16,9 +16,9 @@ import (
var MemoryBudget int = 1e6
var errorType = reflect.TypeOf((*error)(nil)).Elem()
type Function = func(params ...interface{}) (interface{}, error)
type Function = func(params ...any) (any, error)
func Run(program *Program, env interface{}) (interface{}, error) {
func Run(program *Program, env any) (any, error) {
if program == nil {
return nil, fmt.Errorf("program is nil")
}
@@ -28,7 +28,7 @@ func Run(program *Program, env interface{}) (interface{}, error) {
}
type VM struct {
stack []interface{}
stack []any
ip int
scopes []*Scope
debug bool
@@ -55,7 +55,7 @@ func Debug() *VM {
return vm
}
func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error) {
func (vm *VM) Run(program *Program, env any) (_ any, err error) {
defer func() {
if r := recover(); r != nil {
f := &file.Error{
@@ -70,7 +70,7 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
}()
if vm.stack == nil {
vm.stack = make([]interface{}, 0, 2)
vm.stack = make([]any, 0, 2)
} else {
vm.stack = vm.stack[0:0]
}
@@ -119,7 +119,7 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
vm.push(runtime.FetchField(env, program.Constants[arg].(*runtime.Field)))
case OpLoadFast:
vm.push(env.(map[string]interface{})[program.Constants[arg].(string)])
vm.push(env.(map[string]any)[program.Constants[arg].(string)])
case OpLoadMethod:
vm.push(runtime.FetchMethod(env, program.Constants[arg].(*runtime.Method)))
@@ -367,7 +367,7 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
case OpCallN:
fn := vm.pop().(Function)
size := arg
in := make([]interface{}, size)
in := make([]any, size)
for i := int(size) - 1; i >= 0; i-- {
in[i] = vm.pop()
}
@@ -378,9 +378,9 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
vm.push(out)
case OpCallFast:
fn := vm.pop().(func(...interface{}) interface{})
fn := vm.pop().(func(...any) any)
size := arg
in := make([]interface{}, size)
in := make([]any, size)
for i := int(size) - 1; i >= 0; i-- {
in[i] = vm.pop()
}
@@ -394,7 +394,7 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
case OpArray:
size := vm.pop().(int)
array := make([]interface{}, size)
array := make([]any, size)
for i := size - 1; i >= 0; i-- {
array[i] = vm.pop()
}
@@ -406,7 +406,7 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
case OpMap:
size := vm.pop().(int)
m := make(map[string]interface{})
m := make(map[string]any)
for i := size - 1; i >= 0; i-- {
value := vm.pop()
key := vm.pop()
@@ -513,21 +513,21 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
return nil, nil
}
func (vm *VM) push(value interface{}) {
func (vm *VM) push(value any) {
vm.stack = append(vm.stack, value)
}
func (vm *VM) current() interface{} {
func (vm *VM) current() any {
return vm.stack[len(vm.stack)-1]
}
func (vm *VM) pop() interface{} {
func (vm *VM) pop() any {
value := vm.stack[len(vm.stack)-1]
vm.stack = vm.stack[:len(vm.stack)-1]
return value
}
func (vm *VM) Stack() []interface{} {
func (vm *VM) Stack() []any {
return vm.stack
}
+6 -6
View File
@@ -78,7 +78,7 @@ func TestRun_Cast(t *testing.T) {
}
func TestRun_Helpers(t *testing.T) {
values := []interface{}{
values := []any{
uint(1),
uint8(1),
uint16(1),
@@ -110,7 +110,7 @@ func TestRun_Helpers(t *testing.T) {
}
input := fmt.Sprintf("a %v b", op)
env := map[string]interface{}{
env := map[string]any{
"a": a,
"b": b,
}
@@ -145,7 +145,7 @@ func (ErrorEnv) WillError(param string) (bool, error) {
return true, nil
}
func (ErrorEnv) FastError(...interface{}) interface{} {
func (ErrorEnv) FastError(...any) any {
return true
}
@@ -185,9 +185,9 @@ func TestRun_FastMethods(t *testing.T) {
tree, err := parser.Parse(input)
require.NoError(t, err)
env := map[string]interface{}{
"hello": func(...interface{}) interface{} { return "hello " },
"world": func(...interface{}) interface{} { return "world" },
env := map[string]any{
"hello": func(...any) any { return "hello " },
"world": func(...any) any { return "world" },
}
funcConf := conf.New(env)
_, err = checker.Check(tree, funcConf)