Robert Wilhelm : vbscript: Support class default sub.

Alexandre Julliard julliard at winehq.org
Tue Mar 23 15:07:42 CDT 2021


Module: wine
Branch: oldstable
Commit: 5675b9a2e206efc91ec4d4dd6fe83bc03793caaf
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5675b9a2e206efc91ec4d4dd6fe83bc03793caaf

Author: Robert Wilhelm <robert.wilhelm at gmx.net>
Date:   Tue Oct 13 18:58:21 2020 +0200

vbscript: Support class default sub.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35744
Signed-off-by: Robert Wilhelm <robert.wilhelm at gmx.net>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 16fe2037fb2b3ddec1e6312b076cc76d88e9240a)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/vbscript/compile.c      | 14 +++++++++++---
 dlls/vbscript/parser.y       |  2 +-
 dlls/vbscript/tests/lang.vbs | 30 ++++++++++++++++++++++++++++++
 dlls/vbscript/vbdisp.c       |  6 ++----
 4 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index fc0b22c65c8..0674f634078 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1644,6 +1644,7 @@ static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
 static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
 {
     function_decl_t *func_decl, *func_prop_decl;
+    BOOL is_default, have_default = FALSE;
     class_desc_t *class_desc;
     dim_decl_t *prop_decl;
     unsigned i;
@@ -1666,14 +1667,21 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
     if(!class_desc->name)
         return E_OUTOFMEMORY;
 
-    class_desc->func_cnt = 1; /* always allocate slot for default getter */
+    class_desc->func_cnt = 1; /* always allocate slot for default getter or method */
 
     for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
+        is_default = FALSE;
         for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
-            if(func_prop_decl->is_default)
+            if(func_prop_decl->is_default) {
+                if(have_default) {
+                    FIXME("multiple default getters or methods\n");
+                    return E_FAIL;
+                }
+                is_default = have_default = TRUE;
                 break;
+            }
         }
-        if(!func_prop_decl)
+        if(!is_default)
             class_desc->func_cnt++;
     }
 
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 4a4708e7785..20ec89343af 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -995,7 +995,7 @@ static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name,
     BOOL is_default = FALSE;
 
     if(storage_flags & STORAGE_IS_DEFAULT) {
-        if(type == FUNC_PROPGET) {
+        if(type == FUNC_PROPGET || type == FUNC_FUNCTION || type == FUNC_SUB) {
             is_default = TRUE;
         }else {
             FIXME("Invalid default property\n");
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 14761cf5a52..2cd4f3ef2f7 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1671,6 +1671,36 @@ call ok(x.getProp.prop.prop = 3, "x.getProp.prop.prop = " & x.getProp.prop.prop)
 ok getVT(x) = "VT_DISPATCH*", "getVT(x) = " & getVT(x)
 todo_wine_ok getVT(x()) = "VT_BSTR", "getVT(x()) = " & getVT(x())
 
+funcCalled = ""
+class DefaultSubTest1
+ Public  default Sub init(a)
+    funcCalled = "init" & a
+ end sub
+end class
+
+Set obj = New DefaultSubTest1
+obj.init(1)
+call ok(funcCalled = "init1","funcCalled=" & funcCalled)
+funcCalled = ""
+obj(2)
+call ok(funcCalled = "init2","funcCalled=" & funcCalled)
+
+class DefaultSubTest2
+ Public Default Function init
+    funcCalled = "init"
+ end function
+end class
+
+Set obj = New DefaultSubTest2
+funcCalled = ""
+obj.init()
+call ok(funcCalled = "init","funcCalled=" & funcCalled)
+funcCalled = ""
+' todo this is not yet supported
+'funcCalled = ""
+'obj()
+'call ok(funcCalled = "init","funcCalled=" & funcCalled)
+
 with nothing
 end with
 
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 7db333660d7..33366b9de51 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -38,19 +38,17 @@ static BOOL get_func_id(vbdisp_t *This, const WCHAR *name, vbdisp_invoke_type_t
 {
     unsigned i;
 
-    for(i = invoke_type == VBDISP_ANY ? 0 : 1; i < This->desc->func_cnt; i++) {
+    for(i = 0; i < This->desc->func_cnt; i++) {
         if(invoke_type == VBDISP_ANY) {
             if(!search_private && !This->desc->funcs[i].is_public)
                 continue;
-            if(!i && !This->desc->funcs[0].name) /* default value may not exist */
-                continue;
         }else {
             if(!This->desc->funcs[i].entries[invoke_type]
                 || (!search_private && !This->desc->funcs[i].entries[invoke_type]->is_public))
                 continue;
         }
 
-        if(!wcsicmp(This->desc->funcs[i].name, name)) {
+        if(This->desc->funcs[i].name && !wcsicmp(This->desc->funcs[i].name, name)) {
             *id = i;
             return TRUE;
         }




More information about the wine-cvs mailing list