[PATCH 0/3] MR10637: vbscript: Return specific errors for Do keyword, End Class, and property arg count
Return proper error codes instead of generic 1002 (syntax error): - 1028: "Expected 'While', 'Until' or end of statement" for `Do For`, `Do If`, etc. - 1047: "Expected 'Class'" for mismatched `End` keyword inside class body - 1051: "Number of arguments must be consistent across properties specification" for Property Get/Let/Set arg count mismatch -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10637
From: Francis De Brabandere <francisdb@gmail.com> Return "Expected 'While', 'Until' or end of statement" when 'Do' is followed by an unexpected keyword like 'For' or 'If'. --- dlls/vbscript/parser.y | 1 + dlls/vbscript/tests/run.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 1a8ae2013c9..19cfccd6032 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -232,6 +232,7 @@ SimpleStatement { $$ = new_while_statement(ctx, @4, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3); CHECK_ERROR; } | tDO StSep StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, @$, STAT_DOWHILE, NULL, $3); CHECK_ERROR; } + | tDO error { ctx->hres = MAKE_VBSERROR(VBSE_EXPECTED_WHILE_UNTIL_EOS); YYABORT; } | FunctionDecl { $$ = new_function_statement(ctx, @$, $1); CHECK_ERROR; } | tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0, @2); CHECK_ERROR; } | tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0, @2); CHECK_ERROR; } diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 37c8883fcd9..f269d1f571f 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3206,6 +3206,12 @@ static void test_parse_errors(void) "End Class\n", 2, 11, NULL, S_OK, 1037 + }, + { + /* Do followed by wrong keyword - error 1028 */ + L"Do For\nLoop\n", + 0, 3, + NULL, S_OK, 1028 } }; HRESULT hres; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10637
From: Francis De Brabandere <francisdb@gmail.com> Return "Expected 'Class'" when a class body is closed with 'End Sub', 'End Function', or other mismatched 'End' keywords instead of 'End Class'. --- dlls/vbscript/parser.y | 1 + dlls/vbscript/tests/run.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 19cfccd6032..d8d904a5b8f 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -490,6 +490,7 @@ PrimaryExpression ClassDeclaration : tCLASS Identifier StSep ClassBody tEND tCLASS StSep { $4->name = $2; $$ = $4; } + | tCLASS Identifier StSep ClassBody tEND error { ctx->hres = MAKE_VBSERROR(VBSE_EXPECTED_CLASS); YYABORT; } ClassBody : /* empty */ { $$ = new_class_decl(ctx); } diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index f269d1f571f..06702138d50 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3212,6 +3212,12 @@ static void test_parse_errors(void) L"Do For\nLoop\n", 0, 3, NULL, S_OK, 1028 + }, + { + /* Expected 'Class' - End Sub inside class body - error 1047 */ + L"Class C\nEnd Sub\n", + 1, 4, + NULL, S_OK, 1047 } }; HRESULT hres; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10637
From: Francis De Brabandere <francisdb@gmail.com> Return "Number of arguments must be consistent across properties specification" when Property Get/Let/Set declarations for the same name have incompatible argument counts. Property Let/Set must have exactly one more argument than Property Get. --- dlls/vbscript/parser.y | 26 ++++++++++++++++++++++++++ dlls/vbscript/tests/run.c | 9 +++++++++ 2 files changed, 35 insertions(+) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index d8d904a5b8f..290a964afc8 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -1179,6 +1179,27 @@ static class_decl_t *new_class_decl(parser_ctx_t *ctx) return class_decl; } +static unsigned count_args(arg_decl_t *args) +{ + unsigned cnt = 0; + while(args) { cnt++; args = args->next; } + return cnt; +} + +static BOOL check_property_args(function_decl_t *a, function_decl_t *b) +{ + unsigned a_cnt = count_args(a->args); + unsigned b_cnt = count_args(b->args); + + /* Property Get takes N args, Property Let/Set takes N+1 */ + if(a->type == FUNC_PROPGET) + return (b_cnt == a_cnt + 1); + if(b->type == FUNC_PROPGET) + return (a_cnt == b_cnt + 1); + /* Let vs Set: same arg count */ + return (a_cnt == b_cnt); +} + static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_decl, function_decl_t *decl) { function_decl_t *iter; @@ -1205,6 +1226,11 @@ static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_d iter = iter->next_prop_func; } + if(!check_property_args(iter, decl)) { + ctx->error_loc = decl->loc; + ctx->hres = MAKE_VBSERROR(VBSE_PROPERTY_ARG_COUNT_MISMATCH); + return NULL; + } iter->next_prop_func = decl; return class_decl; } diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 06702138d50..7df531672b5 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3218,6 +3218,15 @@ static void test_parse_errors(void) L"Class C\nEnd Sub\n", 1, 4, NULL, S_OK, 1047 + }, + { + /* Property arg count mismatch - error 1051 */ + L"Class C\n" + "Property Get P\n P = 1\nEnd Property\n" + "Property Let P(a, b)\nEnd Property\n" + "End Class\n", + -4, -20, + NULL, S_OK, 1051 } }; HRESULT hres; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10637
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)