[njs] Added Object shorthand methods and computed property names.
Dmitry Volyntsev
xeioex at nginx.com
Fri Jul 19 21:31:14 UTC 2019
details: https://hg.nginx.org/njs/rev/97ab91a7c7f5
branches:
changeset: 1064:97ab91a7c7f5
user: hongzhidao <hongzhidao at gmail.com>
date: Tue Jul 02 22:24:11 2019 -0400
description:
Added Object shorthand methods and computed property names.
This closes #182 issue on Github.
diffstat:
njs/njs_parser.c | 4 +--
njs/njs_parser.h | 2 +
njs/njs_parser_terminal.c | 57 ++++++++++++++++++++++++++++++++++++++++++----
njs/njs_vm.c | 5 +---
njs/test/njs_unit_test.c | 36 ++++++++++++++++++++++++++++-
5 files changed, 89 insertions(+), 15 deletions(-)
diffs (190 lines):
diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_parser.c
--- a/njs/njs_parser.c Fri Jul 19 23:27:53 2019 +0300
+++ b/njs/njs_parser.c Tue Jul 02 22:24:11 2019 -0400
@@ -24,8 +24,6 @@ static njs_token_t njs_parser_labelled_s
njs_parser_t *parser);
static njs_token_t njs_parser_function_declaration(njs_vm_t *vm,
njs_parser_t *parser);
-static njs_token_t njs_parser_function_lambda(njs_vm_t *vm,
- njs_parser_t *parser, njs_function_lambda_t *lambda, njs_token_t token);
static njs_token_t njs_parser_lambda_arguments(njs_vm_t *vm,
njs_parser_t *parser, njs_function_lambda_t *lambda, njs_index_t index,
njs_token_t token);
@@ -757,7 +755,7 @@ njs_parser_function_expression(njs_vm_t
}
-static njs_token_t
+njs_token_t
njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser,
njs_function_lambda_t *lambda, njs_token_t token)
{
diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_parser.h
--- a/njs/njs_parser.h Fri Jul 19 23:27:53 2019 +0300
+++ b/njs/njs_parser.h Tue Jul 02 22:24:11 2019 -0400
@@ -95,6 +95,8 @@ njs_token_t njs_parser_template_literal(
njs_parser_node_t *njs_parser_argument(njs_vm_t *vm, njs_parser_t *parser,
njs_parser_node_t *expr, njs_index_t index);
nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value);
+njs_token_t njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser,
+ njs_function_lambda_t *lambda, njs_token_t token);
njs_token_t njs_parser_lambda_statements(njs_vm_t *vm, njs_parser_t *parser,
njs_token_t token);
njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node);
diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_parser_terminal.c
--- a/njs/njs_parser_terminal.c Fri Jul 19 23:27:53 2019 +0300
+++ b/njs/njs_parser_terminal.c Tue Jul 02 22:24:11 2019 -0400
@@ -480,12 +480,13 @@ njs_parser_builtin(njs_vm_t *vm, njs_par
static njs_token_t
njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj)
{
- uint32_t hash, token_line;
- nxt_int_t ret;
- nxt_str_t name;
- njs_token_t token, prop_token;
- njs_lexer_t *lexer;
- njs_parser_node_t *object, *property, *expression;
+ uint32_t hash, token_line;
+ nxt_int_t ret;
+ nxt_str_t name;
+ njs_token_t token, prop_token;
+ njs_lexer_t *lexer;
+ njs_parser_node_t *object, *property, *expression;
+ njs_function_lambda_t *lambda;
lexer = parser->lexer;
@@ -513,6 +514,26 @@ njs_parser_object(njs_vm_t *vm, njs_pars
case NJS_TOKEN_CLOSE_BRACE:
goto done;
+ case NJS_TOKEN_OPEN_BRACKET:
+ token = njs_parser_token(vm, parser);
+ if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+ return token;
+ }
+
+ if (token == NJS_TOKEN_CLOSE_BRACKET) {
+ return NJS_TOKEN_ILLEGAL;
+ }
+
+ token = njs_parser_assignment_expression(vm, parser, token);
+ if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+ return token;
+ }
+
+ property = parser->node;
+
+ token = njs_parser_match(vm, parser, token, NJS_TOKEN_CLOSE_BRACKET);
+ break;
+
case NJS_TOKEN_NUMBER:
case NJS_TOKEN_STRING:
case NJS_TOKEN_ESCAPE_STRING:
@@ -576,6 +597,30 @@ njs_parser_object(njs_vm_t *vm, njs_pars
expression = parser->node;
break;
+ case NJS_TOKEN_OPEN_PARENTHESIS:
+ expression = njs_parser_node_new(vm, parser,
+ NJS_TOKEN_FUNCTION_EXPRESSION);
+ if (nxt_slow_path(expression == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
+ expression->token_line = njs_parser_token_line(parser);
+ parser->node = expression;
+
+ lambda = njs_function_lambda_alloc(vm, 0);
+ if (nxt_slow_path(lambda == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
+ expression->u.value.data.u.lambda = lambda;
+
+ token = njs_parser_function_lambda(vm, parser, lambda, token);
+ if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+ return token;
+ }
+
+ break;
+
default:
return NJS_TOKEN_ILLEGAL;
}
diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/njs_vm.c
--- a/njs/njs_vm.c Fri Jul 19 23:27:53 2019 +0300
+++ b/njs/njs_vm.c Tue Jul 02 22:24:11 2019 -0400
@@ -478,11 +478,8 @@ njs_vmcode_property_init(njs_vm_t *vm, n
break;
case NJS_OBJECT:
- ret = njs_primitive_value_to_string(vm, &name, property);
+ ret = njs_value_to_string(vm, &name, property);
if (nxt_slow_path(ret != NXT_OK)) {
- njs_internal_error(vm, "failed conversion of type \"%s\" "
- "to string while property initialization",
- njs_type_string(property->type));
return NXT_ERROR;
}
diff -r 9da8ebc3dc07 -r 97ab91a7c7f5 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Fri Jul 19 23:27:53 2019 +0300
+++ b/njs/test/njs_unit_test.c Tue Jul 02 22:24:11 2019 -0400
@@ -3126,7 +3126,7 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("var x = { a: 1 }, b = delete x.a; x.a +' '+ b"),
nxt_string("undefined true") },
- /* Shorthand Object literals. */
+ /* Object shorthand property. */
{ nxt_string("var a = 1; njs.dump({a})"),
nxt_string("{a:1}") },
@@ -3173,6 +3173,38 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("delete undefined"),
nxt_string("SyntaxError: Delete of an unqualified identifier in 1") },
+ /* Object shorthand methods. */
+
+ { nxt_string("var o = {m(){}}; new o.m();"),
+ nxt_string("TypeError: function is not a constructor") },
+
+ { nxt_string("var o = {sum(a, b){return a + b;}}; o.sum(1, 2)"),
+ nxt_string("3") },
+
+ /* Object computed property. */
+
+ { nxt_string("var o = { [0]: 1, [-0]: 2 }; o[0];"),
+ nxt_string("2") },
+
+ { nxt_string("var k = 'abc'.split('');var o = {[k[0]]: 'baz'}; o.a"),
+ nxt_string("baz") },
+
+ { nxt_string("var k = {}; var o = {[k]() {return 'baz'}}; o[k]()"),
+ nxt_string("baz") },
+
+ { nxt_string("njs.dump({[{toString(){return 'xx'}}]:1})"),
+ nxt_string("{xx:1}") },
+
+ { nxt_string("var o = {}; Object.defineProperty(o, 'toString', {value:()=>'xx'});"
+ "njs.dump({[o]:1})"),
+ nxt_string("{xx:1}") },
+
+ { nxt_string("({[{toString(){return {}}}]:1})"),
+ nxt_string("TypeError: Cannot convert object to primitive value") },
+
+ { nxt_string("var o = { [new Number(12345)]: 1000 }; o[12345]"),
+ nxt_string("1000") },
+
/* ES5FIX: "SyntaxError". */
{ nxt_string("delete NaN"),
@@ -3248,7 +3280,7 @@ static njs_unit_test_t njs_test[] =
nxt_string("4") },
{ nxt_string("({[]:1})"),
- nxt_string("SyntaxError: Unexpected token \"[\" in 1") },
+ nxt_string("SyntaxError: Unexpected token \"]\" in 1") },
{ nxt_string("({'AB\\ncd':1})['AB\\ncd']"),
nxt_string("1") },
More information about the nginx-devel
mailing list