From 87cfd408316d1e6712f167e74dde9832624fb709 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Wed, 5 Nov 2014 11:45:15 +0200 Subject: [PATCH] Support object destructuring inside arrow function args * js2-mode.el (js2-parse-plain-property): Don't move too far when there's no colon. (js2-parse-assign-expr): Restore the previous value of `js2-parsed-errors' after arrow token is found. Fixes #167 --- js2-mode.el | 40 ++++++++++++++++++++++------------------ tests/parser.el | 7 +++++-- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index ba0ba4e87..0141eb418 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -8571,13 +8571,14 @@ If NODE is non-nil, it is the AST node associated with the symbol." (let ((tt (js2-get-token)) (pos (js2-current-token-beg)) pn left right op-pos - ts-state recorded-identifiers) + ts-state recorded-identifiers parsed-errors) (if (= tt js2-YIELD) (js2-parse-return-or-yield tt t) ;; Save the tokenizer state in case we find an arrow function ;; and have to rewind. (setq ts-state (make-js2-ts-state) - recorded-identifiers js2-recorded-identifiers) + recorded-identifiers js2-recorded-identifiers + parsed-errors js2-parsed-errors) ;; not yield - parse assignment expression (setq pn (js2-parse-cond-expr) tt (js2-get-token)) @@ -8602,7 +8603,8 @@ If NODE is non-nil, it is the AST node associated with the symbol." ((and (= tt js2-ARROW) (>= js2-language-version 200)) (js2-ts-seek ts-state) - (setq js2-recorded-identifiers recorded-identifiers) + (setq js2-recorded-identifiers recorded-identifiers + js2-parsed-errors parsed-errors) (setq pn (js2-parse-function 'FUNCTION_ARROW (js2-current-token-beg) nil))) (t (js2-unget-token))) @@ -9600,21 +9602,23 @@ When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted." (defun js2-parse-plain-property (prop) "Parse a non-getter/setter property in an object literal. PROP is the node representing the property: a number, name or string." - (js2-must-match js2-COLON "msg.no.colon.prop") - (let* ((pos (js2-node-pos prop)) - (colon (- (js2-current-token-beg) pos)) - (expr (js2-parse-assign-expr)) - (result (make-js2-object-prop-node - :pos pos - ;; don't include last consumed token in length - :len (- (+ (js2-node-pos expr) - (js2-node-len expr)) - pos) - :left prop - :right expr - :op-pos colon))) - (js2-node-add-children result prop expr) - result)) + (let ((pos (js2-node-pos prop)) + colon expr) + (if (js2-must-match js2-COLON "msg.no.colon.prop") + (setq colon (- (js2-current-token-beg) pos) + expr (js2-parse-assign-expr)) + (setq expr (make-js2-error-node))) + (let ((result (make-js2-object-prop-node + :pos pos + ;; don't include last consumed token in length + :len (- (+ (js2-node-pos expr) + (js2-node-len expr)) + pos) + :left prop + :right expr + :op-pos colon))) + (js2-node-add-children result prop expr) + result))) (defun js2-parse-getter-setter-prop (pos prop get-p) "Parse getter or setter property in an object literal. diff --git a/tests/parser.el b/tests/parser.el index 1df960366..ffda856c8 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -222,11 +222,14 @@ the test." (js2-deftest-parse arrow-function-with-args-and-curlies "(a, b = 1, ...c) => { c;\n};") +(js2-deftest-parse arrow-function-with-destructuring + "([{a}, b]) => { a + b;\n};") + (js2-deftest-parse parenless-arrow-function-prohibits-rest - "...b => {b + 1;};" :syntax-error "=>" :errors-count 2) + "...b => {b + 1;};" :syntax-error "=>" :errors-count 1) (js2-deftest-parse parenless-arrow-function-prohibits-destructuring - "[a, b] => {a + b;};" :syntax-error "=>" :errors-count 5) + "[a, b] => {a + b;};" :syntax-error "=>" :errors-count 4) ;;; Automatic semicolon insertion -- 2.39.2