diff --git a/bug_test.go b/bug_test.go index 0ee484d..ac4d020 100644 --- a/bug_test.go +++ b/bug_test.go @@ -231,12 +231,12 @@ func Test_issue24(t *testing.T) { } { - vm.Set("abc", testStruct{Abc: true, Ghi: "Nothing happens."}) + vm.Set("abc", _abcStruct{Abc: true, Ghi: "Nothing happens."}) value, err := vm.Get("abc") is(err, nil) export, _ := value.Export() { - value, valid := export.(testStruct) + value, valid := export.(_abcStruct) is(valid, true) is(value.Abc, true) @@ -245,12 +245,12 @@ func Test_issue24(t *testing.T) { } { - vm.Set("abc", &testStruct{Abc: true, Ghi: "Nothing happens."}) + vm.Set("abc", &_abcStruct{Abc: true, Ghi: "Nothing happens."}) value, err := vm.Get("abc") is(err, nil) export, _ := value.Export() { - value, valid := export.(*testStruct) + value, valid := export.(*_abcStruct) is(valid, true) is(value.Abc, true) diff --git a/reflect_test.go b/reflect_test.go index f91b38c..7f75730 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -6,39 +6,50 @@ import ( "testing" ) -type testStruct struct { +type _abcStruct struct { Abc bool Def int Ghi string Jkl interface{} } -func (t *testStruct) FuncPointerReciever() string { +func (abc *_abcStruct) FuncPointer() string { return "abc" } -func (t testStruct) FuncNoArgsNoRet() { +func (abc _abcStruct) Func() { return } -func (t testStruct) FuncNoArgs() string { +func (abc _abcStruct) FuncReturn1() string { return "abc" } -func (t testStruct) FuncNoArgsMultRet() (string, error) { +func (abc _abcStruct) FuncReturn2() (string, error) { return "def", nil } -func (t testStruct) FuncOneArgs(a string) string { +func (abc _abcStruct) Func1Return1(a string) string { return a } -func (t testStruct) FuncMultArgs(a, b string) string { - return a + b +func (abc _abcStruct) Func2Return1(x, y string) string { + return x + y } -func (t testStruct) FuncVarArgs(as ...string) int { - return len(as) +func (abc _abcStruct) FuncEllipsis(xyz ...string) int { + return len(xyz) +} + +func (abc _abcStruct) FuncReturnStruct() _mnoStruct { + return _mnoStruct{} +} + +type _mnoStruct struct { +} + +func (mno _mnoStruct) Func() string { + return "mno" } func TestReflect(t *testing.T) { @@ -55,15 +66,11 @@ func Test_reflectStruct(t *testing.T) { tt(t, func() { test, vm := test() - // testStruct + // _abcStruct { - abc := &testStruct{} + abc := &_abcStruct{} vm.Set("abc", abc) - test(` - abc.FuncPointerReciever(); - `, "abc") - test(` [ abc.Abc, abc.Ghi ]; `, "false,") @@ -75,7 +82,7 @@ func Test_reflectStruct(t *testing.T) { [ abc.Abc, abc.Ghi ]; `, "true,Nothing happens.") - *abc = testStruct{} + *abc = _abcStruct{} test(` [ abc.Abc, abc.Ghi ]; @@ -109,24 +116,40 @@ func Test_reflectStruct(t *testing.T) { is(abc.Def, 451) test(` - abc.FuncNoArgsNoRet(); + abc.FuncPointer(); + `, "abc") + + test(` + abc.Func(); `, "undefined") + test(` - abc.FuncNoArgs(); + abc.FuncReturn1(); `, "abc") + test(` - abc.FuncOneArgs("abc"); + abc.Func1Return1("abc"); `, "abc") + test(` - abc.FuncMultArgs("abc", "def"); + abc.Func2Return1("abc", "def"); `, "abcdef") + test(` - abc.FuncVarArgs("abc", "def", "ghi"); + abc.FuncEllipsis("abc", "def", "ghi"); `, 3) test(`raise: - abc.FuncNoArgsMultRet(); + abc.FuncReturn2(); `, "TypeError") + + test(` + abc.FuncReturnStruct(); + `, "[object Object]") + + test(` + abc.FuncReturnStruct().Func(); + `, "mno") } }) } @@ -387,7 +410,7 @@ func Test_reflectMapInterface(t *testing.T) { "jkl": "jkl", } vm.Set("abc", abc) - vm.Set("mno", &testStruct{}) + vm.Set("mno", &_abcStruct{}) test(` abc.xyz = "pqr"; @@ -402,7 +425,7 @@ func Test_reflectMapInterface(t *testing.T) { is(abc["xyz"], "pqr") is(abc["ghi"], "[object Object]") is(abc["jkl"], float64(3.14159)) - mno, valid := abc["mno"].(*testStruct) + mno, valid := abc["mno"].(*_abcStruct) is(valid, true) is(mno.Abc, true) is(mno.Ghi, "Something happens.") diff --git a/runtime.go b/runtime.go index 76e51d7..510b6f8 100644 --- a/runtime.go +++ b/runtime.go @@ -267,7 +267,8 @@ func (self *_runtime) toValue(value interface{}) Value { return toValue_object(self.newNativeFunction("", value)) case Object, *Object, _object, *_object: // Nothing happens. - // FIXME + // FIXME We should really figure out what can come here. + // This catch-all is ugly. default: { value := reflect.ValueOf(value) @@ -280,19 +281,21 @@ func (self *_runtime) toValue(value interface{}) Value { return toValue_object(self.newGoArray(value)) } case reflect.Func: + // TODO Maybe cache this? return toValue_object(self.newNativeFunction("", func(call FunctionCall) Value { - args := make([]reflect.Value, len(call.ArgumentList)) - for i, a := range call.ArgumentList { - args[i] = reflect.ValueOf(a.export()) + in := make([]reflect.Value, len(call.ArgumentList)) + for i, value := range call.ArgumentList { + in[i] = reflect.ValueOf(value.export()) } - retvals := value.Call(args) - if len(retvals) > 1 { - panic(newTypeError()) - } else if len(retvals) == 1 { - return toValue(retvals[0].Interface()) + out := value.Call(in) + if len(out) == 1 { + return self.toValue(out[0].Interface()) + } else if len(out) == 0 { + return UndefinedValue() } - return UndefinedValue() + + panic(newTypeError()) })) case reflect.Struct: return toValue_object(self.newGoStructObject(value))