jscript: Added AddNamedItem implementation.

oldstable
Jacek Caban 2008-09-09 01:22:31 +02:00 committed by Alexandre Julliard
parent 2a7c9f1b92
commit 2bbd9d4105
4 changed files with 120 additions and 4 deletions

View File

@ -123,6 +123,24 @@ static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID
return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
}
static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
{
IDispatchEx *dispex;
HRESULT hres;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(FAILED(hres)) {
TRACE("unsing IDispatch\n");
*id = 0;
return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
}
hres = dispex_get_id(dispex, name, flags, id);
IDispatchEx_Release(dispex);
return hres;
}
HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
{
script_ctx_t *script = parser->script;
@ -178,6 +196,7 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so
/* ECMA-262 3rd Edition 10.1.4 */
static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
{
named_item_t *item;
DISPID id = 0;
HRESULT hres;
@ -185,7 +204,17 @@ static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, ex
/* FIXME: scope chain */
/* FIXME: global */
/* FIXME: named items */
for(item = ctx->parser->script->named_items; item; item = item->next) {
hres = disp_get_id(item->disp, identifier, 0, &id);
if(SUCCEEDED(hres))
break;
}
if(item) {
exprval_set_idref(ret, (IDispatch*)item->disp, id);
return S_OK;
}
hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
if(SUCCEEDED(hres)) {

View File

@ -320,8 +320,41 @@ static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
LPCOLESTR pstrName, DWORD dwFlags)
{
JScript *This = ACTSCRIPT_THIS(iface);
FIXME("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
return E_NOTIMPL;
named_item_t *item;
IDispatch *disp;
IUnknown *unk;
HRESULT hres;
TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED;
hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
if(FAILED(hres)) {
WARN("GetItemInfo failed: %08x\n", hres);
return hres;
}
hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
IUnknown_Release(unk);
if(FAILED(hres)) {
WARN("object does not implement IDispatch\n");
return hres;
}
item = heap_alloc(sizeof(*item));
if(!item) {
IDispatch_Release(disp);
return E_OUTOFMEMORY;
}
item->disp = disp;
item->flags = dwFlags;
item->next = This->ctx->named_items;
This->ctx->named_items = item;
return S_OK;
}
static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,

View File

@ -89,11 +89,19 @@ HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,DispatchEx*,DispatchEx
HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
typedef struct named_item_t {
IDispatch *disp;
DWORD flags;
struct named_item_t *next;
} named_item_t;
struct _script_ctx_t {
LONG ref;
SCRIPTSTATE state;
exec_ctx_t *exec_ctx;
named_item_t *named_items;
LCID lcid;
DispatchEx *script_disp;

View File

@ -57,6 +57,11 @@ static const CLSID CLSID_JScript =
expect_ ## func = called_ ## func = FALSE; \
}while(0)
DEFINE_EXPECT(global_propget_d);
DEFINE_EXPECT(global_propget_i);
#define DISPID_GLOBAL_TESTPROPGET 0x1000
static const WCHAR testW[] = {'t','e','s','t',0};
static const char *debugstr_w(LPCWSTR str)
@ -82,6 +87,13 @@ static BSTR a2bstr(const char *str)
return ret;
}
static int strcmp_wa(LPCWSTR strw, const char *stra)
{
WCHAR buf[512];
MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
return lstrcmpW(strw, buf);
}
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
@ -173,12 +185,41 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown
static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
if(!strcmp_wa(bstrName, "testPropGet")) {
CHECK_EXPECT(global_propget_d);
ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
*pid = DISPID_GLOBAL_TESTPROPGET;
return S_OK;
}
ok(0, "unexpected call %s\n", debugstr_w(bstrName));
return DISP_E_UNKNOWNNAME;
}
static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
switch(id) {
case DISPID_GLOBAL_TESTPROPGET:
CHECK_EXPECT(global_propget_i);
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_I4;
V_I4(pvarRes) = 1;
return S_OK;
}
ok(0, "unexpected call %x\n", id);
return DISP_E_MEMBERNOTFOUND;
}
@ -326,7 +367,6 @@ static void parse_script(BSTR script_str)
hres = IActiveScript_AddNamedItem(engine, testW,
SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
todo_wine
ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
@ -350,6 +390,12 @@ static void run_tests(void)
{
parse_script_a("");
parse_script_a("/* empty */ ;");
SET_EXPECT(global_propget_d);
SET_EXPECT(global_propget_i);
parse_script_a("testPropGet;");
CHECK_CALLED(global_propget_d);
CHECK_CALLED(global_propget_i);
}
START_TEST(run)