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

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

[elpa] master 0555a8a 024/110: Support initializer in destructuring


From: Dmitry Gutov
Subject: [elpa] master 0555a8a 024/110: Support initializer in destructuring
Date: Thu, 23 Jun 2016 01:12:54 +0000 (UTC)

branch: master
commit 0555a8a399f512f460cd9e164dbe3f17da01ea9d
Author: Carl Lei <address@hidden>
Commit: Carl Lei <address@hidden>

    Support initializer in destructuring
    
    Also known as default arguments.
---
 NEWS.md         |    2 ++
 js2-mode.el     |   43 +++++++++++++++++++++++++++++++------------
 tests/parser.el |   20 ++++++++++++++++++++
 3 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/NEWS.md b/NEWS.md
index aa04a42..30500e0 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -8,6 +8,8 @@
   with its related functions.  It already handles generator methods,
   and will in the future add support for async methods, so the old
   name will get more confusing.
+* Support for default parameters in destructuring.  It should work for both
+  objects and arrays, in both literals and function arguments.
 
 ## 20150909
 
diff --git a/js2-mode.el b/js2-mode.el
index 865f287..249f4ca 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -8003,16 +8003,18 @@ declared; probably to check them for errors."
         (list node)))
      ((js2-object-node-p node)
       (dolist (elem (js2-object-node-elems node))
-        (when (js2-object-prop-node-p elem)
+        ;; js2-infix-node-p catches both object prop node and initialized
+        ;; binding element (which is directly an infix node).
+        (when (js2-infix-node-p elem)
           (push (js2-define-destruct-symbols
-                 ;; In abbreviated destructuring {a, b}, right == left.
-                 (js2-object-prop-node-right elem)
+                 (js2-infix-node-left elem)
                  decl-type face ignore-not-in-block)
                 name-nodes)))
       (apply #'append (nreverse name-nodes)))
      ((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)))
           (push (js2-define-destruct-symbols
                  elem decl-type face ignore-not-in-block)
                 name-nodes)))
@@ -9632,7 +9634,7 @@ If NODE is non-nil, it is the AST node associated with 
the symbol."
       (js2-node-add-children pn test-expr if-true if-false))
     pn))
 
-(defun js2-make-binary (type left parser)
+(defun js2-make-binary (type left parser &optional no-get)
   "Helper for constructing a binary-operator AST node.
 LEFT is the left-side-expression, already parsed, and the
 binary operator should have just been matched.
@@ -9643,7 +9645,7 @@ FIXME: The latter option is unused?"
          (op-pos (- (js2-current-token-beg) pos))
          (right (if (js2-node-p parser)
                     parser
-                  (js2-get-token)
+                  (unless no-get (js2-get-token))
                   (funcall parser)))
          (pn (make-js2-infix-node :type type
                                   :pos pos
@@ -10364,14 +10366,20 @@ array-literals, array comprehensions and regular 
expressions."
         (apply #'js2-node-add-children pn (js2-array-node-elems pn)))
        ;; destructuring binding
        (js2-is-in-destructuring
-        (push (if (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
+        (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))
+                (make-js2-error-node)))
               elems)
         (setq after-lb-or-comma nil
               after-comma nil))
@@ -10714,6 +10722,10 @@ When `js2-is-in-destructuring' is t, forms like {a, b, 
c} will be permitted."
       (when (js2-name-node-p key)  ; highlight function name properties
         (js2-record-face 'font-lock-function-name-face))
       (js2-parse-method-prop pos key property-type))
+     ;; binding element with initializer
+     ((and (= (js2-peek-token) js2-ASSIGN)
+           (>= js2-language-version 200))
+      (js2-parse-initialized-binding key))
      ;; regular prop
      (t
       (let ((beg (js2-current-token-beg))
@@ -10732,6 +10744,13 @@ When `js2-is-in-destructuring' is t, forms like {a, b, 
c} will be permitted."
                       'record)
         expr)))))
 
+(defun js2-parse-initialized-binding (name)
+  "Parse a `SingleNameBinding' with initializer.
+
+`name' is the `BindingIdentifier'."
+  (when (js2-match-token js2-ASSIGN)
+    (js2-make-binary js2-ASSIGN name 'js2-parse-assign-expr t)))
+
 (defun js2-parse-prop-name (tt)
   (cond
    ;; Literal string keys: {'foo': 'bar'}
diff --git a/tests/parser.el b/tests/parser.el
index c65be2c..51b03eb 100644
--- a/tests/parser.el
+++ b/tests/parser.el
@@ -178,6 +178,26 @@ the test."
 (js2-deftest-parse destruct-in-catch-clause
   "try {\n} catch ({a, b}) {\n  a + b;\n}")
 
+(js2-deftest-parse destruct-with-initializer-in-object
+  "var {a, b = 2, c} = {};")
+
+(js2-deftest-parse destruct-with-initializer-in-array
+  "var [a, b = 2, c] = [];")
+
+(js2-deftest-parse destruct-non-name-target-is-error
+  "var {1=1} = {};" :syntax-error "1" :errors-count 1)
+
+(js2-deftest-parse destruct-with-initializer-in-function-arguments
+  "function f({a, b = 1, c}, [d, e = 1, f]) {\n}")
+
+(js2-deftest-parse destruct-name-conflict-is-error-in-object
+  "\"use strict\";\nvar {a=1,a=2} = {};" :syntax-error "a" :errors-count 1)
+
+(js2-deftest destruct-name-conflict-is-warning-in-array "\"use strict\";\nvar 
[a=1,a=2] = [];"
+  (js2-mode)
+  (should (equal '("msg.var.redecl" "a")
+                 (caar js2-parsed-warnings))))
+
 ;;; Object literals
 
 (js2-deftest-parse object-literal-shorthand



reply via email to

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