closes https://bugs.winehq.org/show_bug.cgi?id=53644
* This applies the patch [provided by](https://bugs.winehq.org/show_bug.cgi?id=53644) @sloper42 and adds tests. * I left a TODO for accessing class variables of type array for a later mr.
-- v6: vbscript: class single line multivar
From: Francis De Brabandere francisdb@gmail.com
--- dlls/vbscript/parser.y | 42 ++++++++++++++++++++++++--------- dlls/vbscript/tests/lang.vbs | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 11 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 09d60bff5d9..20c30eed681 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -150,11 +150,11 @@ static statement_t *link_statements(statement_t*,statement_t*); %type <elseif> ElseIfs_opt ElseIfs ElseIf %type <class_decl> ClassDeclaration ClassBody %type <uint> Storage Storage_opt IntegerValue -%type <dim_decl> DimDeclList DimDecl +%type <dim_decl> DimDeclList DimDecl MemberDeclList MemberDecl %type <dim_list> DimList %type <redim_decl> ReDimDeclList ReDimDecl %type <const_decl> ConstDecl ConstDeclList -%type <string> Identifier +%type <string> Identifier MemberIdentifier %type <case_clausule> CaseClausules
%% @@ -257,6 +257,15 @@ Preserve_opt : /* empty */ { $$ = FALSE; } | tPRESERVE { $$ = TRUE; }
+MemberDeclList + : MemberDecl { $$ = $1; } + | MemberDecl ',' MemberDeclList { $1->next = $3; $$ = $1; } + +MemberDecl + : MemberIdentifier { $$ = new_dim_decl(ctx, $1, FALSE, NULL); CHECK_ERROR; } + | MemberIdentifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, TRUE, $3); CHECK_ERROR; } + | MemberIdentifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, TRUE, NULL); CHECK_ERROR; } + ReDimDecl : tIdentifier '(' ArgumentList ')' { $$ = new_redim_decl(ctx, $1, $3); CHECK_ERROR; }
@@ -458,13 +467,10 @@ ClassBody : /* empty */ { $$ = new_class_decl(ctx); } | FunctionDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; } | FunctionDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; } - /* FIXME: We should use DimDecl here to support arrays, but that conflicts with PropertyDecl. */ - | Storage tIdentifier { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR; - $$ = add_dim_prop(ctx, new_class_decl(ctx), dim_decl, $1); CHECK_ERROR; } - | Storage tIdentifier StSep ClassBody { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR; - $$ = add_dim_prop(ctx, $4, dim_decl, $1); CHECK_ERROR; } - | tDIM DimDecl { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, 0); CHECK_ERROR; } - | tDIM DimDecl StSep ClassBody { $$ = add_dim_prop(ctx, $4, $2, 0); CHECK_ERROR; } + | Storage MemberDeclList { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, $1); CHECK_ERROR; } + | Storage MemberDeclList StSep ClassBody { $$ = add_dim_prop(ctx, $4, $2, $1); CHECK_ERROR; } + | tDIM DimDeclList { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, 0); CHECK_ERROR; } + | tDIM DimDeclList StSep ClassBody { $$ = add_dim_prop(ctx, $4, $2, 0); CHECK_ERROR; } | PropertyDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; } | PropertyDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
@@ -513,6 +519,12 @@ ArgumentDecl | tBYVAL Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, FALSE); }
/* these keywords may also be an identifier, depending on context */ +MemberIdentifier + : tIdentifier { $$ = $1; } + | tERROR { ctx->last_token = tIdentifier; $$ = $1; } + | tEXPLICIT { ctx->last_token = tIdentifier; $$ = $1; } + | tSTEP { ctx->last_token = tIdentifier; $$ = $1; } + Identifier : tIdentifier { $$ = $1; } | tDEFAULT { ctx->last_token = tIdentifier; $$ = $1; } @@ -1135,14 +1147,22 @@ static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_d
static class_decl_t *add_dim_prop(parser_ctx_t *ctx, class_decl_t *class_decl, dim_decl_t *dim_decl, unsigned storage_flags) { + dim_decl_t *iter; + if(storage_flags & STORAGE_IS_DEFAULT) { FIXME("variant prop can't be default value\n"); ctx->hres = E_FAIL; return NULL; }
- dim_decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE); - dim_decl->next = class_decl->props; + iter = dim_decl; + while(1) { + iter->is_public = !(storage_flags & STORAGE_IS_PRIVATE); + if (!iter->next) break; + iter = iter->next; + } + + iter->next = class_decl->props; class_decl->props = dim_decl; return class_decl; } diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 3c6ce656f1c..10b5ea3c86a 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -2142,6 +2142,51 @@ call ok(x.getprop.getprop().prop is obj, "x.getprop.getprop().prop is not obj (e ok getVT(x) = "VT_DISPATCH*", "getVT(x) = " & getVT(x) todo_wine_ok getVT(x()) = "VT_BSTR", "getVT(x()) = " & getVT(x())
+Class TestClassVariablesMulti + Public pub1, pub2 + Public pubArray(3), pubArray2(5, 10) + Private priv1, priv2 + Private error, explicit, step + Dim dim1, dim2 + + Private Sub Class_Initialize() + pub1 = 1 + pub2 = 2 + pubArray(0) = 3 + pubArray2(0, 0) = 4 + priv1 = 5 + priv2 = 6 + dim1 = 7 + dim2 = 8 + error = 9 + explicit = 10 + step = 11 + End Sub +End Class + +Set x = new TestClassVariablesMulti +call ok(x.pub1 = 1, "x.pub1 = " & x.pub1) +call ok(x.pub2 = 2, "x.pub2 = " & x.pub2) +call ok(ubound(x.pubArray) = 3, "ubound(x.pubArray) = " & ubound(x.pubArray)) +call ok(ubound(x.pubArray2, 1) = 5, "ubound(x.pubArray2, 1) = " & ubound(x.pubArray2, 1)) +call ok(ubound(x.pubArray2, 2) = 10, "ubound(x.pubArray2, 2) = " & ubound(x.pubArray2, 2)) +' TODO: this does not parse: accessing class variable of array type element directly +' call ok(x.pubArray(0) = 3, "x.pubArray(0) = " & x.pubArray(0)) +call ok(x.dim1 = 7, "x.dim1 = " & x.dim1) +call ok(x.dim2 = 8, "x.dim2 = " & x.dim2) + +on error resume next +x.priv1 = 1 +call ok(err.number = 438, "err.number = " & err.number) +err.clear +x.priv2 = 2 +call ok(err.number = 438, "err.number = " & err.number) +err.clear +' TODO: set class variable of array type element directly +x.pubArray(0) = 1 +call todo_wine_ok(err.number = 0, "set x.pubArray(0) err.number = " & err.number) +on error goto 0 + funcCalled = "" class DefaultSubTest1 Public default Sub init(a)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151220
Your paranoid android.
=== debian11b (64 bit WoW report) ===
kernel32: comm.c:1586: Test failed: Unexpected time 1001, expected around 500
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0000000000DC00E6, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
On Tue Feb 4 08:23:26 2025 +0000, Jacek Caban wrote:
The patch looks good to me now. However, please add class variables with those keywords as names to the test.
Ok like this?
On Tue Feb 4 14:11:59 2025 +0000, Francis De Brabandere wrote:
Ok like this?
Yes, thanks.
This merge request was approved by Jacek Caban.