Răsfoiți Sursa

Handling Symbol properties in native Proxy handler. Fixes #149.

Dmitry Panov 5 ani în urmă
părinte
comite
c61e8285ad
2 a modificat fișierele cu 44 adăugiri și 9 ștergeri
  1. 20 4
      builtin_proxy.go
  2. 24 5
      builtin_proxy_test.go

+ 20 - 4
builtin_proxy.go

@@ -72,7 +72,10 @@ func (r *Runtime) proxyproto_nativehandler_getOwnPropertyDescriptor(native func(
 		handler.self._putProp("getOwnPropertyDescriptor", r.newNativeFunc(func(call FunctionCall) Value {
 			if len(call.Arguments) >= 2 {
 				if t, ok := call.Argument(0).(*Object); ok {
-					if p, ok := call.Argument(1).(valueString); ok {
+					switch p := call.Argument(1).(type) {
+					case *valueSymbol:
+						return _undefined
+					default:
 						desc := native(t, p.String())
 						return desc.toValue(r)
 					}
@@ -105,7 +108,10 @@ func (r *Runtime) proxyproto_nativehandler_gen_obj_string_bool(name proxyTrap, n
 		handler.self._putProp(unistring.String(name), r.newNativeFunc(func(call FunctionCall) Value {
 			if len(call.Arguments) >= 2 {
 				if t, ok := call.Argument(0).(*Object); ok {
-					if p, ok := call.Argument(1).(valueString); ok {
+					switch p := call.Argument(1).(type) {
+					case *valueSymbol:
+						return valueFalse
+					default:
 						o := native(t, p.String())
 						return r.ToValue(o)
 					}
@@ -121,8 +127,11 @@ func (r *Runtime) proxyproto_nativehandler_get(native func(*Object, string, *Obj
 		handler.self._putProp("get", r.newNativeFunc(func(call FunctionCall) Value {
 			if len(call.Arguments) >= 3 {
 				if t, ok := call.Argument(0).(*Object); ok {
-					if p, ok := call.Argument(1).(valueString); ok {
-						if r, ok := call.Argument(2).(*Object); ok {
+					if r, ok := call.Argument(2).(*Object); ok {
+						switch p := call.Argument(1).(type) {
+						case *valueSymbol:
+							return _undefined
+						default:
 							return native(t, p.String(), r)
 						}
 					}
@@ -191,6 +200,13 @@ func (r *Runtime) proxyproto_nativehandler_construct(native func(*Object, []Valu
 	}
 }
 
+// ProxyTrapConfig provides a simplified Go-friendly API for implementing Proxy traps.
+// Note that the Proxy may not have Symbol properties when using this as a handler because property keys are
+// passed as strings.
+// get() and getOwnPropertyDescriptor() for Symbol properties will always return undefined;
+// has() and deleteProperty() for Symbol properties will always return false;
+// set() and defineProperty() for Symbol properties will throw a TypeError.
+// If you need Symbol properties implement the handler in JavaScript.
 type ProxyTrapConfig struct {
 	// A trap for Object.getPrototypeOf, Reflect.getPrototypeOf, __proto__, Object.prototype.isPrototypeOf, instanceof
 	GetPrototypeOf func(target *Object) (prototype *Object)

+ 24 - 5
builtin_proxy_test.go

@@ -512,10 +512,6 @@ func TestProxy_proxy_get_json_stringify(t *testing.T) {
 			return obj[prop];
 		}
 	});
-	/*Object.defineProperty(proxy, "foo", {
-		value: "test123",
-		configurable: true,
-	});*/
 	var res = JSON.stringify(proxy);
 	assert.sameValue(res, '{"foo":"321tset"}');
 	assert.sameValue(_prop, "foo");
@@ -525,7 +521,7 @@ func TestProxy_proxy_get_json_stringify(t *testing.T) {
 	testScript1(TESTLIB+SCRIPT, _undefined, t)
 }
 
-func TestProxy_native_proxy_get_json_stringify(t *testing.T) {
+func TestProxy_native_proxy_get(t *testing.T) {
 	vm := New()
 	propValue := vm.ToValue("321tset")
 	obj := vm.NewObject()
@@ -558,6 +554,29 @@ func TestProxy_native_proxy_get_json_stringify(t *testing.T) {
 	if !res.SameAs(asciiString(`{"foo":"321tset"}`)) {
 		t.Fatalf("res: %v", res)
 	}
+	res, err = vm.RunString(`proxy[Symbol.toPrimitive]`)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !IsUndefined(res) {
+		t.Fatalf("res: %v", res)
+	}
+
+	res, err = vm.RunString(`proxy.hasOwnProperty(Symbol.toPrimitive)`)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !res.SameAs(valueFalse) {
+		t.Fatalf("res: %v", res)
+	}
+
+	res, err = vm.RunString(`proxy.toString()`)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !res.SameAs(asciiString(`[object Object]`)) {
+		t.Fatalf("res: %v", res)
+	}
 }
 
 func TestProxy_target_set_prop(t *testing.T) {