diff --git a/env/env.go b/env/env.go index d8faa70f..4852dab3 100644 --- a/env/env.go +++ b/env/env.go @@ -154,6 +154,28 @@ func (e *Env) GetEnvFromPath(path []string) (*Env, error) { return e, nil } +// Values returns all values in Env. +func (e *Env) Values() map[string]reflect.Value { + e.rwMutex.RLock() + values := make(map[string]reflect.Value, len(e.values)) + for symbol, value := range e.values { + values[symbol] = value + } + e.rwMutex.RUnlock() + return values +} + +// Types returns all Types in Env. +func (e *Env) Types() map[string]reflect.Type { + e.rwMutex.RLock() + types := make(map[string]reflect.Type, len(e.types)) + for symbol, aType := range e.types { + types[symbol] = aType + } + e.rwMutex.RUnlock() + return types +} + // Copy the Env for current scope func (e *Env) Copy() *Env { e.rwMutex.RLock() diff --git a/env/env_test.go b/env/env_test.go index bd7a682d..b23f0dd5 100644 --- a/env/env_test.go +++ b/env/env_test.go @@ -286,6 +286,48 @@ func TestGetEnvFromPath(t *testing.T) { } } +func TestEnv_Values(t *testing.T) { + t.Parallel() + + env := NewEnv() + err := env.Define("test", "test str") + if err != nil { + t.Fatal("Define error:", err) + } + + values := env.Values() + v, ok := values["test"] + if !ok { + t.Fatal("test is not exist") + } + if v.Interface().(string) != "test str" { + t.Fatal("invalid test value") + } +} + +func TestEnv_Types(t *testing.T) { + t.Parallel() + + type Foo struct { + A string + } + + env := NewEnv() + err := env.DefineType("test", Foo{}) + if err != nil { + t.Fatal("Define error:", err) + } + + types := env.Types() + typ, ok := types["test"] + if !ok { + t.Fatal("test is not exist") + } + if typ.String() != "env.Foo" { + t.Fatal("invalid test type") + } +} + func TestCopy(t *testing.T) { t.Parallel() diff --git a/vm/vm.go b/vm/vm.go index 949a53b6..e3f417ce 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -409,26 +409,10 @@ func makeValue(t reflect.Type) (reflect.Value, error) { if err != nil { return nilValue, err } - ptrV.Elem().Set(v) return ptrV, nil case reflect.Slice: return reflect.MakeSlice(t, 0, 0), nil - case reflect.Struct: - structV := reflect.New(t).Elem() - for i := 0; i < structV.NumField(); i++ { - if structV.Field(i).Kind() == reflect.Ptr { - continue - } - v, err := makeValue(structV.Field(i).Type()) - if err != nil { - return nilValue, err - } - if structV.Field(i).CanSet() { - structV.Field(i).Set(v) - } - } - return structV, nil } return reflect.New(t).Elem(), nil } diff --git a/vm/vmContainers_test.go b/vm/vmContainers_test.go index 23d40814..ace02a19 100644 --- a/vm/vmContainers_test.go +++ b/vm/vmContainers_test.go @@ -1892,7 +1892,7 @@ make(struct { A *int64 B []int64 C map[string]int64 - }{A: (*int64)(nil), B: []int64{}, C: map[string]int64{}}}, + }{A: (*int64)(nil), B: nil, C: nil}}, // make struct within structs {Script: ` @@ -1920,7 +1920,7 @@ make(struct { }{AA: 0, AB: 0}, B: struct { BA []int64 BB map[string]int64 - }{BA: []int64{}, BB: map[string]int64{}}}}, + }{BA: nil, BB: nil}}}, } runTests(t, tests, nil, &Options{Debug: true}) } diff --git a/vm/vm_test.go b/vm/vm_test.go index a5dd9bcf..a8c872b5 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -567,9 +567,9 @@ func TestMake(t *testing.T) { // struct {Script: `make(struct { A int64 })`, RunOutput: struct{ A int64 }{}}, {Script: `make(struct { A *int64 })`, RunOutput: struct{ A *int64 }{}}, - {Script: `make(struct { A []int64 })`, RunOutput: struct{ A []int64 }{A: []int64{}}}, - {Script: `make(struct { A map[string]int64 })`, RunOutput: struct{ A map[string]int64 }{A: map[string]int64{}}}, - {Script: `a = make(struct { A chan int64 }); go func(){ a.A <- 1 }(); <- a.A`, RunOutput: int64(1)}, + {Script: `make(struct { A []int64 })`, RunOutput: struct{ A []int64 }{A: nil}}, + {Script: `make(struct { A map[string]int64 })`, RunOutput: struct{ A map[string]int64 }{A: nil}}, + {Script: `make(struct { A chan int64 })`, RunOutput: struct{ A chan int64 }{A: nil}}, } runTests(t, tests, nil, &Options{Debug: true}) }