[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
- [elpa] master 0cda392 109/110: Make a new release, (continued)
- [elpa] master 0cda392 109/110: Make a new release, Dmitry Gutov, 2016/06/22
- [elpa] master be0b00d 063/110: js2-mode-extend-comment: Don't check that the next line is also commented, Dmitry Gutov, 2016/06/22
- [elpa] master 757f91d 065/110: And move its definition below, Dmitry Gutov, 2016/06/22
- [elpa] master 7e0b11f 071/110: Add tests for of parsing, Dmitry Gutov, 2016/06/22
- [elpa] master 83d9890 070/110: Fix await parsing, Dmitry Gutov, 2016/06/22
- [elpa] master bacb022 074/110: Refactor async arrow function matching, Dmitry Gutov, 2016/06/22
- [elpa] master 57dca37 073/110: Refactor await parsing to only parse once, Dmitry Gutov, 2016/06/22
- [elpa] master 60f7a2b 080/110: Fix computed property generator methods indentation, Dmitry Gutov, 2016/06/22
- [elpa] master de6df33 049/110: Fix semicolons and scoping in exported decls, Dmitry Gutov, 2016/06/22
- [elpa] master dbf4fe9 038/110: Adapt async/await changes to latest master, Dmitry Gutov, 2016/06/22
- [elpa] master 7fe7165 053/110: Fix array destructuring including triple-dot,
Dmitry Gutov <=
- [elpa] master d1bf11f 068/110: Fix void parsing, Dmitry Gutov, 2016/06/22
- [elpa] master 7b430a3 079/110: Merge pull request #308 from zmwangx/jsdoc-callback-func-method, Dmitry Gutov, 2016/06/22
- [elpa] master c988876 086/110: Fix the straggler, Dmitry Gutov, 2016/06/22
- [elpa] master 6399bec 001/110: Support ES(7) async/await syntax; Closes #185, Dmitry Gutov, 2016/06/22
- [elpa] master fa0aa09 060/110: Merge pull request #294 from lunaryorn/patch-1, Dmitry Gutov, 2016/06/22
- [elpa] master ec7932d 047/110: Merge pull request #283 from XeCycle/master-with-async, Dmitry Gutov, 2016/06/22
- [elpa] master e44d9e1 088/110: Merge pull request #325 from phst/all-tests, Dmitry Gutov, 2016/06/22
- [elpa] master 812df51 091/110: Merge pull request #326 from phst/compiler-warning-25, Dmitry Gutov, 2016/06/22
- [elpa] master de5b31c 085/110: Fix the tests broken in the previous commit, Dmitry Gutov, 2016/06/22
- [elpa] master f130121 095/110: Merge pull request #328 from XeCycle/iname-color, Dmitry Gutov, 2016/06/22