mirror of
https://github.com/robertkrimen/otto
synced 2025-10-26 20:28:49 +08:00
Add ability to call struct methods
This fixes #60 This is incompatible with go 1.0.3
This commit is contained in:
parent
661a61c5a0
commit
07737f86b9
|
|
@ -14,6 +14,34 @@ type testStruct struct {
|
||||||
Jkl interface{}
|
Jkl interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *testStruct) FuncPointerReciever() string {
|
||||||
|
return "abc"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t testStruct) FuncNoArgsNoRet() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t testStruct) FuncNoArgs() string {
|
||||||
|
return "abc"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t testStruct) FuncNoArgsMultRet() (string, error) {
|
||||||
|
return "def", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t testStruct) FuncOneArgs(a string) string {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t testStruct) FuncMultArgs(a, b string) string {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t testStruct) FuncVarArgs(as ...string) int {
|
||||||
|
return len(as)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReflect(t *testing.T) {
|
func TestReflect(t *testing.T) {
|
||||||
Terst(t)
|
Terst(t)
|
||||||
|
|
||||||
|
|
@ -35,6 +63,10 @@ func Test_reflectStruct(t *testing.T) {
|
||||||
abc := &testStruct{}
|
abc := &testStruct{}
|
||||||
failSet("abc", abc)
|
failSet("abc", abc)
|
||||||
|
|
||||||
|
test(`
|
||||||
|
abc.FuncPointerReciever();
|
||||||
|
`, "abc")
|
||||||
|
|
||||||
test(`
|
test(`
|
||||||
[ abc.Abc, abc.Ghi ];
|
[ abc.Abc, abc.Ghi ];
|
||||||
`, "false,")
|
`, "false,")
|
||||||
|
|
@ -78,6 +110,26 @@ func Test_reflectStruct(t *testing.T) {
|
||||||
[ abc.Def, abc.abc ];
|
[ abc.Def, abc.abc ];
|
||||||
`, "451,")
|
`, "451,")
|
||||||
Is(abc.Def, 451)
|
Is(abc.Def, 451)
|
||||||
|
|
||||||
|
test(`
|
||||||
|
abc.FuncNoArgsNoRet();
|
||||||
|
`, "undefined")
|
||||||
|
test(`
|
||||||
|
abc.FuncNoArgs();
|
||||||
|
`, "abc")
|
||||||
|
test(`
|
||||||
|
abc.FuncOneArgs("abc");
|
||||||
|
`, "abc")
|
||||||
|
test(`
|
||||||
|
abc.FuncMultArgs("abc", "def");
|
||||||
|
`, "abcdef")
|
||||||
|
test(`
|
||||||
|
abc.FuncVarArgs("abc", "def", "ghi");
|
||||||
|
`, "3")
|
||||||
|
|
||||||
|
test(`raise:
|
||||||
|
abc.FuncNoArgsMultRet();
|
||||||
|
`, "TypeError")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
15
runtime.go
15
runtime.go
|
|
@ -322,6 +322,21 @@ func (self *_runtime) toValue(value interface{}) Value {
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
return toValue_object(self.newGoArray(value))
|
return toValue_object(self.newGoArray(value))
|
||||||
}
|
}
|
||||||
|
case reflect.Func:
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
|
||||||
|
retvals := value.Call(args)
|
||||||
|
if len(retvals) > 1 {
|
||||||
|
panic(newTypeError())
|
||||||
|
} else if len(retvals) == 1 {
|
||||||
|
return toValue(retvals[0].Interface())
|
||||||
|
}
|
||||||
|
return UndefinedValue()
|
||||||
|
}))
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return toValue_object(self.newGoStructObject(value))
|
return toValue_object(self.newGoStructObject(value))
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,25 @@ func _newGoStructObject(value reflect.Value) *_goStructObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self _goStructObject) getValue(name string) reflect.Value {
|
func (self _goStructObject) getValue(name string) reflect.Value {
|
||||||
return reflect.Indirect(self.value).FieldByName(name)
|
if field := reflect.Indirect(self.value).FieldByName(name); (field != reflect.Value{}) {
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
|
||||||
|
if method := self.value.MethodByName(name); (method != reflect.Value{}) {
|
||||||
|
return method
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.Value{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self _goStructObject) field(name string) (reflect.StructField, bool) {
|
func (self _goStructObject) field(name string) (reflect.StructField, bool) {
|
||||||
return reflect.Indirect(self.value).Type().FieldByName(name)
|
return reflect.Indirect(self.value).Type().FieldByName(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self _goStructObject) method(name string) (reflect.Method, bool) {
|
||||||
|
return reflect.Indirect(self.value).Type().MethodByName(name)
|
||||||
|
}
|
||||||
|
|
||||||
func (self _goStructObject) setValue(name string, value Value) bool {
|
func (self _goStructObject) setValue(name string, value Value) bool {
|
||||||
field, exists := self.field(name)
|
field, exists := self.field(name)
|
||||||
if !exists {
|
if !exists {
|
||||||
|
|
@ -60,10 +72,17 @@ func goStructGetOwnProperty(self *_object, name string) *_property {
|
||||||
|
|
||||||
func goStructEnumerate(self *_object, all bool, each func(string) bool) {
|
func goStructEnumerate(self *_object, all bool, each func(string) bool) {
|
||||||
object := self.value.(*_goStructObject)
|
object := self.value.(*_goStructObject)
|
||||||
count := object.value.NumField()
|
|
||||||
type_ := object.value.Type()
|
// Enumerate fields
|
||||||
for index := 0; index < count; index++ {
|
for index := 0; index < reflect.Indirect(object.value).NumField(); index++ {
|
||||||
if !each(type_.Field(index).Name) {
|
if !each(reflect.Indirect(object.value).Type().Field(index).Name) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enumerate methods
|
||||||
|
for index := 0; index < object.value.NumMethod(); index++ {
|
||||||
|
if !each(object.value.Type().Method(index).Name) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user