diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index dae8a97c832..6b0e113bef5 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1571,7 +1571,7 @@ static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, functi function_t *func; HRESULT hres; - if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) { + if(lookup_dim_decls(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) { FIXME("%s: redefinition\n", debugstr_w(decl->name)); return E_FAIL; } @@ -1826,7 +1826,6 @@ static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script) { class_desc_t *class; dynamic_var_t *var; - function_t *func; for(var = ctx->global_vars; var; var = var->next) { if(lookup_script_identifier(script, var->name)) { @@ -1835,13 +1834,6 @@ static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script) } } - for(func = ctx->funcs; func; func = func->next) { - if(lookup_script_identifier(script, func->name)) { - FIXME("%s: redefined\n", debugstr_w(func->name)); - return E_FAIL; - } - } - for(class = ctx->classes; class; class = class->next) { if(lookup_script_identifier(script, class->name)) { FIXME("%s: redefined\n", debugstr_w(class->name)); @@ -1997,8 +1989,18 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *deli script->global_funcs = new_funcs; script->global_funcs_size = cnt; } - for(func_iter = ctx.funcs; func_iter; func_iter = func_iter->next) - script->global_funcs[script->global_funcs_cnt++] = func_iter; + for(func_iter = ctx.funcs; func_iter; func_iter = func_iter->next) { + unsigned i; + for(i = 0; i < script->global_funcs_cnt; i++) { + if(!wcsicmp(script->global_funcs[i]->name, func_iter->name)) { + /* global function already exists, replace it */ + script->global_funcs[i] = func_iter; + break; + } + } + if(i == script->global_funcs_cnt) + script->global_funcs[script->global_funcs_cnt++] = func_iter; + } if(ctx.classes) { class_desc_t *class = ctx.classes; diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 4623a08e2ba..8a6f0ecd45f 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -886,6 +886,21 @@ Public Function TestSepFunc(ByVal a) : : End Function Call ok(TestSepFunc(1) = 1, "Function did not return 1") +ok duplicatedfunc() = 2, "duplicatedfunc = " & duplicatedfunc() + +function duplicatedfunc + ok false, "duplicatedfunc called" +end function + +sub duplicatedfunc + ok false, "duplicatedfunc called" +end sub + +function duplicatedfunc + duplicatedfunc = 2 +end function + +ok duplicatedfunc() = 2, "duplicatedfunc = " & duplicatedfunc() ' Stop has an effect only in debugging mode Stop diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index d3d41a80d2f..9ed1096a4dc 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2688,6 +2688,47 @@ static void test_isexpression(void) close_script(engine); } +static void test_multiple_parse(void) +{ + IActiveScriptParse *parser; + IActiveScript *script; + HRESULT hres; + + script = create_and_init_script(SCRIPTITEM_GLOBALMEMBERS, TRUE); + + hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres); + + hres = IActiveScriptParse_ParseScriptText(parser, + L"function duplicatedfunc\n" + L" ok false, \"duplicatedfunc called\"\n" + L"end function\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + + hres = IActiveScriptParse_ParseScriptText(parser, + L"sub duplicatedfunc\n" + L" ok false, \"duplicatedfunc called\"\n" + L"end sub\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + + hres = IActiveScriptParse_ParseScriptText(parser, + L"function duplicatedfunc\n" + L" duplicatedfunc = 2\n" + L"end function\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + + hres = IActiveScriptParse_ParseScriptText(parser, + L"ok duplicatedfunc() = 2, \"duplicatedfunc = \" & duplicatedfunc()\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + + IActiveScriptParse_Release(parser); + close_script(script); +} + static BSTR get_script_from_file(const char *filename) { DWORD size, len; @@ -3037,6 +3078,7 @@ static void run_tests(void) test_parse_errors(); test_parse_context(); test_callbacks(); + test_multiple_parse(); } static BOOL check_vbscript(void)