emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 7fe7165 053/110: Fix array destructuring including triple-


From: Dmitry Gutov
Subject: [elpa] master 7fe7165 053/110: Fix array destructuring including triple-dot
Date: Thu, 23 Jun 2016 01:12:56 +0000 (UTC)

branch: master
commit 7fe716506b3e8536446c1a83a54e4b3c8d39f361
Author: David Greenspan <address@hidden>
Commit: David Greenspan <address@hidden>

    Fix array destructuring including triple-dot
    
    This change enables proper parsing of:
    * `let [a, b, ...c] = d;`
    * `let [[x,y] = [1,2]] = z;`
    
    The first case is simply the "rest" part of "array rest/spread," which
    lacked the appropriate cases in `js2-parse-array-literal` and
    `js2-define-destruct-symbols`.  There's also new logic to make sure that
    in the destructuring (rest) case, the rest element comes last (while
    spread can occur anywhere).
    
    The removal of the `;; destructuring bind` case of
    `js2-parse-array-literal` may require some explanation.  It was doing
    more harm than good.  For example, it assumed that only identifiers
    have defaults.  Also, calling `js2-parse-destruct-primary-expr` is
    unnecessary, since `js2-is-in-destructuring` is already true.  Rather
    than add the triple-dot logic in two places, it was simpler to stop
    distinguishing between destructuring and non-destructuring at this
    level, because the grammars are extremely similar.  In addition, wacky
    "vars" as in `let [f()] = x` throw an error anyway when they hit
    `js2-define-destruct-symbols`.
---
 js2-mode.el     |   52 ++++++++++++++++++++++------------------------------
 tests/parser.el |   14 ++++++++++++++
 2 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/js2-mode.el b/js2-mode.el
index bf7219a..4ad9c6a 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -8079,7 +8079,11 @@ declared; probably to check them for errors."
      ((js2-array-node-p node)
       (dolist (elem (js2-array-node-elems node))
         (when elem
-          (if (js2-infix-node-p elem) (setq elem (js2-infix-node-left elem)))
+          (setq elem (cond ((js2-infix-node-p elem) ;; default (=)
+                            (js2-infix-node-left elem))
+                           ((js2-unary-node-p elem) ;; rest (...)
+                            (js2-unary-node-operand elem))
+                           (t elem)))
           (push (js2-define-destruct-symbols
                  elem decl-type face ignore-not-in-block)
                 name-nodes)))
@@ -10449,19 +10453,13 @@ array-literals, array comprehensions and regular 
expressions."
 
 (defun js2-parse-array-literal (pos)
   (let ((after-lb-or-comma t)
-        after-comma tt elems pn
+        after-comma tt elems pn was-rest
         (continue t))
     (unless js2-is-in-destructuring
       (js2-push-scope (make-js2-scope))) ; for the legacy array comp
     (while continue
       (setq tt (js2-get-token))
       (cond
-       ;; comma
-       ((= tt js2-COMMA)
-        (setq after-comma (js2-current-token-end))
-        (if (not after-lb-or-comma)
-            (setq after-lb-or-comma t)
-          (push nil elems)))
        ;; end of array
        ((or (= tt js2-RB)
             (= tt js2-EOF))  ; prevent infinite loop
@@ -10475,27 +10473,18 @@ array-literals, array comprehensions and regular 
expressions."
                                       :len (- js2-ts-cursor pos)
                                       :elems (nreverse elems)))
         (apply #'js2-node-add-children pn (js2-array-node-elems pn)))
-       ;; destructuring binding
-       (js2-is-in-destructuring
-        (push (cond
-               ((and (= tt js2-NAME)
-                     (= js2-ASSIGN (js2-peek-token)))
-                ;; a=defaultValue
-                (js2-parse-initialized-binding (js2-parse-name js2-NAME)))
-               ((or (= tt js2-LC)
-                    (= tt js2-LB)
-                    (= tt js2-NAME))
-                ;; [a, b, c] | {a, b, c} | {a:x, b:y, c:z} | a
-                (js2-parse-destruct-primary-expr))
-               ;; invalid pattern
-               (t
-                (js2-report-error "msg.bad.var")
-                (make-js2-error-node)))
-              elems)
-        (setq after-lb-or-comma nil
-              after-comma nil))
+       ;; anything after rest element (...foo)
+       (was-rest
+        (js2-report-error "msg.param.after.rest"))
+       ;; comma
+       ((= tt js2-COMMA)
+        (setq after-comma (js2-current-token-end))
+        (if (not after-lb-or-comma)
+            (setq after-lb-or-comma t)
+          (push nil elems)))
        ;; array comp
        ((and (>= js2-language-version 170)
+             (not js2-is-in-destructuring)
              (= tt js2-FOR)          ; check for array comprehension
              (not after-lb-or-comma) ; "for" can't follow a comma
              elems                   ; must have at least 1 element
@@ -10509,9 +10498,12 @@ array-literals, array comprehensions and regular 
expressions."
           (js2-report-error "msg.no.bracket.arg"))
         (if (and (= tt js2-TRIPLEDOT)
                  (>= js2-language-version 200))
-            ;; spread operator
-            (push (js2-make-unary tt 'js2-parse-assign-expr)
-                  elems)
+            ;; rest/spread operator
+            (progn
+              (push (js2-make-unary tt 'js2-parse-assign-expr)
+                    elems)
+              (if js2-is-in-destructuring
+                  (setq was-rest t)))
           (js2-unget-token)
           (push (js2-parse-assign-expr) elems))
         (setq after-lb-or-comma nil
diff --git a/tests/parser.el b/tests/parser.el
index 79481c8..5e19c5b 100644
--- a/tests/parser.el
+++ b/tests/parser.el
@@ -354,6 +354,20 @@ the test."
 (js2-deftest-parse spread-in-function-call
   "f(3, ...[t(2), t(3)], 42, ...[t(4)]);")
 
+(js2-deftest-parse rest-in-array-destructure
+  "let [x, y, z, ...w] = [1, ...a, ...b, c];")
+
+(js2-deftest-parse comma-after-rest-in-array
+  "let [...x,] = [1, 2, 3];"
+  :syntax-error "," :errors-count 1)
+
+(js2-deftest-parse elem-after-rest-in-array
+  "let [...x, y] = [1, 2, 3];"
+  :syntax-error "," :errors-count 2)
+
+(js2-deftest-parse array-destructure-expr-default
+  "let [[x] = [3]] = y;")
+
 ;;; Arrow functions
 
 (js2-deftest-parse arrow-function-with-empty-args-and-no-curlies



reply via email to

[Prev in Thread] Current Thread [Next in Thread]