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