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:
Robert Fancsik 2019-07-16 13:52:05 +02:00 committed by GitHub
parent 6bd7d70a69
commit 2700e66c4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 4 deletions

View File

@ -364,6 +364,22 @@ parser_append_object_literal_item (parser_context_t *context_p, /**< context */
#error "Class support requires ES2015 object literal support"
#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.
*/
@ -390,19 +406,30 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
break;
}
bool is_computed = false;
if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
{
uint16_t literal_index, function_literal_index;
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;
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);
literal_index = context_p->lit_object.index;
bool is_computed = false;
if (context_p->token.type == LEXER_RIGHT_SQUARE)
{
is_computed = true;
@ -499,8 +526,6 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
continue;
}
bool is_computed = false;
if (context_p->token.type == LEXER_RIGHT_SQUARE)
{
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);
}
parse_class_method:
parser_flush_cbc (context_p);
uint16_t literal_index = context_p->lit_object.index;

View File

@ -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);