Skip to content

Commit 2700e66

Browse files
authored
Improve class literal parsing (#2970)
Until now "get"/"set" were always parsed as special 'keywords' for accessor methods, but they should be parsed as simple class method if no identifier is followed by them. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
1 parent 6bd7d70 commit 2700e66

2 files changed

Lines changed: 72 additions & 4 deletions

File tree

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

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,22 @@ parser_append_object_literal_item (parser_context_t *context_p, /**< context */
364364
#error "Class support requires ES2015 object literal support"
365365
#endif /* !ENABLED (JERRY_ES2015_OBJECT_INITIALIZER) */
366366

367+
/**
368+
* Description of "get" literal string.
369+
*/
370+
static const lexer_lit_location_t lexer_get_literal =
371+
{
372+
(const uint8_t *) "get", 3, LEXER_STRING_LITERAL, false
373+
};
374+
375+
/**
376+
* Description of "set" literal string.
377+
*/
378+
static const lexer_lit_location_t lexer_set_literal =
379+
{
380+
(const uint8_t *) "set", 3, LEXER_STRING_LITERAL, false
381+
};
382+
367383
/**
368384
* Parse class as an object literal.
369385
*/
@@ -390,19 +406,30 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
390406
break;
391407
}
392408

409+
bool is_computed = false;
410+
393411
if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
394412
{
395413
uint16_t literal_index, function_literal_index;
396414
bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER);
397415

416+
lexer_skip_empty_statements (context_p);
417+
418+
if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
419+
{
420+
lexer_construct_literal_object (context_p,
421+
(is_getter ? (lexer_lit_location_t *) &lexer_get_literal
422+
: (lexer_lit_location_t *) &lexer_set_literal),
423+
LEXER_STRING_LITERAL);
424+
goto parse_class_method;
425+
}
426+
398427
uint32_t accessor_status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE;
399428
accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER);
400429

401430
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
402431
literal_index = context_p->lit_object.index;
403432

404-
bool is_computed = false;
405-
406433
if (context_p->token.type == LEXER_RIGHT_SQUARE)
407434
{
408435
is_computed = true;
@@ -499,8 +526,6 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
499526
continue;
500527
}
501528

502-
bool is_computed = false;
503-
504529
if (context_p->token.type == LEXER_RIGHT_SQUARE)
505530
{
506531
is_computed = true;
@@ -511,6 +536,7 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
511536
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
512537
}
513538

539+
parse_class_method:
514540
parser_flush_cbc (context_p);
515541

516542
uint16_t literal_index = context_p->lit_object.index;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
16+
class A {
17+
// Test skipping spaces
18+
get (a, b, c) {
19+
return a + b + c;
20+
}
21+
22+
// Test skipping spaces
23+
static get(a, b, c) {
24+
return a - b - c;
25+
}
26+
27+
set (a, b) {
28+
return a * b;
29+
}
30+
31+
static set (a, b) {
32+
return a / b;
33+
}
34+
}
35+
36+
assert(A.get(1, 2, 3) === -4);
37+
assert(A.set(2, 1) === 2);
38+
39+
var a = new A;
40+
41+
assert(a.get(1, 2, 3) === 6);
42+
assert(a.set(2, 2) === 4);

0 commit comments

Comments
 (0)