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
This commit is contained in:
@@ -364,6 +364,22 @@ parser_append_object_literal_item (parser_context_t *context_p, /**< context */
|
|||||||
#error "Class support requires ES2015 object literal support"
|
#error "Class support requires ES2015 object literal support"
|
||||||
#endif /* !ENABLED (JERRY_ES2015_OBJECT_INITIALIZER) */
|
#endif /* !ENABLED (JERRY_ES2015_OBJECT_INITIALIZER) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of "get" literal string.
|
||||||
|
*/
|
||||||
|
static const lexer_lit_location_t lexer_get_literal =
|
||||||
|
{
|
||||||
|
(const uint8_t *) "get", 3, LEXER_STRING_LITERAL, false
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of "set" literal string.
|
||||||
|
*/
|
||||||
|
static const lexer_lit_location_t lexer_set_literal =
|
||||||
|
{
|
||||||
|
(const uint8_t *) "set", 3, LEXER_STRING_LITERAL, false
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse class as an object literal.
|
* Parse class as an object literal.
|
||||||
*/
|
*/
|
||||||
@@ -390,19 +406,30 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_computed = false;
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
|
if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
|
||||||
{
|
{
|
||||||
uint16_t literal_index, function_literal_index;
|
uint16_t literal_index, function_literal_index;
|
||||||
bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER);
|
bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER);
|
||||||
|
|
||||||
|
lexer_skip_empty_statements (context_p);
|
||||||
|
|
||||||
|
if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
|
||||||
|
{
|
||||||
|
lexer_construct_literal_object (context_p,
|
||||||
|
(is_getter ? (lexer_lit_location_t *) &lexer_get_literal
|
||||||
|
: (lexer_lit_location_t *) &lexer_set_literal),
|
||||||
|
LEXER_STRING_LITERAL);
|
||||||
|
goto parse_class_method;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t accessor_status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE;
|
uint32_t accessor_status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE;
|
||||||
accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER);
|
accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER);
|
||||||
|
|
||||||
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
|
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
|
||||||
literal_index = context_p->lit_object.index;
|
literal_index = context_p->lit_object.index;
|
||||||
|
|
||||||
bool is_computed = false;
|
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_RIGHT_SQUARE)
|
if (context_p->token.type == LEXER_RIGHT_SQUARE)
|
||||||
{
|
{
|
||||||
is_computed = true;
|
is_computed = true;
|
||||||
@@ -499,8 +526,6 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_computed = false;
|
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_RIGHT_SQUARE)
|
if (context_p->token.type == LEXER_RIGHT_SQUARE)
|
||||||
{
|
{
|
||||||
is_computed = true;
|
is_computed = true;
|
||||||
@@ -511,6 +536,7 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
|
|||||||
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
|
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parse_class_method:
|
||||||
parser_flush_cbc (context_p);
|
parser_flush_cbc (context_p);
|
||||||
|
|
||||||
uint16_t literal_index = context_p->lit_object.index;
|
uint16_t literal_index = context_p->lit_object.index;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
class A {
|
||||||
|
// Test skipping spaces
|
||||||
|
get (a, b, c) {
|
||||||
|
return a + b + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test skipping spaces
|
||||||
|
static get(a, b, c) {
|
||||||
|
return a - b - c;
|
||||||
|
}
|
||||||
|
|
||||||
|
set (a, b) {
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static set (a, b) {
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(A.get(1, 2, 3) === -4);
|
||||||
|
assert(A.set(2, 1) === 2);
|
||||||
|
|
||||||
|
var a = new A;
|
||||||
|
|
||||||
|
assert(a.get(1, 2, 3) === 6);
|
||||||
|
assert(a.set(2, 2) === 4);
|
||||||
Reference in New Issue
Block a user