Skip to content

Commit e0e6363

Browse files
authored
Fix object initializer prescanning issues. (#2563)
This patch fixes incorrect syntax errors reported by the prescanner for ES5.1 getter/setter property initializers and ES2015 computed properties. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
1 parent f8f691d commit e0e6363

File tree

4 files changed

+161
-1
lines changed

4 files changed

+161
-1
lines changed

jerry-core/parser/js/js-lexer.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,9 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
24272427
lexer_next_token (context_p);
24282428

24292429
if (context_p->token.type == LEXER_LITERAL
2430+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
2431+
|| context_p->token.type == LEXER_LEFT_SQUARE
2432+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
24302433
|| context_p->token.type == LEXER_RIGHT_BRACE)
24312434
{
24322435
return;

jerry-core/parser/js/js-parser-scanner.c

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ typedef enum
6767
SCAN_STACK_BLOCK_STATEMENT, /**< block statement group */
6868
SCAN_STACK_BLOCK_EXPRESSION, /**< block expression group */
6969
SCAN_STACK_BLOCK_PROPERTY, /**< block property group */
70+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
71+
SCAN_STACK_COMPUTED_PROPERTY, /**< computed property name */
72+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
7073
#ifndef CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
7174
SCAN_STACK_TEMPLATE_STRING, /**< template string */
7275
#endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
@@ -372,9 +375,41 @@ parser_scan_primary_expression_end (parser_context_t *context_p, /**< context */
372375
return false;
373376
}
374377

378+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
379+
if (context_p->token.type == LEXER_RIGHT_SQUARE && stack_top == SCAN_STACK_COMPUTED_PROPERTY)
380+
{
381+
lexer_next_token (context_p);
382+
383+
parser_stack_pop_uint8 (context_p);
384+
stack_top = (scan_stack_modes_t) context_p->stack_top_uint8;
385+
386+
if (stack_top == SCAN_STACK_BLOCK_PROPERTY)
387+
{
388+
if (context_p->token.type != LEXER_LEFT_PAREN)
389+
{
390+
parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIST_EXPECTED);
391+
}
392+
393+
*mode = SCAN_MODE_FUNCTION_ARGUMENTS;
394+
return true;
395+
}
396+
397+
JERRY_ASSERT (stack_top == SCAN_STACK_OBJECT_LITERAL);
398+
399+
if (context_p->token.type != LEXER_COLON)
400+
{
401+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
402+
}
403+
404+
*mode = SCAN_MODE_PRIMARY_EXPRESSION;
405+
return false;
406+
}
407+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
408+
375409
/* Check whether we can enter to statement mode. */
376410
if (stack_top != SCAN_STACK_BLOCK_STATEMENT
377411
&& stack_top != SCAN_STACK_BLOCK_EXPRESSION
412+
&& stack_top != SCAN_STACK_BLOCK_PROPERTY
378413
#ifndef CONFIG_DISABLE_ES2015_CLASS
379414
&& stack_top != SCAN_STACK_CLASS
380415
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
@@ -776,6 +811,7 @@ parser_scan_until (parser_context_t *context_p, /**< context */
776811

777812
if (context_p->token.type == LEXER_LITERAL
778813
&& (context_p->token.lit_location.type == LEXER_IDENT_LITERAL
814+
|| context_p->token.lit_location.type == LEXER_STRING_LITERAL
779815
|| context_p->token.lit_location.type == LEXER_NUMBER_LITERAL))
780816
{
781817
lexer_next_token (context_p);
@@ -826,6 +862,15 @@ parser_scan_until (parser_context_t *context_p, /**< context */
826862

827863
lexer_scan_identifier (context_p, true);
828864

865+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
866+
if (context_p->token.type == LEXER_LEFT_SQUARE)
867+
{
868+
parser_stack_push_uint8 (context_p, SCAN_STACK_COMPUTED_PROPERTY);
869+
mode = SCAN_MODE_PRIMARY_EXPRESSION;
870+
break;
871+
}
872+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
873+
829874
if (context_p->token.type == LEXER_RIGHT_BRACE)
830875
{
831876
parser_stack_pop_uint8 (context_p);
@@ -836,9 +881,26 @@ parser_scan_until (parser_context_t *context_p, /**< context */
836881
if (context_p->token.type == LEXER_PROPERTY_GETTER
837882
|| context_p->token.type == LEXER_PROPERTY_SETTER)
838883
{
884+
lexer_next_token (context_p);
885+
839886
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
887+
888+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
889+
if (context_p->token.type == LEXER_LEFT_SQUARE)
890+
{
891+
parser_stack_push_uint8 (context_p, SCAN_STACK_COMPUTED_PROPERTY);
892+
mode = SCAN_MODE_PRIMARY_EXPRESSION;
893+
break;
894+
}
895+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
896+
897+
if (context_p->token.type != LEXER_LITERAL)
898+
{
899+
parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
900+
}
901+
840902
mode = SCAN_MODE_FUNCTION_ARGUMENTS;
841-
break;
903+
continue;
842904
}
843905

844906
lexer_next_token (context_p);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
function member_str() {
16+
return "member";
17+
}
18+
19+
switch (true) {
20+
default:
21+
var obj = {
22+
["val" + "ue"]: 0,
23+
set[member_str()](x) {
24+
// Multiple statements.
25+
this.value = x + 4;
26+
this.value += 2;
27+
},
28+
get[member_str() ? member_str() : ""]() {
29+
// Multiple statements.
30+
this.value = this.value + 1;
31+
return this.value;
32+
},
33+
get
34+
[1 + 2]
35+
()
36+
{
37+
return 3;
38+
},
39+
[false ? member_str()
40+
: ""]
41+
:8
42+
}
43+
}
44+
45+
obj["member"] = 10;
46+
assert(obj.member === 17);
47+
assert(obj.member === 18);
48+
49+
assert(obj[3] === 3);
50+
assert(obj["3"] === 3);
51+
52+
assert(obj[""] === 8);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
switch (true) {
16+
default:
17+
var obj = {
18+
value: 0,
19+
set
20+
member
21+
(x)
22+
{
23+
// Multiple statements.
24+
this.value = x + 4;
25+
this.value += 2;
26+
},
27+
get"member"() {
28+
// Multiple statements.
29+
this.value = this.value + 1;
30+
return this.value;
31+
},
32+
get 3() {
33+
return 3;
34+
}
35+
}
36+
}
37+
38+
obj["member"] = 10;
39+
assert(obj.member === 17);
40+
assert(obj.member === 18);
41+
42+
assert(obj[3] === 3);
43+
assert(obj["3"] === 3);

0 commit comments

Comments
 (0)