Module: wine Branch: master Commit: 56be97fd5d5fc0a9a5b78005383f6e8770c7fec8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=56be97fd5d5fc0a9a5b780053...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Nov 30 22:44:32 2018 +0100
jscript: Add parser support for getters and setters in object initializer.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/jscript/engine.h | 6 ++++++ dlls/jscript/lex.c | 17 ++++++++++++++--- dlls/jscript/parser.h | 1 + dlls/jscript/parser.y | 29 +++++++++++++++++++++-------- dlls/jscript/tests/lang.js | 2 ++ 5 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index d3fd3d77..d0c419a 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -129,6 +129,12 @@ typedef struct { } u; } instr_t;
+typedef enum { + PROPERTY_DEFINITION_VALUE, + PROPERTY_DEFINITION_GETTER, + PROPERTY_DEFINITION_SETTER +} property_definition_type_t; + typedef struct { BSTR name; int ref; diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c index 7ef2112..be20e99 100644 --- a/dlls/jscript/lex.c +++ b/dlls/jscript/lex.c @@ -46,12 +46,14 @@ static const WCHAR falseW[] = {'f','a','l','s','e',0}; static const WCHAR finallyW[] = {'f','i','n','a','l','l','y',0}; static const WCHAR forW[] = {'f','o','r',0}; static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0}; +static const WCHAR getW[] = {'g','e','t',0}; static const WCHAR ifW[] = {'i','f',0}; static const WCHAR inW[] = {'i','n',0}; static const WCHAR instanceofW[] = {'i','n','s','t','a','n','c','e','o','f',0}; static const WCHAR newW[] = {'n','e','w',0}; static const WCHAR nullW[] = {'n','u','l','l',0}; static const WCHAR returnW[] = {'r','e','t','u','r','n',0}; +static const WCHAR setW[] = {'s','e','t',0}; static const WCHAR switchW[] = {'s','w','i','t','c','h',0}; static const WCHAR thisW[] = {'t','h','i','s',0}; static const WCHAR throwW[] = {'t','h','r','o','w',0}; @@ -70,11 +72,12 @@ static const struct { const WCHAR *word; int token; BOOL no_nl; + unsigned min_version; } keywords[] = { - {breakW, kBREAK, TRUE}, + {breakW, kBREAK, TRUE}, {caseW, kCASE}, {catchW, kCATCH}, - {continueW, kCONTINUE, TRUE}, + {continueW, kCONTINUE, TRUE}, {defaultW, kDEFAULT}, {deleteW, kDELETE}, {doW, kDO}, @@ -83,12 +86,14 @@ static const struct { {finallyW, kFINALLY}, {forW, kFOR}, {functionW, kFUNCTION}, + {getW, kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, {ifW, kIF}, {inW, kIN}, {instanceofW, kINSTANCEOF}, {newW, kNEW}, {nullW, kNULL}, - {returnW, kRETURN, TRUE}, + {returnW, kRETURN, TRUE}, + {setW, kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, {switchW, kSWITCH}, {thisW, kTHIS}, {throwW, kTHROW}, @@ -169,6 +174,12 @@ static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
r = check_keyword(ctx, keywords[i].word, lval); if(!r) { + if(ctx->script->version < keywords[i].min_version) { + TRACE("ignoring keyword %s in incompatible mode\n", + debugstr_w(keywords[i].word)); + ctx->ptr -= strlenW(keywords[i].word); + return 0; + } ctx->implicit_nl_semicolon = keywords[i].no_nl; return keywords[i].token; } diff --git a/dlls/jscript/parser.h b/dlls/jscript/parser.h index 908d6b6..03f504f 100644 --- a/dlls/jscript/parser.h +++ b/dlls/jscript/parser.h @@ -359,6 +359,7 @@ typedef struct { } array_literal_expression_t;
typedef struct _property_definition_t { + unsigned type; literal_t *name; expression_t *value;
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 47ac1bc..157bc18 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -45,8 +45,8 @@ typedef struct _property_list_t { property_definition_t *tail; } property_list_t;
-static property_definition_t *new_property_definition(parser_ctx_t *ctx, literal_t *name, - expression_t *value); +static property_definition_t *new_property_definition(parser_ctx_t *ctx, property_definition_type_t, + literal_t *name, expression_t *value); static property_list_t *new_property_list(parser_ctx_t*,property_definition_t*); static property_list_t *property_list_add(parser_ctx_t*,property_list_t*,property_definition_t*);
@@ -167,7 +167,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state }
/* keywords */ -%token <identifier> kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kFUNCTION kIF kFINALLY kFOR kIN +%token <identifier> kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kFUNCTION kIF kFINALLY kFOR kGET kIN kSET %token <identifier> kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH %token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ kDCOL
@@ -224,6 +224,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state %type <expr> CallExpression %type <expr> MemberExpression %type <expr> PrimaryExpression +%type <expr> GetterSetterMethod %type <identifier> Identifier_opt %type <variable_list> VariableDeclarationList %type <variable_list> VariableDeclarationListNoIn @@ -243,7 +244,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state %type <property_definition> PropertyDefinition %type <literal> PropertyName %type <literal> BooleanLiteral -%type <srcptr> KFunction +%type <srcptr> KFunction left_bracket %type <ival> AssignOper %type <identifier> IdentifierName ReservedAsIdentifier
@@ -800,9 +801,17 @@ PropertyNameAndValueList /* ECMA-262 5.1 Edition 12.2.6 */ PropertyDefinition : PropertyName ':' AssignmentExpression - { $$ = new_property_definition(ctx, $1, $3); } + { $$ = new_property_definition(ctx, PROPERTY_DEFINITION_VALUE, $1, $3); } + | kGET PropertyName GetterSetterMethod + { $$ = new_property_definition(ctx, PROPERTY_DEFINITION_GETTER, $2, $3); } + | kSET PropertyName GetterSetterMethod + { $$ = new_property_definition(ctx, PROPERTY_DEFINITION_SETTER, $2, $3); }
-/* ECMA-262 3rd Edition 11.1.5 */ +GetterSetterMethod + : left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' + { $$ = new_function_expression(ctx, NULL, $2, $5, NULL, $1, $6-$1); } + +/* Ecma-262 3rd Edition 11.1.5 */ PropertyName : IdentifierName { $$ = new_string_literal(ctx, $1); } | tStringLiteral { $$ = new_string_literal(ctx, $1); } @@ -839,12 +848,14 @@ ReservedAsIdentifier | kFINALLY { $$ = $1; } | kFOR { $$ = $1; } | kFUNCTION { $$ = $1; } + | kGET { $$ = $1; } | kIF { $$ = $1; } | kIN { $$ = $1; } | kINSTANCEOF { $$ = $1; } | kNEW { $$ = $1; } | kNULL { $$ = $1; } | kRETURN { $$ = $1; } + | kSET { $$ = $1; } | kSWITCH { $$ = $1; } | kTHIS { $$ = $1; } | kTHROW { $$ = $1; } @@ -878,7 +889,7 @@ semicolon_opt | error { if(!allow_auto_semicolon(ctx)) {YYABORT;} }
left_bracket - : '(' + : '(' { $$ = ctx->ptr; } | error { set_error(ctx, JS_E_MISSING_LBRACKET); YYABORT; }
right_bracket @@ -929,10 +940,12 @@ static literal_t *new_null_literal(parser_ctx_t *ctx) return ret; }
-static property_definition_t *new_property_definition(parser_ctx_t *ctx, literal_t *name, expression_t *value) +static property_definition_t *new_property_definition(parser_ctx_t *ctx, property_definition_type_t type, + literal_t *name, expression_t *value) { property_definition_t *ret = parser_alloc(ctx, sizeof(property_definition_t));
+ ret->type = type; ret->name = name; ret->value = value; ret->next = NULL; diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 1cd5668..2a30ea3 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1832,6 +1832,8 @@ ok(tmp, "tmp = " + tmp); ok(x === undefined, "x = " + x); })();
+var get, set; + /* NoNewline rule parser tests */ while(true) { if(true) break