]> git.kaiwu.me - njs.git/commitdiff
Added Object shorthand methods and computed property names.
authorhongzhidao <hongzhidao@gmail.com>
Wed, 3 Jul 2019 02:24:11 +0000 (22:24 -0400)
committerhongzhidao <hongzhidao@gmail.com>
Wed, 3 Jul 2019 02:24:11 +0000 (22:24 -0400)
This closes #182 issue on Github.

njs/njs_parser.c
njs/njs_parser.h
njs/njs_parser_terminal.c
njs/njs_vm.c
njs/test/njs_unit_test.c

index 1f86dbc8501130683f9b05c83a2e363c1f8383e6..eaaa4299ea18ba09e06756ee851dfa72b588f2d6 100644 (file)
@@ -24,8 +24,6 @@ static njs_token_t njs_parser_labelled_statement(njs_vm_t *vm,
     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 *vm, njs_parser_t *parser)
 }
 
 
-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)
 {
index b4677a8b46014addabdad201255febe31757f080..e754d6d5d90c9557a76ffdc0783cb27ce93efc56 100644 (file)
@@ -95,6 +95,8 @@ njs_token_t njs_parser_template_literal(njs_vm_t *vm, njs_parser_t *parser,
 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);
index b25cdfc834a888939729990dafb1f6aa4f0323f6..37b87d2af512e64b1fb7cde32654be6240e4184a 100644 (file)
@@ -480,12 +480,13 @@ njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node,
 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_parser_t *parser, njs_parser_node_t *obj)
         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_parser_t *parser, njs_parser_node_t *obj)
             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;
         }
index c47be87c63726f4766d4c08c58504eb85eccef67..cb1979b9aeb3076eeacc876df9eaf9172ea5b69d 100644 (file)
@@ -478,11 +478,8 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *object,
         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;
         }
 
index 1caac8b8b128af49847d47467634fdad2969a989..9b922bd4cef184396820452b7d2f73394fbb236f 100644 (file)
@@ -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") },