1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-12 20:27:30 +08:00

Merge pull request #6 from stevenh/array-types

Export arrays to common type if possible
This commit is contained in:
Steven Hartland 2015-02-19 11:08:22 +00:00
commit 9cb5e6bc30
2 changed files with 64 additions and 3 deletions

View File

@ -523,6 +523,46 @@ func Test_reflectArray(t *testing.T) {
is(abc[len(abc)-1], true)
}
// no common type
{
test(`
abc = [1, 2.2, "str"];
abc;
`, "1,2.2,str")
val, err := vm.Get("abc")
is(err, nil)
abc, err := val.Export()
is(err, nil)
is(abc, []interface{}{int64(1), 2.2, "str"})
}
// common type int
{
test(`
abc = [1, 2, 3];
abc;
`, "1,2,3")
val, err := vm.Get("abc")
is(err, nil)
abc, err := val.Export()
is(err, nil)
is(abc, []int64{1, 2, 3})
}
// common type string
{
test(`
abc = ["str1", "str2", "str3"];
abc;
`, "str1,str2,str3")
val, err := vm.Get("abc")
is(err, nil)
abc, err := val.Export()
is(err, nil)
is(abc, []string{"str1", "str2", "str3"})
}
})
}

View File

@ -680,15 +680,36 @@ func (self Value) export() interface{} {
result := make([]interface{}, 0)
lengthValue := object.get("length")
length := lengthValue.value.(uint32)
kind := reflect.Invalid
state := 0
var t reflect.Type
for index := uint32(0); index < length; index += 1 {
name := strconv.FormatInt(int64(index), 10)
if !object.hasProperty(name) {
continue
}
value := object.get(name)
result = append(result, value.export())
value := object.get(name).export()
t = reflect.TypeOf(value)
if state == 0 {
kind = t.Kind()
state = 1
} else if state == 1 && kind != t.Kind() {
state = 2
}
result = append(result, value)
}
return result
if state != 1 || kind == reflect.Interface {
// No common type
return result
}
// Convert to the common type
val := reflect.MakeSlice(reflect.SliceOf(t), len(result), len(result))
for i, v := range result {
val.Index(i).Set(reflect.ValueOf(v))
}
return val.Interface()
} else {
result := make(map[string]interface{})
// TODO Should we export everything? Or just what is enumerable?