Fixes for ES2015 classes. (#2424)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
committed by
Robert Sipka
parent
0ca04376a5
commit
f86d7459d1
@@ -286,9 +286,10 @@ lexer_skip_empty_statements (parser_context_t *context_p) /**< context */
|
||||
{
|
||||
lexer_skip_spaces (context_p);
|
||||
|
||||
while (*context_p->source_p == LIT_CHAR_SEMICOLON)
|
||||
while (context_p->source_p < context_p->source_end_p
|
||||
&& *context_p->source_p == LIT_CHAR_SEMICOLON)
|
||||
{
|
||||
lexer_next_token (context_p);
|
||||
context_p->source_p++;
|
||||
lexer_skip_spaces (context_p);
|
||||
}
|
||||
} /* lexer_skip_empty_statements */
|
||||
@@ -2268,7 +2269,9 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
|
||||
lexer_skip_spaces (context_p);
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
bool is_static_method = (context_p->token.type == LEXER_KEYW_STATIC);
|
||||
int is_class_method = ((context_p->status_flags & PARSER_IS_CLASS)
|
||||
&& !must_be_identifier
|
||||
&& (context_p->token.type != LEXER_KEYW_STATIC));
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
|
||||
context_p->token.line = context_p->line;
|
||||
@@ -2302,11 +2305,9 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
if ((context_p->status_flags & PARSER_IS_CLASS)
|
||||
&& !must_be_identifier
|
||||
&& !is_static_method
|
||||
&& context_p->token.lit_location.length == 6
|
||||
if (is_class_method
|
||||
&& lexer_compare_raw_identifier_to_current (context_p, "static", 6))
|
||||
{
|
||||
context_p->token.type = LEXER_KEYW_STATIC;
|
||||
@@ -2349,9 +2350,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
if ((context_p->status_flags & PARSER_IS_CLASS)
|
||||
&& !must_be_identifier
|
||||
&& !is_static_method
|
||||
if (is_class_method
|
||||
&& lexer_compare_raw_identifier_to_current (context_p, "constructor", 11))
|
||||
{
|
||||
context_p->token.type = LEXER_CLASS_CONSTRUCTOR;
|
||||
@@ -2431,28 +2430,28 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
|
||||
*/
|
||||
bool
|
||||
lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context */
|
||||
const lexer_lit_location_t *right) /**< identifier */
|
||||
const lexer_lit_location_t *right_ident_p) /**< identifier */
|
||||
{
|
||||
lexer_lit_location_t *left = &context_p->token.lit_location;
|
||||
lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
|
||||
const uint8_t *left_p;
|
||||
const uint8_t *right_p;
|
||||
size_t count;
|
||||
|
||||
JERRY_ASSERT (left->length > 0 && right->length > 0);
|
||||
JERRY_ASSERT (left_ident_p->length > 0 && right_ident_p->length > 0);
|
||||
|
||||
if (left->length != right->length)
|
||||
if (left_ident_p->length != right_ident_p->length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!left->has_escape && !right->has_escape)
|
||||
if (!left_ident_p->has_escape && !right_ident_p->has_escape)
|
||||
{
|
||||
return memcmp (left->char_p, right->char_p, left->length) == 0;
|
||||
return memcmp (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length) == 0;
|
||||
}
|
||||
|
||||
left_p = left->char_p;
|
||||
right_p = right->char_p;
|
||||
count = left->length;
|
||||
left_p = left_ident_p->char_p;
|
||||
right_p = right_ident_p->char_p;
|
||||
count = left_ident_p->length;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -2529,14 +2528,14 @@ lexer_compare_raw_identifier_to_current (parser_context_t *context_p, /**< conte
|
||||
const char *right_ident_p, /**< identifier */
|
||||
size_t right_ident_length) /**< identifier length */
|
||||
{
|
||||
lexer_lit_location_t *left = &context_p->token.lit_location;
|
||||
lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
|
||||
|
||||
if (left->length != right_ident_length || left->has_escape)
|
||||
if (left_ident_p->length != right_ident_length || left_ident_p->has_escape)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return memcmp (left->char_p, right_ident_p, right_ident_length) == 0;
|
||||
return memcmp (left_ident_p->char_p, right_ident_p, right_ident_length) == 0;
|
||||
} /* lexer_compare_raw_identifier_to_current */
|
||||
|
||||
/**
|
||||
|
||||
@@ -429,7 +429,7 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */
|
||||
if (constructor_literal_p->type == LEXER_FUNCTION_LITERAL)
|
||||
{
|
||||
/* 14.5.1 */
|
||||
parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTOR);
|
||||
parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS);
|
||||
}
|
||||
|
||||
parser_flush_cbc (context_p);
|
||||
@@ -445,7 +445,7 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
if (is_static && lexer_compare_raw_identifier_to_current (context_p, "prototype", 9))
|
||||
{
|
||||
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROPERTY_NAME_PROTOTYPE);
|
||||
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
|
||||
}
|
||||
|
||||
if (!lexer_check_left_paren (context_p))
|
||||
@@ -1102,13 +1102,6 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
|
||||
PARSER_IS_FUNCTION | PARSER_IS_FUNC_EXPRESSION | PARSER_IS_CLOSURE);
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
case LEXER_KEYW_CLASS:
|
||||
{
|
||||
parser_parse_class (context_p, false);
|
||||
return;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
case LEXER_LEFT_BRACE:
|
||||
{
|
||||
parser_parse_object_literal (context_p);
|
||||
@@ -1165,6 +1158,13 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
|
||||
parser_emit_cbc (context_p, CBC_PUSH_NULL);
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
case LEXER_KEYW_CLASS:
|
||||
{
|
||||
parser_parse_class (context_p, false);
|
||||
return;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||
case LEXER_RIGHT_PAREN:
|
||||
{
|
||||
|
||||
@@ -454,7 +454,7 @@ bool lexer_construct_number_object (parser_context_t *context_p, bool is_expr, b
|
||||
void lexer_convert_push_number_to_push_literal (parser_context_t *context_p);
|
||||
uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags);
|
||||
void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only);
|
||||
bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right);
|
||||
bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right_ident_p);
|
||||
bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const char *right_ident_p,
|
||||
size_t right_ident_length);
|
||||
|
||||
@@ -468,6 +468,9 @@ bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const
|
||||
/* Parser functions. */
|
||||
|
||||
void parser_parse_expression (parser_context_t *context_p, int options);
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
void parser_parse_class (parser_context_t *context_p, bool is_statement);
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
@@ -486,9 +489,6 @@ void parser_scan_until (parser_context_t *context_p, lexer_range_t *range_p, lex
|
||||
*/
|
||||
|
||||
void parser_parse_statements (parser_context_t *context_p);
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
void parser_parse_class (parser_context_t *context_p, bool is_statement);
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
void parser_free_jumps (parser_stack_iterator_t iterator);
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,15 +41,15 @@ typedef enum
|
||||
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||
SCAN_MODE_ARROW_FUNCTION, /**< arrow function might follows */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
SCAN_MODE_CLASS_DECLARATION, /**< scanning class declaration */
|
||||
SCAN_MODE_CLASS_METHOD, /**< scanning class method */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
SCAN_MODE_POST_PRIMARY_EXPRESSION, /**< scanning post primary expression */
|
||||
SCAN_MODE_PRIMARY_EXPRESSION_END, /**< scanning primary expression end */
|
||||
SCAN_MODE_STATEMENT, /**< scanning statement */
|
||||
SCAN_MODE_FUNCTION_ARGUMENTS, /**< scanning function arguments */
|
||||
SCAN_MODE_PROPERTY_NAME, /**< scanning property name */
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
SCAN_MODE_CLASS_DECLARATION, /**< scanning class declaration */
|
||||
SCAN_MODE_CLASS_METHOD, /**< scanning class method */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
} scan_modes_t;
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ typedef enum
|
||||
SCAN_STACK_TEMPLATE_STRING, /**< template string */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
SCAN_STACK_CLASS, /**< class language element */
|
||||
SCAN_STACK_CLASS, /**< class language element */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
} scan_stack_modes_t;
|
||||
|
||||
@@ -106,14 +106,6 @@ parser_scan_primary_expression (parser_context_t *context_p, /**< context */
|
||||
*mode = SCAN_MODE_FUNCTION_ARGUMENTS;
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
case LEXER_KEYW_CLASS:
|
||||
{
|
||||
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION);
|
||||
*mode = SCAN_MODE_CLASS_DECLARATION;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
case LEXER_LEFT_PAREN:
|
||||
{
|
||||
parser_stack_push_uint8 (context_p, SCAN_STACK_PAREN_EXPRESSION);
|
||||
@@ -164,6 +156,14 @@ parser_scan_primary_expression (parser_context_t *context_p, /**< context */
|
||||
*mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
case LEXER_KEYW_CLASS:
|
||||
{
|
||||
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION);
|
||||
*mode = SCAN_MODE_CLASS_DECLARATION;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
case LEXER_RIGHT_SQUARE:
|
||||
{
|
||||
if (stack_top != SCAN_STACK_SQUARE_BRACKETED_EXPRESSION)
|
||||
@@ -512,7 +512,7 @@ parser_scan_statement (parser_context_t *context_p, /**< context */
|
||||
*mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
if (stack_top == SCAN_STACK_CLASS)
|
||||
else if (stack_top == SCAN_STACK_CLASS)
|
||||
{
|
||||
*mode = SCAN_MODE_CLASS_METHOD;
|
||||
}
|
||||
@@ -767,7 +767,7 @@ parser_scan_until (parser_context_t *context_p, /**< context */
|
||||
|| stack_top == SCAN_STACK_BLOCK_EXPRESSION
|
||||
|| stack_top == SCAN_STACK_CLASS
|
||||
|| stack_top == SCAN_STACK_BLOCK_PROPERTY);
|
||||
#else
|
||||
#else /* CONFIG_DISABLE_ES2015_CLASS */
|
||||
JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT
|
||||
|| stack_top == SCAN_STACK_BLOCK_EXPRESSION
|
||||
|| stack_top == SCAN_STACK_BLOCK_PROPERTY);
|
||||
|
||||
@@ -898,6 +898,20 @@ parser_error_to_string (parser_error_t error) /**< error code */
|
||||
{
|
||||
return "Case statement must be in a switch block.";
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS:
|
||||
{
|
||||
return "Multiple constructors are not allowed.";
|
||||
}
|
||||
case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR:
|
||||
{
|
||||
return "Class constructor may not be an accessor.";
|
||||
}
|
||||
case PARSER_ERR_CLASS_STATIC_PROTOTYPE:
|
||||
{
|
||||
return "Classes may not have a static property called 'prototype'.";
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
case PARSER_ERR_LEFT_PAREN_EXPECTED:
|
||||
{
|
||||
return "Expected '(' token.";
|
||||
@@ -920,20 +934,6 @@ parser_error_to_string (parser_error_t error) /**< error code */
|
||||
return "Expected '}' token.";
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTOR:
|
||||
{
|
||||
return "Multiple constructors are not allowed.";
|
||||
}
|
||||
case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR:
|
||||
{
|
||||
return "Class constructor may not be an accessor.";
|
||||
}
|
||||
case PARSER_ERR_CLASS_STATIC_PROPERTY_NAME_PROTOTYPE:
|
||||
{
|
||||
return "Classes may not have a static property called 'prototype'.";
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
case PARSER_ERR_COLON_EXPECTED:
|
||||
{
|
||||
return "Expected ':' token.";
|
||||
|
||||
@@ -2541,8 +2541,7 @@ parser_parse_function (parser_context_t *context_p, /**< context */
|
||||
bool is_constructor = context_p->status_flags & PARSER_CLASS_CONSTRUCTOR;
|
||||
JERRY_DEBUG_MSG (is_constructor ? "\n--- Class constructor parsing start ---\n\n"
|
||||
: "\n--- Function parsing start ---\n\n");
|
||||
|
||||
#else
|
||||
#else /* CONFIG_DISABLE_ES2015_CLASS */
|
||||
JERRY_DEBUG_MSG ("\n--- Function parsing start ---\n\n");
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
}
|
||||
@@ -2646,7 +2645,7 @@ parser_parse_function (parser_context_t *context_p, /**< context */
|
||||
bool is_constructor = context_p->status_flags & PARSER_CLASS_CONSTRUCTOR;
|
||||
JERRY_DEBUG_MSG (is_constructor ? "\n--- Class constructor parsing end ---\n\n"
|
||||
: "\n--- Function parsing end ---\n\n");
|
||||
#else
|
||||
#else /* CONFIG_DISABLE_ES2015_CLASS */
|
||||
JERRY_DEBUG_MSG ("\n--- Function parsing end ---\n\n");
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
}
|
||||
|
||||
@@ -79,6 +79,11 @@ typedef enum
|
||||
PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED, /**< multiple default cases are not allowed */
|
||||
PARSER_ERR_DEFAULT_NOT_IN_SWITCH, /**< default statement is not in switch block */
|
||||
PARSER_ERR_CASE_NOT_IN_SWITCH, /**< case statement is not in switch block */
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS, /**< multiple class constructor */
|
||||
PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR, /**< class constructor cannot be an accessor */
|
||||
PARSER_ERR_CLASS_STATIC_PROTOTYPE, /**< static method name 'prototype' is not allowed */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
|
||||
PARSER_ERR_LEFT_PAREN_EXPECTED, /**< left paren expected */
|
||||
PARSER_ERR_LEFT_BRACE_EXPECTED, /**< left brace expected */
|
||||
@@ -87,11 +92,6 @@ typedef enum
|
||||
#ifndef CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
|
||||
PARSER_ERR_RIGHT_BRACE_EXPECTED, /**< right brace expected */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
|
||||
#ifndef CONFIG_DISABLE_ES2015_CLASS
|
||||
PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTOR, /**< multiple class constructor */
|
||||
PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR, /**< class constructor cannot be an accessor */
|
||||
PARSER_ERR_CLASS_STATIC_PROPERTY_NAME_PROTOTYPE, /**< static method name 'prototype' is not allowed */
|
||||
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
|
||||
PARSER_ERR_COLON_EXPECTED, /**< colon expected */
|
||||
PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED, /**< colon expected for conditional expression */
|
||||
PARSER_ERR_SEMICOLON_EXPECTED, /**< semicolon expected */
|
||||
|
||||
Reference in New Issue
Block a user