Jacek Caban : jscript: Add parser support for getters and setters in object initializer.

Alexandre Julliard julliard at winehq.org
Mon Dec 3 15:28:52 CST 2018


Module: wine
Branch: master
Commit: 56be97fd5d5fc0a9a5b78005383f6e8770c7fec8
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=56be97fd5d5fc0a9a5b78005383f6e8770c7fec8

Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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




More information about the wine-cvs mailing list