[njs] Filtering out integer indices in njs_object_completions().

Dmitry Volyntsev xeioex at nginx.com
Mon Feb 10 16:02:01 UTC 2020


details:   https://hg.nginx.org/njs/rev/5bd15bd3766c
branches:  
changeset: 1324:5bd15bd3766c
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Feb 10 17:39:41 2020 +0300
description:
Filtering out integer indices in njs_object_completions().

This closes #285 issue on Github.

diffstat:

 src/njs_builtin.c        |  123 +++++++++++++---------------------------------
 test/njs_expect_test.exp |   21 ++++++++
 2 files changed, 57 insertions(+), 87 deletions(-)

diffs (189 lines):

diff -r 79c14715edc2 -r 5bd15bd3766c src/njs_builtin.c
--- a/src/njs_builtin.c	Mon Feb 10 17:09:53 2020 +0300
+++ b/src/njs_builtin.c	Mon Feb 10 17:39:41 2020 +0300
@@ -24,7 +24,7 @@ typedef struct {
 
 static njs_arr_t *njs_vm_expression_completions(njs_vm_t *vm,
     njs_str_t *expression);
-static njs_arr_t *njs_object_completions(njs_vm_t *vm, njs_object_t *object);
+static njs_arr_t *njs_object_completions(njs_vm_t *vm, njs_value_t *object);
 static njs_int_t njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash,
     char **environment);
 
@@ -633,110 +633,59 @@ njs_vm_expression_completions(njs_vm_t *
         value = &prop->value;
     }
 
-    return njs_object_completions(vm, njs_object(value));
+    return njs_object_completions(vm, value);
 }
 
 
 static njs_arr_t *
-njs_object_completions(njs_vm_t *vm, njs_object_t *object)
+njs_object_completions(njs_vm_t *vm, njs_value_t *object)
 {
-    size_t             size;
-    njs_str_t          *compl;
-    njs_arr_t          *completions;
-    njs_uint_t         n, k;
-    njs_object_t       *o;
-    njs_object_prop_t  *prop;
-    njs_lvlhsh_each_t  lhe;
-
-    size = 0;
-    o = object;
-
-    do {
-        njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
-
-        for ( ;; ) {
-            prop = njs_lvlhsh_each(&o->hash, &lhe);
-            if (prop == NULL) {
-                break;
-            }
+    double            num;
+    njs_arr_t         *array;
+    njs_str_t         *completion;
+    njs_uint_t        n;
+    njs_array_t       *keys;
+    njs_value_type_t  type;
 
-            size++;
-        }
-
-        njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
-
-        for ( ;; ) {
-            prop = njs_lvlhsh_each(&o->shared_hash, &lhe);
-            if (prop == NULL) {
-                break;
-            }
+    array = NULL;
+    type = object->type;
 
-            size++;
-        }
-
-        o = o->__proto__;
+    if (type == NJS_ARRAY || type == NJS_TYPED_ARRAY) {
+        object->type = NJS_OBJECT;
+    }
 
-    } while (o != NULL);
-
-    completions = njs_arr_create(vm->mem_pool, size, sizeof(njs_str_t));
-    if (njs_slow_path(completions == NULL)) {
-        return NULL;
+    keys = njs_value_enumerate(vm, object, NJS_ENUM_KEYS, NJS_ENUM_STRING, 1);
+    if (njs_slow_path(keys == NULL)) {
+        goto done;
     }
 
-    n = 0;
-    o = object;
-    compl = completions->start;
-
-    do {
-        njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    array = njs_arr_create(vm->mem_pool, 8, sizeof(njs_str_t));
+    if (njs_slow_path(array == NULL)) {
+        goto done;
+    }
 
-        for ( ;; ) {
-            prop = njs_lvlhsh_each(&o->hash, &lhe);
-            if (prop == NULL) {
-                break;
-            }
+    for (n = 0; n < keys->length; n++) {
+        num = njs_key_to_index(&keys->start[n]);
 
-            njs_string_get(&prop->name, &compl[n]);
-
-            for (k = 0; k < n; k++) {
-                if (njs_strstr_eq(&compl[k], &compl[n])) {
-                    break;
-                }
+        if (!njs_key_is_integer_index(num, &keys->start[n])) {
+            completion = njs_arr_add(array);
+            if (njs_slow_path(completion == NULL)) {
+                njs_arr_destroy(array);
+                array = NULL;
+                goto done;
             }
 
-            if (k == n) {
-                n++;
-            }
+            njs_string_get(&keys->start[n], completion);
         }
-
-        njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    }
 
-        for ( ;; ) {
-            prop = njs_lvlhsh_each(&o->shared_hash, &lhe);
-            if (prop == NULL) {
-                break;
-            }
-
-            njs_string_get(&prop->name, &compl[n]);
+done:
 
-            for (k = 0; k < n; k++) {
-                if (njs_strstr_eq(&compl[k], &compl[n])) {
-                    break;
-                }
-            }
+    if (type == NJS_ARRAY || type == NJS_TYPED_ARRAY) {
+        object->type = type;
+    }
 
-            if (k == n) {
-                n++;
-            }
-        }
-
-        o = o->__proto__;
-
-    } while (o != NULL);
-
-    completions->items = n;
-
-    return completions;
+    return array;
 }
 
 
diff -r 79c14715edc2 -r 5bd15bd3766c test/njs_expect_test.exp
--- a/test/njs_expect_test.exp	Mon Feb 10 17:09:53 2020 +0300
+++ b/test/njs_expect_test.exp	Mon Feb 10 17:39:41 2020 +0300
@@ -192,6 +192,27 @@ njs_test {
      "o.a.toDateString*o.a.toLocaleDateString*o.a.toString"}
 }
 
+njs_test {
+    {"var o = {a:1,b:2,333:'t'}\r\n"
+     "var o = {a:1,b:2,333:'t'}\r\nundefined\r\n>> "}
+    {"o.3\t\t"
+     "o.3"}
+}
+
+njs_test {
+    {"var a = Array(5000000); a.aab = 1; a.aac = 2\r\n"
+     "var a = Array(5000000); a.aab = 1; a.aac = 2\r\n2\r\n>> "}
+    {"a.\t\t"
+     "a.aab*"}
+}
+
+njs_test {
+    {"var a = new Uint8Array([5,6,7,8,8]); a.aab = 1; a.aac = 2\r\n"
+     "var a = new Uint8Array(\\\[5,6,7,8,8]); a.aab = 1; a.aac = 2\r\n2\r\n>> "}
+    {"a.\t\t"
+     "a.aab*"}
+}
+
 # function declarations in interactive mode
 njs_test {
     {"function a() { return 1; }\r\n"


More information about the nginx-devel mailing list