diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 520398f90e9..f4b065f1d53 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2014,10 +2014,42 @@ HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, js return E_NOTIMPL; } -HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.4.2 */ +HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + unary_expression_t *expr = (unary_expression_t*)_expr; + VARIANT_BOOL b = VARIANT_FALSE; + exprval_t exprval; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression, EXPR_STRREF, ei, &exprval); + if(FAILED(hres)) + return hres; + + switch(exprval.type) { + case EXPRVAL_NAMEREF: { + IDispatchEx *dispex; + + hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex); + if(SUCCEEDED(hres)) { + hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name, fdexNameCaseSensitive); + b = VARIANT_TRUE; + IDispatchEx_Release(dispex); + } + break; + } + default: + FIXME("unsupported type %d\n", exprval.type); + hres = E_NOTIMPL; + } + + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + return return_bool(ret, b); } /* ECMA-262 3rd Edition 11.4.2 */ diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 1e5fcf97413..4359ca4d80b 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -650,4 +650,11 @@ ok(arr["test1"] === true, "arr[test1] !== true"); ok(arr["test2"] === true, "arr[test2] !== true"); ok(arr["test3"] === true, "arr[test3] !== true"); +tmp = new Object(); +tmp.test = false; +ok((delete tmp.test) === true, "delete returned false"); +ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test)); +for(iter in tmp) + ok(false, "tmp has prop " + iter); + reportSuccess(); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index ee9cccce5f9..c40653a9b29 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -63,6 +63,7 @@ DEFINE_EXPECT(global_propput_d); DEFINE_EXPECT(global_propput_i); DEFINE_EXPECT(global_success_d); DEFINE_EXPECT(global_success_i); +DEFINE_EXPECT(testobj_delete); #define DISPID_GLOBAL_TESTPROPGET 0x1000 #define DISPID_GLOBAL_TESTPROPPUT 0x1001 @@ -70,6 +71,7 @@ DEFINE_EXPECT(global_success_i); #define DISPID_GLOBAL_TRACE 0x1003 #define DISPID_GLOBAL_OK 0x1004 #define DISPID_GLOBAL_GETVT 0x1005 +#define DISPID_GLOBAL_TESTOBJ 0x1006 static const WCHAR testW[] = {'t','e','s','t',0}; @@ -195,6 +197,48 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown return E_NOTIMPL; } +static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) +{ + CHECK_EXPECT(testobj_delete); + + ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", debugstr_w(bstrName)); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + return S_OK; +} + +static IDispatchExVtbl testObjVtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + DispatchEx_GetDispID, + DispatchEx_InvokeEx, + testObj_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +static IDispatchEx testObj = { &testObjVtbl }; + static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { if(!strcmp_wa(bstrName, "ok")) { @@ -230,6 +274,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD *pid = DISPID_GLOBAL_GETVT; return S_OK; } + if(!strcmp_wa(bstrName, "testObj")) { + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_TESTOBJ; + return S_OK; + } if(strict_dispid_check) ok(0, "unexpected call %s\n", debugstr_w(bstrName)); @@ -361,7 +410,22 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, } return S_OK; - } + + case DISPID_GLOBAL_TESTOBJ: + ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgvarg, "rgvarg != NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + ok(pei != NULL, "pei == NULL\n"); + + V_VT(pvarRes) = VT_DISPATCH; + V_DISPATCH(pvarRes) = (IDispatch*)&testObj; + return S_OK; + } ok(0, "unexpected call %x\n", id); return DISP_E_MEMBERNOTFOUND; @@ -584,6 +648,10 @@ static void run_tests(void) CHECK_CALLED(global_success_d); CHECK_CALLED(global_success_i); + SET_EXPECT(testobj_delete); + parse_script_a("delete testObj.deleteTest;"); + CHECK_CALLED(testobj_delete); + run_from_res("lang.js"); run_from_res("api.js"); run_from_res("regexp.js");