Commit 56be97fd authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

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

parent fd4c3475
...@@ -129,6 +129,12 @@ typedef struct { ...@@ -129,6 +129,12 @@ typedef struct {
} u; } u;
} instr_t; } instr_t;
typedef enum {
PROPERTY_DEFINITION_VALUE,
PROPERTY_DEFINITION_GETTER,
PROPERTY_DEFINITION_SETTER
} property_definition_type_t;
typedef struct { typedef struct {
BSTR name; BSTR name;
int ref; int ref;
......
...@@ -46,12 +46,14 @@ static const WCHAR falseW[] = {'f','a','l','s','e',0}; ...@@ -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 finallyW[] = {'f','i','n','a','l','l','y',0};
static const WCHAR forW[] = {'f','o','r',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 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 ifW[] = {'i','f',0};
static const WCHAR inW[] = {'i','n',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 instanceofW[] = {'i','n','s','t','a','n','c','e','o','f',0};
static const WCHAR newW[] = {'n','e','w',0}; static const WCHAR newW[] = {'n','e','w',0};
static const WCHAR nullW[] = {'n','u','l','l',0}; static const WCHAR nullW[] = {'n','u','l','l',0};
static const WCHAR returnW[] = {'r','e','t','u','r','n',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 switchW[] = {'s','w','i','t','c','h',0};
static const WCHAR thisW[] = {'t','h','i','s',0}; static const WCHAR thisW[] = {'t','h','i','s',0};
static const WCHAR throwW[] = {'t','h','r','o','w',0}; static const WCHAR throwW[] = {'t','h','r','o','w',0};
...@@ -70,11 +72,12 @@ static const struct { ...@@ -70,11 +72,12 @@ static const struct {
const WCHAR *word; const WCHAR *word;
int token; int token;
BOOL no_nl; BOOL no_nl;
unsigned min_version;
} keywords[] = { } keywords[] = {
{breakW, kBREAK, TRUE}, {breakW, kBREAK, TRUE},
{caseW, kCASE}, {caseW, kCASE},
{catchW, kCATCH}, {catchW, kCATCH},
{continueW, kCONTINUE, TRUE}, {continueW, kCONTINUE, TRUE},
{defaultW, kDEFAULT}, {defaultW, kDEFAULT},
{deleteW, kDELETE}, {deleteW, kDELETE},
{doW, kDO}, {doW, kDO},
...@@ -83,12 +86,14 @@ static const struct { ...@@ -83,12 +86,14 @@ static const struct {
{finallyW, kFINALLY}, {finallyW, kFINALLY},
{forW, kFOR}, {forW, kFOR},
{functionW, kFUNCTION}, {functionW, kFUNCTION},
{getW, kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
{ifW, kIF}, {ifW, kIF},
{inW, kIN}, {inW, kIN},
{instanceofW, kINSTANCEOF}, {instanceofW, kINSTANCEOF},
{newW, kNEW}, {newW, kNEW},
{nullW, kNULL}, {nullW, kNULL},
{returnW, kRETURN, TRUE}, {returnW, kRETURN, TRUE},
{setW, kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
{switchW, kSWITCH}, {switchW, kSWITCH},
{thisW, kTHIS}, {thisW, kTHIS},
{throwW, kTHROW}, {throwW, kTHROW},
...@@ -169,6 +174,12 @@ static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval) ...@@ -169,6 +174,12 @@ static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
r = check_keyword(ctx, keywords[i].word, lval); r = check_keyword(ctx, keywords[i].word, lval);
if(!r) { 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; ctx->implicit_nl_semicolon = keywords[i].no_nl;
return keywords[i].token; return keywords[i].token;
} }
......
...@@ -359,6 +359,7 @@ typedef struct { ...@@ -359,6 +359,7 @@ typedef struct {
} array_literal_expression_t; } array_literal_expression_t;
typedef struct _property_definition_t { typedef struct _property_definition_t {
unsigned type;
literal_t *name; literal_t *name;
expression_t *value; expression_t *value;
......
...@@ -45,8 +45,8 @@ typedef struct _property_list_t { ...@@ -45,8 +45,8 @@ typedef struct _property_list_t {
property_definition_t *tail; property_definition_t *tail;
} property_list_t; } property_list_t;
static property_definition_t *new_property_definition(parser_ctx_t *ctx, literal_t *name, static property_definition_t *new_property_definition(parser_ctx_t *ctx, property_definition_type_t,
expression_t *value); literal_t *name, expression_t *value);
static property_list_t *new_property_list(parser_ctx_t*,property_definition_t*); 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*); 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 ...@@ -167,7 +167,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
} }
/* keywords */ /* 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 <identifier> kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH
%token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ kDCOL %token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ kDCOL
...@@ -224,6 +224,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state ...@@ -224,6 +224,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
%type <expr> CallExpression %type <expr> CallExpression
%type <expr> MemberExpression %type <expr> MemberExpression
%type <expr> PrimaryExpression %type <expr> PrimaryExpression
%type <expr> GetterSetterMethod
%type <identifier> Identifier_opt %type <identifier> Identifier_opt
%type <variable_list> VariableDeclarationList %type <variable_list> VariableDeclarationList
%type <variable_list> VariableDeclarationListNoIn %type <variable_list> VariableDeclarationListNoIn
...@@ -243,7 +244,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state ...@@ -243,7 +244,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
%type <property_definition> PropertyDefinition %type <property_definition> PropertyDefinition
%type <literal> PropertyName %type <literal> PropertyName
%type <literal> BooleanLiteral %type <literal> BooleanLiteral
%type <srcptr> KFunction %type <srcptr> KFunction left_bracket
%type <ival> AssignOper %type <ival> AssignOper
%type <identifier> IdentifierName ReservedAsIdentifier %type <identifier> IdentifierName ReservedAsIdentifier
...@@ -800,9 +801,17 @@ PropertyNameAndValueList ...@@ -800,9 +801,17 @@ PropertyNameAndValueList
/* ECMA-262 5.1 Edition 12.2.6 */ /* ECMA-262 5.1 Edition 12.2.6 */
PropertyDefinition PropertyDefinition
: PropertyName ':' AssignmentExpression : 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 PropertyName
: IdentifierName { $$ = new_string_literal(ctx, $1); } : IdentifierName { $$ = new_string_literal(ctx, $1); }
| tStringLiteral { $$ = new_string_literal(ctx, $1); } | tStringLiteral { $$ = new_string_literal(ctx, $1); }
...@@ -839,12 +848,14 @@ ReservedAsIdentifier ...@@ -839,12 +848,14 @@ ReservedAsIdentifier
| kFINALLY { $$ = $1; } | kFINALLY { $$ = $1; }
| kFOR { $$ = $1; } | kFOR { $$ = $1; }
| kFUNCTION { $$ = $1; } | kFUNCTION { $$ = $1; }
| kGET { $$ = $1; }
| kIF { $$ = $1; } | kIF { $$ = $1; }
| kIN { $$ = $1; } | kIN { $$ = $1; }
| kINSTANCEOF { $$ = $1; } | kINSTANCEOF { $$ = $1; }
| kNEW { $$ = $1; } | kNEW { $$ = $1; }
| kNULL { $$ = $1; } | kNULL { $$ = $1; }
| kRETURN { $$ = $1; } | kRETURN { $$ = $1; }
| kSET { $$ = $1; }
| kSWITCH { $$ = $1; } | kSWITCH { $$ = $1; }
| kTHIS { $$ = $1; } | kTHIS { $$ = $1; }
| kTHROW { $$ = $1; } | kTHROW { $$ = $1; }
...@@ -878,7 +889,7 @@ semicolon_opt ...@@ -878,7 +889,7 @@ semicolon_opt
| error { if(!allow_auto_semicolon(ctx)) {YYABORT;} } | error { if(!allow_auto_semicolon(ctx)) {YYABORT;} }
left_bracket left_bracket
: '(' : '(' { $$ = ctx->ptr; }
| error { set_error(ctx, JS_E_MISSING_LBRACKET); YYABORT; } | error { set_error(ctx, JS_E_MISSING_LBRACKET); YYABORT; }
right_bracket right_bracket
...@@ -929,10 +940,12 @@ static literal_t *new_null_literal(parser_ctx_t *ctx) ...@@ -929,10 +940,12 @@ static literal_t *new_null_literal(parser_ctx_t *ctx)
return ret; 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)); property_definition_t *ret = parser_alloc(ctx, sizeof(property_definition_t));
ret->type = type;
ret->name = name; ret->name = name;
ret->value = value; ret->value = value;
ret->next = NULL; ret->next = NULL;
......
...@@ -1832,6 +1832,8 @@ ok(tmp, "tmp = " + tmp); ...@@ -1832,6 +1832,8 @@ ok(tmp, "tmp = " + tmp);
ok(x === undefined, "x = " + x); ok(x === undefined, "x = " + x);
})(); })();
var get, set;
/* NoNewline rule parser tests */ /* NoNewline rule parser tests */
while(true) { while(true) {
if(true) break if(true) break
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment