Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Parse default parameters

Closes #50
  • Loading branch information...
commit cd50c7b7303886b71fc6fcca3526d896784e4bf6 1 parent e67ed66
@dgutov dgutov authored
Showing with 64 additions and 19 deletions.
  1. +26 −2 js2-mode.el
  2. +38 −17 tests/ast.el
View
28 js2-mode.el
@@ -1562,6 +1562,9 @@ the correct number of ARGS must be provided."
(js2-msg "msg.no.paren.after.parms"
"missing ) after formal parameters")
+(js2-msg "msg.no.default.after.default.param" ; added by js2-mode
+ "parameter without default follows parameter with default")
+
(js2-msg "msg.no.brace.body"
"missing '{' before function body")
@@ -7466,23 +7469,44 @@ NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'."
(defun js2-parse-function-params (fn-node pos)
(if (js2-match-token js2-RP)
(setf (js2-function-node-rp fn-node) (- js2-token-beg pos))
- (let (params len param)
+ (let (params len param default-found)
(loop for tt = (js2-peek-token)
do
(cond
;; destructuring param
((or (= tt js2-LB) (= tt js2-LC))
+ (when default-found
+ (js2-report-error "msg.no.default.after.default.param"))
(setq param (js2-parse-destruct-primary-expr))
(js2-define-destruct-symbols param
js2-LP
'js2-function-param-face)
(push param params))
- ;; simple name
+ ;; variable name
(t
(js2-must-match js2-NAME "msg.no.parm")
(js2-record-face 'js2-function-param-face)
(setq param (js2-create-name-node))
(js2-define-symbol js2-LP js2-ts-string param)
+ ;; default parameter value
+ (when (or (and default-found
+ (js2-must-match js2-ASSIGN
+ "msg.no.default.after.default.param"
+ (js2-node-pos param)
+ (js2-node-len param)))
+ (and (>= js2-language-version 200)
+ (js2-match-token js2-ASSIGN)))
+ (let* ((pos (js2-node-pos param))
+ (tt js2-current-token)
+ (op-pos (- js2-token-beg pos))
+ (left param)
+ (right (js2-parse-assign-expr))
+ (len (- (js2-node-end right) pos)))
+ (setq param (make-js2-assign-node
+ :type tt :pos pos :len len :op-pos op-pos
+ :left left :right right)
+ default-found t)
+ (js2-node-add-children param left right)))
(push param params)))
while
(js2-match-token js2-COMMA))
View
55 tests/ast.el
@@ -9,21 +9,29 @@
(should (null js2-mode-buffer-dirty-p))
js2-mode-ast))
-(defun js2-test-ast-string (code-string)
+(defun js2-test-ast-string (code-string &key syntax-error)
(let ((ast (js2-test-string-to-ast code-string)))
- (ert-with-test-buffer (:name 'copy)
- (js2-print-tree ast)
- (skip-chars-backward " \t\n")
- (should (string= code-string (buffer-substring-no-properties
- (point-min) (point)))))))
-
-(defmacro js2-deftest-ast (name code-string &optional bindings)
- "Parse CODE-STRING, print it out with `js2-print-tree', and
-assert the result to be equal to the original string.
-When BINDINGS are specified, apply them around the test."
+ (if syntax-error
+ (let ((errors (js2-ast-root-errors ast)))
+ (should (= 1 (length errors)))
+ (destructuring-bind (_ pos len) (first errors)
+ (should (string= syntax-error (substring code-string
+ (1- pos) (+ pos len -1))))))
+ (ert-with-test-buffer (:name 'copy)
+ (js2-print-tree ast)
+ (skip-chars-backward " \t\n")
+ (should (string= code-string (buffer-substring-no-properties
+ (point-min) (point))))))))
+
+(defmacro* js2-deftest-ast (name code-string &key bind syntax-error)
+ "Parse CODE-STRING. If SYNTAX-ERROR is nil, print syntax tree
+with `js2-print-tree' and assert the result to be equal to the
+original string. If SYNTAX-ERROR is passed, expect syntax error
+highlighting substring equal to SYNTAX-ERROR value.
+BIND defines bindings to apply them around the test."
`(ert-deftest ,name ()
- (let ,(append bindings '((js2-basic-offset 2)))
- (js2-test-ast-string ,code-string))))
+ (let ,(append bind '((js2-basic-offset 2)))
+ (js2-test-ast-string ,code-string :syntax-error ,syntax-error))))
(put 'js2-deftest-ast 'lisp-indent-function 'defun)
@@ -34,19 +42,19 @@ When BINDINGS are specified, apply them around the test."
(js2-deftest-ast parse-property-access-when-keyword
"A.in = 3;"
- ((js2-allow-keywords-as-property-names t)))
+ :bind ((js2-allow-keywords-as-property-names t)))
(js2-deftest-ast parse-property-access-when-keyword-no-xml
"A.in = 3;"
- ((js2-allow-keywords-as-property-names t)
- (js2-compiler-xml-available nil)))
+ :bind ((js2-allow-keywords-as-property-names t)
+ (js2-compiler-xml-available nil)))
(js2-deftest-ast parse-array-literal-when-not-keyword
"a = {b: 1};")
(js2-deftest-ast parse-array-literal-when-keyword
"a = {in: 1};"
- ((js2-allow-keywords-as-property-names t)))
+ :bind ((js2-allow-keywords-as-property-names t)))
;;; 'of' contextual keyword.
@@ -75,3 +83,16 @@ When BINDINGS are specified, apply them around the test."
(js2-deftest-ast destruct-in-catch-clause
"try {\n} catch ({a, b}) {\n return a + b;\n}")
+
+;;; Function arguments.
+
+(js2-deftest-ast function-with-default-parameters
+ "function foo(a = 1, b = a + 1) {\n}")
+
+(js2-deftest-ast function-with-no-default-after-default
+ "function foo(a = 1, b) {\n}"
+ :syntax-error "b")
+
+(js2-deftest-ast function-with-destruct-after-default
+ "function foo(a = 1, {b, c}) {\n}"
+ :syntax-error "{")
Please sign in to comment.
Something went wrong with that request. Please try again.