Piotr Caban : jscript: Added Object.hasOwnProperty implementation.

Alexandre Julliard julliard at winehq.org
Fri Sep 2 13:13:37 CDT 2011


Module: wine
Branch: master
Commit: 71b58e56c24c06db589605cd53fc37aca5e2d747
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=71b58e56c24c06db589605cd53fc37aca5e2d747

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri Sep  2 12:24:12 2011 +0200

jscript: Added Object.hasOwnProperty implementation.

---

 dlls/jscript/dispex.c     |   14 ++++++++++++++
 dlls/jscript/jscript.h    |    1 +
 dlls/jscript/object.c     |   43 +++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/tests/api.js |   11 +++++++++++
 dlls/jscript/tests/run.c  |   30 ++++++++++++++++++++++++++++++
 5 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 653857c..3a0eabf 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1132,3 +1132,17 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
 
     return delete_prop(prop);
 }
+
+VARIANT_BOOL jsdisp_is_own_prop(jsdisp_t *obj, BSTR name)
+{
+    dispex_prop_t *prop;
+    HRESULT hres;
+
+    hres = find_prop_name(obj, name, &prop);
+    if(FAILED(hres))
+        return VARIANT_FALSE;
+    else if(!prop)
+        return VARIANT_FALSE;
+
+    return prop->type==PROP_VARIANT ? VARIANT_TRUE : VARIANT_FALSE;
+}
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index c0b60ae..ee03e90 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -217,6 +217,7 @@ HRESULT jsdisp_propget_name(jsdisp_t*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvi
 HRESULT jsdisp_get_idx(jsdisp_t*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*) DECLSPEC_HIDDEN;
 HRESULT jsdisp_get_id(jsdisp_t*,const WCHAR*,DWORD,DISPID*) DECLSPEC_HIDDEN;
 HRESULT jsdisp_delete_idx(jsdisp_t*,DWORD) DECLSPEC_HIDDEN;
+VARIANT_BOOL jsdisp_is_own_prop(jsdisp_t *obj, BSTR name) DECLSPEC_HIDDEN;
 
 HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
         jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
index 9f2e4d5..c1137c1 100644
--- a/dlls/jscript/object.c
+++ b/dlls/jscript/object.c
@@ -111,8 +111,47 @@ static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
 static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    BSTR name;
+    BOOL result;
+    DISPID id;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!arg_cnt(dp)) {
+        if(retv) {
+            V_VT(retv) = VT_BOOL;
+            V_BOOL(retv) = VARIANT_FALSE;
+        }
+
+        return S_OK;
+    }
+
+    hres = to_string(ctx, get_arg(dp, 0), ei, &name);
+    if(FAILED(hres))
+        return hres;
+
+    if(is_jsdisp(jsthis)) {
+        result = jsdisp_is_own_prop(jsthis->u.jsdisp, name);
+        if(retv) {
+            V_VT(retv) = VT_BOOL;
+            V_BOOL(retv) = result;
+        }
+
+        return S_OK;
+    } else if(is_dispex(jsthis)) {
+        hres = IDispatchEx_GetDispID(jsthis->u.dispex, name,
+                make_grfdex(ctx, fdexNameCaseSensitive), &id);
+    } else {
+        hres = IDispatch_GetIDsOfNames(jsthis->u.disp, &IID_NULL,
+                &name, 1, ctx->lcid, &id);
+    }
+
+    if(retv) {
+        V_VT(retv) = VT_BOOL;
+        V_BOOL(retv) = SUCCEEDED(hres) ? VARIANT_TRUE : VARIANT_FALSE;
+    }
+    return S_OK;
 }
 
 static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index c5f0c4f..09c3360 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -1864,11 +1864,22 @@ ok(err.message === 4, "err.message = " + err.message);
 ok(!("number" in Error), "number is in Error");
 
 tmp = new Object();
+ok(tmp.hasOwnProperty("toString") === false, "toString property should be inherited");
 tmp.toString = function() { return "test"; };
+ok(tmp.hasOwnProperty("toString") === true, "toString own property should exist");
+ok(tmp.hasOwnProperty("nonExisting") === false, "nonExisting property should not exist");
 
 tmp = Error.prototype.toString.call(tmp);
 ok(tmp === "[object Error]", "Error.prototype.toString.call(tmp) = " + tmp);
 
+tmp = function() { return 0; };
+tmp[0] = true;
+ok(tmp.hasOwnProperty("toString") === false, "toString property should be inherited");
+ok(tmp.hasOwnProperty("0") === true, "hasOwnProperty(0) returned false");
+ok(tmp.hasOwnProperty() === false, "hasOwnProperty() returned true");
+
+ok(Object.prototype.hasOwnProperty.call(testObj) === false, "hasOwnProperty without name returned true");
+
 if(invokeVersion >= 2) {
     obj = new Object();
     obj.name = "test";
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index 88c69ef..fbbff96 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -64,6 +64,8 @@ DEFINE_EXPECT(global_propput_i);
 DEFINE_EXPECT(global_success_d);
 DEFINE_EXPECT(global_success_i);
 DEFINE_EXPECT(global_notexists_d);
+DEFINE_EXPECT(puredisp_prop_d);
+DEFINE_EXPECT(puredisp_noprop_d);
 DEFINE_EXPECT(testobj_delete);
 DEFINE_EXPECT(testobj_value);
 DEFINE_EXPECT(testobj_prop_d);
@@ -173,6 +175,18 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
                                                 LPOLESTR *rgszNames, UINT cNames,
                                                 LCID lcid, DISPID *rgDispId)
 {
+    ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
+    ok(cNames==1, "cNames = %d\n", cNames);
+
+    if(!strcmp_wa(*rgszNames, "prop")) {
+        CHECK_EXPECT(puredisp_prop_d);
+        *rgDispId = DISPID_TESTOBJ_PROP;
+        return S_OK;
+    } else if(!strcmp_wa(*rgszNames, "noprop")) {
+        CHECK_EXPECT(puredisp_noprop_d);
+        return DISP_E_UNKNOWNNAME;
+    }
+
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
@@ -1476,6 +1490,22 @@ static void run_tests(void)
     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
     CHECK_CALLED(testobj_noprop_d);
 
+    SET_EXPECT(testobj_prop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\\\"prop\\\") returned false');");
+    CHECK_CALLED(testobj_prop_d);
+
+    SET_EXPECT(testobj_noprop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
+    CHECK_CALLED(testobj_noprop_d);
+
+    SET_EXPECT(puredisp_prop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\\\"noprop\\\") returned false');");
+    CHECK_CALLED(puredisp_prop_d);
+
+    SET_EXPECT(puredisp_noprop_d);
+    parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
+    CHECK_CALLED(puredisp_noprop_d);
+
     SET_EXPECT(testobj_value);
     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
     CHECK_CALLED(testobj_value);




More information about the wine-cvs mailing list