Browse Source

Support dereferencing in ExportTo(). Closes #300

Dmitry Panov 4 years ago
parent
commit
705acef95b
2 changed files with 37 additions and 6 deletions
  1. 16 6
      runtime.go
  2. 21 0
      runtime_test.go

+ 16 - 6
runtime.go

@@ -1804,13 +1804,23 @@ func (r *Runtime) toReflectValue(v Value, dst reflect.Value, ctx *objectExportCt
 			dst.Set(reflect.Zero(typ))
 			dst.Set(reflect.Zero(typ))
 			return nil
 			return nil
 		}
 		}
-		if et.AssignableTo(typ) {
-			dst.Set(reflect.ValueOf(exportValue(v, ctx)))
-			return nil
-		} else if et.ConvertibleTo(typ) {
-			dst.Set(reflect.ValueOf(exportValue(v, ctx)).Convert(typ))
-			return nil
+
+		for i := 0; ; i++ {
+			if et.ConvertibleTo(typ) {
+				ev := reflect.ValueOf(exportValue(v, ctx))
+				for ; i > 0; i-- {
+					ev = ev.Elem()
+				}
+				dst.Set(ev.Convert(typ))
+				return nil
+			}
+			if et.Kind() == reflect.Ptr {
+				et = et.Elem()
+			} else {
+				break
+			}
 		}
 		}
+
 		if typ == typeTime {
 		if typ == typeTime {
 			if obj, ok := v.(*Object); ok {
 			if obj, ok := v.(*Object); ok {
 				if d, ok := obj.self.(*dateObject); ok {
 				if d, ok := obj.self.(*dateObject); ok {

+ 21 - 0
runtime_test.go

@@ -650,6 +650,27 @@ func TestRuntime_ExportToStructAnonymous(t *testing.T) {
 
 
 }
 }
 
 
+func TestRuntime_ExportToStructFromPtr(t *testing.T) {
+	vm := New()
+	v := vm.ToValue(&testGoReflectMethod_O{
+		field: "5",
+		Test:  "12",
+	})
+
+	var o testGoReflectMethod_O
+	err := vm.ExportTo(v, &o)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if o.Test != "12" {
+		t.Fatalf("Unexpected value: '%s'", o.Test)
+	}
+	if o.field != "5" {
+		t.Fatalf("Unexpected value for field: '%s'", o.field)
+	}
+}
+
 func TestRuntime_ExportToStructWithPtrValues(t *testing.T) {
 func TestRuntime_ExportToStructWithPtrValues(t *testing.T) {
 	type BaseTestStruct struct {
 	type BaseTestStruct struct {
 		A int64
 		A int64