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

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

[elpa] master a6c39c2 38/38: Merge commit '38e425785d5ea4600c3642f650006


From: Dmitry Gutov
Subject: [elpa] master a6c39c2 38/38: Merge commit '38e425785d5ea4600c3642f6500062ecedf694a4' from js2-mode
Date: Wed, 28 Feb 2018 20:12:15 -0500 (EST)

branch: master
commit a6c39c29d7b6a4ad8500b2c0947026ff16714576
Merge: 94c7628 38e4257
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>

    Merge commit '38e425785d5ea4600c3642f6500062ecedf694a4' from js2-mode
---
 packages/js2-mode/NEWS.md           |   8 ++
 packages/js2-mode/README.md         |  11 +-
 packages/js2-mode/js2-mode.el       | 216 ++++++++++++++----------------------
 packages/js2-mode/js2-old-indent.el |   3 +-
 packages/js2-mode/tests/consume.el  |  25 +++++
 packages/js2-mode/tests/jsdoc.el    | 113 +++++++++++++++++++
 packages/js2-mode/tests/parser.el   | 115 +++++++++++++++++--
 7 files changed, 343 insertions(+), 148 deletions(-)

diff --git a/packages/js2-mode/NEWS.md b/packages/js2-mode/NEWS.md
index 51ff733..d66f25e 100644
--- a/packages/js2-mode/NEWS.md
+++ b/packages/js2-mode/NEWS.md
@@ -1,5 +1,13 @@
 # History of user-visible changes
 
+## 2018-03-01
+
+* Support single-line JSDocs.
+* New face `js2-object-property-access`.
+* Support for trailing comma in function arguments
+* JSDoc highlighting for address@hidden, address@hidden, address@hidden, 
address@hidden and address@hidden
+* Support for anonymous class exports.
+
 ## 2017-07-21
 
 * Support for async arrow function without parentheses.
diff --git a/packages/js2-mode/README.md b/packages/js2-mode/README.md
index cbce9c3..506c2d4 100644
--- a/packages/js2-mode/README.md
+++ b/packages/js2-mode/README.md
@@ -25,13 +25,16 @@ Bugs
 ====
 
 * See broken syntax highlighting and timer errors? Recently upgraded
-Emacs from version 24.2 or earlier?
-
-* Try
+Emacs from version 24.2 or earlier? Try
 [reinstalling or byte-recompiling](https://github.com/mooz/js2-mode/issues/72)
 the package.
 
-Please report problems at <http://github.com/mooz/js2-mode/issues>.
+* Any indentation problems should be reported with `M-x report-emacs-bug`
+(please try reproducing them with `js-mode` first, for clarity).
+Starting with Emacs 25, `js2-mode` delegates indentation to
+the indentation engine of `js-mode`.
+
+Please report other problems at <http://github.com/mooz/js2-mode/issues>.
 
 Contributing
 ======
diff --git a/packages/js2-mode/js2-mode.el b/packages/js2-mode/js2-mode.el
index f889935..8def8f2 100644
--- a/packages/js2-mode/js2-mode.el
+++ b/packages/js2-mode/js2-mode.el
@@ -1,13 +1,13 @@
-;;; js2-mode.el --- Improved JavaScript editing mode
+;;; js2-mode.el --- Improved JavaScript editing mode -*- lexical-binding: t -*-
 
-;; Copyright (C) 2009, 2011-2017  Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011-2018  Free Software Foundation, Inc.
 
 ;; Author: Steve Yegge <address@hidden>
 ;;         mooz <address@hidden>
 ;;         Dmitry Gutov <address@hidden>
 ;; URL:  https://github.com/mooz/js2-mode/
 ;;       http://code.google.com/p/js2-mode/
-;; Version: 20170721
+;; Version: 20180301
 ;; Keywords: languages, javascript
 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
 
@@ -684,7 +684,6 @@ Current scan position.")
 List of chars built up while scanning various tokens.")
 
 (cl-defstruct (js2-token
-               (:constructor nil)
                (:constructor make-js2-token (beg)))
   "Value returned from the token stream."
   (type js2-EOF)
@@ -1031,6 +1030,11 @@ in large files.")
   "Face used to highlight named property in object literal."
   :group 'js2-mode)
 
+(defface js2-object-property-access
+  '((t :inherit js2-object-property))
+  "Face used to highlight property access with dot on an object."
+  :group 'js2-mode)
+
 (defface js2-instance-member
   '((t :foreground "DarkOrchid"))
   "Face used to highlight instance variables in javascript.
@@ -2253,7 +2257,6 @@ If any given node in NODES is nil, doesn't record that 
link."
 
 (cl-defstruct (js2-block-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-block-node (&key (type js2-BLOCK)
                                                        (pos 
(js2-current-token-beg))
                                                        len
@@ -2279,7 +2282,6 @@ If any given node in NODES is nil, doesn't record that 
link."
 
 (cl-defstruct (js2-scope
                (:include js2-block-node)
-               (:constructor nil)
                (:constructor make-js2-scope (&key (type js2-BLOCK)
                                                   (pos (js2-current-token-beg))
                                                   len
@@ -2351,7 +2353,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
             (js2-scope-symbol-table scope)))))
 
 (cl-defstruct (js2-symbol
-               (:constructor nil)
                (:constructor make-js2-symbol (decl-type name &optional 
ast-node)))
   "A symbol table entry."
   ;; One of js2-FUNCTION, js2-LP (for parameters), js2-VAR,
@@ -2362,7 +2363,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-error-node
                (:include js2-node)
-               (:constructor nil) ; silence emacs21 byte-compiler
                (:constructor make-js2-error-node (&key (type js2-ERROR)
                                                        (pos 
(js2-current-token-beg))
                                                        len)))
@@ -2373,13 +2373,9 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-script-node
                (:include js2-scope)
-               (:constructor nil)
                (:constructor make-js2-script-node (&key (type js2-SCRIPT)
                                                         (pos 
(js2-current-token-beg))
-                                                        len
-                                                        ;; FIXME: What are 
those?
-                                                        var-decls
-                                                        fun-decls)))
+                                                        len)))
   functions   ; Lisp list of nested functions
   regexps     ; Lisp list of (string . flags)
   symbols     ; alist (every symbol gets unique index)
@@ -2397,7 +2393,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-ast-root
                (:include js2-script-node)
-               (:constructor nil)
                (:constructor make-js2-ast-root (&key (type js2-SCRIPT)
                                                      (pos 
(js2-current-token-beg))
                                                      len
@@ -2420,7 +2415,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-comment-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-comment-node (&key (type js2-COMMENT)
                                                          (pos 
(js2-current-token-beg))
                                                          len
@@ -2438,7 +2432,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-expr-stmt-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-expr-stmt-node (&key (type js2-EXPR_VOID)
                                                            (pos js2-ts-cursor)
                                                            len
@@ -2470,7 +2463,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-do-node
                (:include js2-loop-node)
-               (:constructor nil)
                (:constructor make-js2-do-node (&key (type js2-DO)
                                                     (pos 
(js2-current-token-beg))
                                                     len
@@ -2501,7 +2493,6 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
 
 (cl-defstruct (js2-export-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-export-node (&key (type js2-EXPORT)
                                                         (pos 
(js2-current-token-beg))
                                                         len
@@ -2564,7 +2555,6 @@ so many of its properties will be nil.
 
 (cl-defstruct (js2-while-node
                (:include js2-loop-node)
-               (:constructor nil)
                (:constructor make-js2-while-node (&key (type js2-WHILE)
                                                        (pos 
(js2-current-token-beg))
                                                        len body
@@ -2590,7 +2580,6 @@ so many of its properties will be nil.
 
 (cl-defstruct (js2-for-node
                (:include js2-loop-node)
-               (:constructor nil)
                (:constructor make-js2-for-node (&key (type js2-FOR)
                                                      (pos js2-ts-cursor)
                                                      len body init
@@ -2624,7 +2613,6 @@ so many of its properties will be nil.
 
 (cl-defstruct (js2-for-in-node
                (:include js2-loop-node)
-               (:constructor nil)
                (:constructor make-js2-for-in-node (&key (type js2-FOR)
                                                         (pos js2-ts-cursor)
                                                         len body
@@ -2667,7 +2655,6 @@ so many of its properties will be nil.
 
 (cl-defstruct (js2-return-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-return-node (&key (type js2-RETURN)
                                                         (pos js2-ts-cursor)
                                                         len
@@ -2690,7 +2677,6 @@ so many of its properties will be nil.
 
 (cl-defstruct (js2-if-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-if-node (&key (type js2-IF)
                                                     (pos js2-ts-cursor)
                                                     len condition
@@ -2736,7 +2722,6 @@ so many of its properties will be nil.
 
 (cl-defstruct (js2-export-binding-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-export-binding-node (&key (type -1)
                                                                 pos
                                                                 len
@@ -2777,7 +2762,6 @@ different, visit the extern-name."
 
 (cl-defstruct (js2-import-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-import-node (&key (type js2-IMPORT)
                                                         (pos 
(js2-current-token-beg))
                                                         len
@@ -2822,7 +2806,6 @@ import ImportClause FromClause;"
 
 (cl-defstruct (js2-import-clause-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-import-clause-node (&key (type -1)
                                                                pos
                                                                len
@@ -2843,13 +2826,13 @@ local context."
   (let ((ns-import (js2-import-clause-node-namespace-import n))
         (named-imports (js2-import-clause-node-named-imports n))
         (default (js2-import-clause-node-default-binding n)))
+    (when default
+      (js2-visit-ast default v))
     (when ns-import
       (js2-visit-ast ns-import v))
     (when named-imports
       (dolist (import named-imports)
-        (js2-visit-ast import v)))
-    (when default
-      (js2-visit-ast default v))))
+        (js2-visit-ast import v)))))
 
 (defun js2-print-import-clause (n)
   (let ((ns-import (js2-import-clause-node-namespace-import n))
@@ -2888,7 +2871,6 @@ local context."
 
 (cl-defstruct (js2-namespace-import-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-namespace-import-node (&key (type -1)
                                                                   pos
                                                                   len
@@ -2909,7 +2891,6 @@ It contains a single name node referring to the bound 
name."
 
 (cl-defstruct (js2-from-clause-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-from-clause-node (&key (type js2-NAME)
                                                              pos
                                                              len
@@ -2934,7 +2915,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-try-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-try-node (&key (type js2-TRY)
                                                      (pos js2-ts-cursor)
                                                      len
@@ -2971,7 +2951,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-catch-node
                (:include js2-scope)
-               (:constructor nil)
                (:constructor make-js2-catch-node (&key (type js2-CATCH)
                                                        (pos js2-ts-cursor)
                                                        len
@@ -3010,7 +2989,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-finally-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-finally-node (&key (type js2-FINALLY)
                                                          (pos js2-ts-cursor)
                                                          len body)))
@@ -3031,7 +3009,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-switch-node
                (:include js2-scope)
-               (:constructor nil)
                (:constructor make-js2-switch-node (&key (type js2-SWITCH)
                                                         (pos js2-ts-cursor)
                                                         len
@@ -3064,7 +3041,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-case-node
                (:include js2-block-node)
-               (:constructor nil)
                (:constructor make-js2-case-node (&key (type js2-CASE)
                                                       (pos js2-ts-cursor)
                                                       len kids expr)))
@@ -3092,7 +3068,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-throw-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-throw-node (&key (type js2-THROW)
                                                        (pos js2-ts-cursor)
                                                        len expr)))
@@ -3112,7 +3087,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-with-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-with-node (&key (type js2-WITH)
                                                       (pos js2-ts-cursor)
                                                       len object
@@ -3140,7 +3114,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-label-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-label-node (&key (type js2-LABEL)
                                                        (pos js2-ts-cursor)
                                                        len name)))
@@ -3158,7 +3131,6 @@ modules metadata itself."
 
 (cl-defstruct (js2-labeled-stmt-node
                (:include js2-node)
-               (:constructor nil)
                ;; type needs to be in `js2-side-effecting-tokens' to avoid 
spurious
                ;; no-side-effects warnings, hence js2-EXPR_RESULT.
                (:constructor make-js2-labeled-stmt-node (&key (type 
js2-EXPR_RESULT)
@@ -3219,7 +3191,6 @@ NODE is a `js2-labels-node'.  LABEL is an identifier."
 
 (cl-defstruct (js2-break-node
                (:include js2-jump-node)
-               (:constructor nil)
                (:constructor make-js2-break-node (&key (type js2-BREAK)
                                                        (pos js2-ts-cursor)
                                                        len label target)))
@@ -3240,7 +3211,6 @@ is the target of the break - a label node or enclosing 
loop/switch statement.")
 
 (cl-defstruct (js2-continue-node
                (:include js2-jump-node)
-               (:constructor nil)
                (:constructor make-js2-continue-node (&key (type js2-CONTINUE)
                                                           (pos js2-ts-cursor)
                                                           len label target)))
@@ -3261,7 +3231,6 @@ a `js2-label-node' or the innermost enclosing loop.")
 
 (cl-defstruct (js2-function-node
                (:include js2-script-node)
-               (:constructor nil)
                (:constructor make-js2-function-node (&key (type js2-FUNCTION)
                                                           (pos js2-ts-cursor)
                                                           len
@@ -3355,7 +3324,6 @@ The `params' field is a Lisp list of nodes.  Each node is 
either a simple
 ;; Eclipse apparently screwed this up and now has two versions, expr and stmt.
 (cl-defstruct (js2-var-decl-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-var-decl-node (&key (type js2-VAR)
                                                           (pos 
(js2-current-token-beg))
                                                           len kids
@@ -3395,7 +3363,6 @@ declarations, the node begins at the position of the 
first child."
 
 (cl-defstruct (js2-var-init-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-var-init-node (&key (type js2-VAR)
                                                           (pos js2-ts-cursor)
                                                           len target
@@ -3424,7 +3391,6 @@ The type field will be js2-CONST for a const decl."
 
 (cl-defstruct (js2-cond-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-cond-node (&key (type js2-HOOK)
                                                       (pos js2-ts-cursor)
                                                       len
@@ -3458,7 +3424,6 @@ The type field will be js2-CONST for a const decl."
 
 (cl-defstruct (js2-infix-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-infix-node (&key type
                                                        (pos js2-ts-cursor)
                                                        len op-pos
@@ -3549,7 +3514,6 @@ The type field inherited from `js2-node' holds the 
operator."
 
 (cl-defstruct (js2-assign-node
                (:include js2-infix-node)
-               (:constructor nil)
                (:constructor make-js2-assign-node (&key type
                                                         (pos js2-ts-cursor)
                                                         len op-pos
@@ -3562,7 +3526,6 @@ The type field holds the actual assignment operator.")
 
 (cl-defstruct (js2-unary-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-unary-node (&key type ; required
                                                        (pos js2-ts-cursor)
                                                        len operand)))
@@ -3598,7 +3561,6 @@ property is added if the operator follows the operand."
 
 (cl-defstruct (js2-let-node
                (:include js2-scope)
-               (:constructor nil)
                (:constructor make-js2-let-node (&key (type js2-LETEXPR)
                                                      (pos 
(js2-current-token-beg))
                                                      len vars body
@@ -3627,7 +3589,6 @@ Note that a let declaration such as let x=6, y=7 is a 
`js2-var-decl-node'."
 
 (cl-defstruct (js2-keyword-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-keyword-node (&key type
                                                          (pos 
(js2-current-token-beg))
                                                          (len (- js2-ts-cursor 
pos)))))
@@ -3657,7 +3618,6 @@ The node type is set to js2-NULL, js2-THIS, etc.")
 
 (cl-defstruct (js2-new-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-new-node (&key (type js2-NEW)
                                                      (pos 
(js2-current-token-beg))
                                                      len target
@@ -3691,7 +3651,6 @@ The node type is set to js2-NULL, js2-THIS, etc.")
 
 (cl-defstruct (js2-name-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-name-node (&key (type js2-NAME)
                                                       (pos 
(js2-current-token-beg))
                                                       (len (- js2-ts-cursor
@@ -3717,7 +3676,6 @@ Returns 0 if NODE is nil or its identifier field is nil."
 
 (cl-defstruct (js2-number-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-number-node (&key (type js2-NUMBER)
                                                         (pos 
(js2-current-token-beg))
                                                         (len (- js2-ts-cursor
@@ -3744,7 +3702,6 @@ Returns 0 if NODE is nil or its identifier field is nil."
 
 (cl-defstruct (js2-regexp-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-regexp-node (&key (type js2-REGEXP)
                                                         (pos 
(js2-current-token-beg))
                                                         (len (- js2-ts-cursor
@@ -3767,7 +3724,6 @@ Returns 0 if NODE is nil or its identifier field is nil."
 
 (cl-defstruct (js2-string-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-string-node (&key (type js2-STRING)
                                                         (pos 
(js2-current-token-beg))
                                                         (len (- js2-ts-cursor
@@ -3787,7 +3743,6 @@ You can tell the quote type by looking at the first 
character."
 
 (cl-defstruct (js2-template-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-template-node (&key (type 
js2-TEMPLATE_HEAD)
                                                           pos len kids)))
   "Template literal."
@@ -3810,7 +3765,6 @@ You can tell the quote type by looking at the first 
character."
 
 (cl-defstruct (js2-tagged-template-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-tagged-template-node (&key (type 
js2-TAGGED_TEMPLATE)
                                                                  pos len tag 
template)))
   "Tagged template literal."
@@ -3831,7 +3785,6 @@ You can tell the quote type by looking at the first 
character."
 
 (cl-defstruct (js2-array-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-array-node (&key (type js2-ARRAYLIT)
                                                        (pos js2-ts-cursor)
                                                        len elems)))
@@ -3855,7 +3808,6 @@ You can tell the quote type by looking at the first 
character."
 
 (cl-defstruct (js2-object-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-object-node (&key (type js2-OBJECTLIT)
                                                         (pos js2-ts-cursor)
                                                         len
@@ -3878,7 +3830,6 @@ You can tell the quote type by looking at the first 
character."
 
 (cl-defstruct (js2-class-node
                (:include js2-object-node)
-               (:constructor nil)
                (:constructor make-js2-class-node (&key (type js2-CLASS)
                                                        (pos js2-ts-cursor)
                                                        (form 'CLASS_STATEMENT)
@@ -3924,7 +3875,6 @@ optional `js2-expr-node'"
 
 (cl-defstruct (js2-computed-prop-name-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-computed-prop-name-node
                              (&key
                               (type js2-LB)
@@ -3948,7 +3898,6 @@ optional `js2-expr-node'"
 
 (cl-defstruct (js2-object-prop-node
                (:include js2-infix-node)
-               (:constructor nil)
                (:constructor make-js2-object-prop-node (&key (type js2-COLON)
                                                              (pos 
js2-ts-cursor)
                                                              len left
@@ -3974,7 +3923,6 @@ both fields have the same value.")
 
 (cl-defstruct (js2-method-node
                (:include js2-infix-node)
-               (:constructor nil)
                (:constructor make-js2-method-node (&key (pos js2-ts-cursor)
                                                         len left right)))
   "AST node for a method in an object literal or a class body.
@@ -4004,7 +3952,6 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
 
 (cl-defstruct (js2-prop-get-node
                (:include js2-infix-node)
-               (:constructor nil)
                (:constructor make-js2-prop-get-node (&key (type js2-GETPROP)
                                                           (pos js2-ts-cursor)
                                                           len left right)))
@@ -4025,7 +3972,6 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
 
 (cl-defstruct (js2-elem-get-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-elem-get-node (&key (type js2-GETELEM)
                                                           (pos js2-ts-cursor)
                                                           len target element
@@ -4052,7 +3998,6 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
 
 (cl-defstruct (js2-call-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-call-node (&key (type js2-CALL)
                                                       (pos js2-ts-cursor)
                                                       len target args
@@ -4080,7 +4025,6 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
 
 (cl-defstruct (js2-yield-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-yield-node (&key (type js2-YIELD)
                                                        (pos js2-ts-cursor)
                                                        len value star-p)))
@@ -4105,7 +4049,6 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
 
 (cl-defstruct (js2-paren-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-paren-node (&key (type js2-LP)
                                                        (pos js2-ts-cursor)
                                                        len expr)))
@@ -4128,7 +4071,6 @@ as opposed to required parens such as those enclosing an 
if-conditional."
 
 (cl-defstruct (js2-comp-node
                (:include js2-scope)
-               (:constructor nil)
                (:constructor make-js2-comp-node (&key (type js2-ARRAYCOMP)
                                                       (pos js2-ts-cursor)
                                                       len result
@@ -4182,7 +4124,6 @@ as opposed to required parens such as those enclosing an 
if-conditional."
 
 (cl-defstruct (js2-comp-loop-node
                (:include js2-for-in-node)
-               (:constructor nil)
                (:constructor make-js2-comp-loop-node (&key (type js2-FOR)
                                                            (pos js2-ts-cursor)
                                                            len iterator
@@ -4212,7 +4153,6 @@ as opposed to required parens such as those enclosing an 
if-conditional."
 
 (cl-defstruct (js2-empty-expr-node
                (:include js2-node)
-               (:constructor nil)
                (:constructor make-js2-empty-expr-node (&key (type js2-EMPTY)
                                                             (pos 
(js2-current-token-beg))
                                                             len)))
@@ -4223,7 +4163,6 @@ as opposed to required parens such as those enclosing an 
if-conditional."
 
 (cl-defstruct (js2-xml-node
                (:include js2-block-node)
-               (:constructor nil)
                (:constructor make-js2-xml-node (&key (type js2-XML)
                                                      (pos 
(js2-current-token-beg))
                                                      len kids)))
@@ -4240,7 +4179,6 @@ a `js2-xml-js-expr-node'.  Equivalent to Rhino's 
XmlLiteral node.")
 
 (cl-defstruct (js2-xml-js-expr-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-js-expr-node (&key (type js2-XML)
                                                              (pos 
js2-ts-cursor)
                                                              len expr)))
@@ -4262,7 +4200,6 @@ The start and end fields correspond to the curly-braces."
 
 (cl-defstruct (js2-xml-dot-query-node
                (:include js2-infix-node)
-               (:constructor nil)
                (:constructor make-js2-xml-dot-query-node (&key (type 
js2-DOTQUERY)
                                                                (pos 
js2-ts-cursor)
                                                                op-pos len left
@@ -4319,7 +4256,6 @@ expression whose parent is a `js2-xml-dot-query-node'."
 
 (cl-defstruct (js2-xml-prop-ref-node
                (:include js2-xml-ref-node)
-               (:constructor nil)
                (:constructor make-js2-xml-prop-ref-node (&key (type 
js2-REF_NAME)
                                                               (pos 
(js2-current-token-beg))
                                                               len propname
@@ -4358,7 +4294,6 @@ expression."
 
 (cl-defstruct (js2-xml-elem-ref-node
                (:include js2-xml-ref-node)
-               (:constructor nil)
                (:constructor make-js2-xml-elem-ref-node (&key (type 
js2-REF_MEMBER)
                                                               (pos 
(js2-current-token-beg))
                                                               len expr lb rb
@@ -4408,7 +4343,6 @@ end of the index expression."
 
 (cl-defstruct (js2-xml-start-tag-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-start-tag-node (&key (type js2-XML)
                                                                (pos 
js2-ts-cursor)
                                                                len name attrs 
kids
@@ -4440,7 +4374,6 @@ The `kids' field is a Lisp list of child content nodes."
 ;; and add the end-tag to the kids list of the parent as well.
 (cl-defstruct (js2-xml-end-tag-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-end-tag-node (&key (type js2-XML)
                                                              (pos 
js2-ts-cursor)
                                                              len name)))
@@ -4461,7 +4394,6 @@ The `kids' field is a Lisp list of child content nodes."
 
 (cl-defstruct (js2-xml-name-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-name-node (&key (type js2-XML)
                                                           (pos js2-ts-cursor)
                                                           len namespace kids)))
@@ -4488,7 +4420,6 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
 
 (cl-defstruct (js2-xml-pi-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-pi-node (&key (type js2-XML)
                                                         (pos js2-ts-cursor)
                                                         len name attrs)))
@@ -4514,7 +4445,6 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
 
 (cl-defstruct (js2-xml-cdata-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-cdata-node (&key (type js2-XML)
                                                            (pos js2-ts-cursor)
                                                            len content)))
@@ -4533,7 +4463,6 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
 
 (cl-defstruct (js2-xml-attr-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-attr-node (&key (type js2-XML)
                                                       (pos js2-ts-cursor)
                                                       len name value
@@ -4563,7 +4492,6 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
 
 (cl-defstruct (js2-xml-text-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-text-node (&key (type js2-XML)
                                                       (pos js2-ts-cursor)
                                                       len content)))
@@ -4583,7 +4511,6 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
 
 (cl-defstruct (js2-xml-comment-node
                (:include js2-xml-node)
-               (:constructor nil)
                (:constructor make-js2-xml-comment-node (&key (type js2-XML)
                                                              (pos 
js2-ts-cursor)
                                                              len)))
@@ -5247,8 +5174,7 @@ appearing in a statement context will have a parent that 
is a
     (if (or (null parent)
             (js2-stmt-node-p parent)
             (and (js2-function-node-p parent)
-                 (not (eq (js2-function-node-form parent)
-                          'FUNCTION_EXPRESSION))))
+                 (eq (js2-function-node-form parent) 'FUNCTION_STATEMENT)))
         parent
       (js2-node-parent-stmt parent))))
 
@@ -6836,7 +6762,7 @@ Shown at or above `js2-highlight-level' 3.")
                  (if (string-match js2-ecma-object-props prop-name)
                      'font-lock-constant-face))))))
         (when (and (not face) target (not call-p) prop-name)
-          (setq face 'js2-object-property))
+          (setq face 'js2-object-property-access))
         (when face
           (let ((pos (+ (js2-node-pos parent)  ; absolute
                         (js2-node-pos prop)))) ; relative
@@ -6905,7 +6831,7 @@ of a simple name.  Called before EXPR has a parent node."
 
 (defconst js2-jsdoc-param-tag-regexp
   (concat "^\\s-*\\*+\\s-*\\(@"
-          "\\(?:param\\|arg\\(?:ument\\)?\\|prop\\(?:erty\\)?\\)"
+          (regexp-opt '("param" "arg" "argument" "prop" "property" "typedef"))
           "\\)"
           "\\s-*\\({[^}]+}\\)?"         ; optional type
           "\\s-*\\[?\\([[:alnum:]_$\.]+\\)?\\]?"  ; name
@@ -6925,6 +6851,9 @@ of a simple name.  Called before EXPR has a parent node."
              "requires"
              "return"
              "returns"
+             "yield"
+             "yields"
+             "type"
              "throw"
              "throws"))
           "\\)\\)\\s-*\\({[^}]+}\\)?")
@@ -6955,7 +6884,6 @@ of a simple name.  Called before EXPR has a parent node."
              "suppress"
              "this"
              "throws"
-             "type"
              "version"))
           "\\)\\)\\s-+\\([^ \t\n]+\\)")
   "Matches jsdoc tags with a single argument.")
@@ -6963,7 +6891,8 @@ of a simple name.  Called before EXPR has a parent node."
 (defconst js2-jsdoc-empty-tag-regexp
   (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
           (regexp-opt
-           '("addon"
+           '("abstract"
+             "addon"
              "author"
              "class"
              "const"
@@ -7001,6 +6930,7 @@ of a simple name.  Called before EXPR has a parent node."
              "public"
              "static"
              "supported"
+             "virtual"
              ))
           "\\)\\)\\s-*")
   "Matches empty jsdoc tags.")
@@ -7043,8 +6973,10 @@ of a simple name.  Called before EXPR has a parent node."
     (save-excursion
       (dolist (node comments)
         (when (eq (js2-comment-node-format node) 'jsdoc)
-          (setq beg (js2-node-abs-pos node)
-                end (+ beg (js2-node-len node)))
+          ;; Slice off the leading /* and trailing */ in case there
+          ;; are tags on the first line
+          (setq beg (+ 2 (js2-node-abs-pos node))
+                end (+ beg -4 (js2-node-len node)))
           (save-restriction
             (narrow-to-region beg end)
             (dolist (re (list js2-jsdoc-param-tag-regexp
@@ -7250,7 +7182,7 @@ key of a literal object."
                                 finally return syms))))))
     (list declared assigned object-key)))
 
-(defun js2--classify-variable (parent node)
+(defun js2--classify-variable (parent node vars)
   "Classify the single variable NODE, a js2-name-node."
   (let ((function-param (and (js2-function-node-p parent)
                              (memq node (js2-function-node-params parent)))))
@@ -7330,7 +7262,7 @@ are ignored."
        (when (and (null end-p) (js2-name-node-p node))
          (let ((parent (js2-node-parent node)))
            (when parent
-             (js2--classify-variable parent node))))
+             (js2--classify-variable parent node vars))))
        t))
     vars))
 
@@ -7956,7 +7888,7 @@ string is NAME.  Returns nil and keeps current token 
otherwise."
              (end (js2-current-token-end))
              pn)
          (js2-get-token)
-         (setq pn (js2-make-unary js2-AWAIT 'js2-parse-unary-expr))
+         (setq pn (js2-make-unary beg js2-AWAIT 'js2-parse-unary-expr))
          (if (= (js2-node-type (js2-unary-node-operand pn)) js2-ERROR)
              ;; The parse failed, so pretend like nothing happened and restore
              ;; the previous parsing state.
@@ -8751,9 +8683,9 @@ imports or a namespace import that follows it.
         (when ns-import
           (let ((name-node (js2-namespace-import-node-name ns-import)))
             (js2-define-symbol
-             js2-LET (js2-name-node-name name-node) name-node t)))
-        (setf (js2-import-clause-node-namespace-import clause) ns-import)
-        (push ns-import children)))
+             js2-LET (js2-name-node-name name-node) name-node t))
+          (setf (js2-import-clause-node-namespace-import clause) ns-import)
+          (push ns-import children))))
      ((js2-match-token js2-LC)
       (let ((imports (js2-parse-export-bindings t)))
         (setf (js2-import-clause-node-named-imports clause) imports)
@@ -8812,7 +8744,8 @@ The current token must be js2-MUL."
            node)))
       (t
        (js2-unget-token)
-       (js2-report-error "msg.syntax")))))
+       (js2-report-error "msg.syntax")
+       nil))))
 
 
 (defun js2-parse-from-clause ()
@@ -9045,14 +8978,20 @@ invalid export statements."
         (setq from-clause (js2-parse-from-clause))))
      ((js2-match-token js2-DEFAULT)
       (setq default (cond ((js2-match-token js2-CLASS)
-                           (js2-parse-class-stmt))
+                           (if (eq (js2-peek-token) js2-NAME)
+                               (js2-parse-class-stmt)
+                             (js2-parse-class-expr)))
                           ((js2-match-token js2-NAME)
                            (if (js2-match-async-function)
-                               (js2-parse-async-function-stmt)
+                               (if (eq (js2-peek-token) js2-NAME)
+                                   (js2-parse-async-function-stmt)
+                                 (js2-parse-function-expr t))
                              (js2-unget-token)
                              (js2-parse-expr)))
                           ((js2-match-token js2-FUNCTION)
-                           (js2-parse-function-stmt))
+                           (if (eq (js2-peek-token) js2-NAME)
+                               (js2-parse-function-stmt)
+                             (js2-parse-function-expr)))
                           (t (js2-parse-expr)))))
      ((or (js2-match-token js2-VAR) (js2-match-token js2-CONST) 
(js2-match-token js2-LET))
       (setq declaration (js2-parse-variables (js2-current-token-type) 
(js2-current-token-beg))))
@@ -10084,11 +10023,13 @@ FIXME: The latter option is unused?"
         (setq pn (js2-make-binary js2-EXPON pn 'js2-parse-expon-expr))))
     pn))
 
-(defun js2-make-unary (type parser &rest args)
-  "Make a unary node of type TYPE.
-PARSER is either a node (for postfix operators) or a function to call
-to parse the operand (for prefix operators)."
-  (let* ((pos (js2-current-token-beg))
+(defun js2-make-unary (beg type parser &rest args)
+  "Make a unary node starting at BEG of type TYPE.
+If BEG is nil, `(js2-current-token-beg)' is used for the node
+start position.  PARSER is either a node (for postfix operators)
+or a function to call to parse the operand (for prefix
+operators)."
+  (let* ((pos (or beg (js2-current-token-beg)))
          (postfix (js2-node-p parser))
          (expr (if postfix
                    parser
@@ -10120,33 +10061,33 @@ to parse the operand (for prefix operators)."
 
 (defun js2-parse-unary-expr ()
   (let ((tt (js2-current-token-type))
-        pn expr beg end)
+        (beg (js2-current-token-beg)))
     (cond
      ((or (= tt js2-VOID)
           (= tt js2-NOT)
           (= tt js2-BITNOT)
           (= tt js2-TYPEOF))
       (js2-get-token)
-      (js2-make-unary tt 'js2-parse-unary-expr))
+      (js2-make-unary beg tt 'js2-parse-unary-expr))
      ((= tt js2-ADD)
       (js2-get-token)
       ;; Convert to special POS token in decompiler and parse tree
-      (js2-make-unary js2-POS 'js2-parse-unary-expr))
+      (js2-make-unary beg js2-POS 'js2-parse-unary-expr))
      ((= tt js2-SUB)
       (js2-get-token)
       ;; Convert to special NEG token in decompiler and parse tree
-      (js2-make-unary js2-NEG 'js2-parse-unary-expr))
+      (js2-make-unary beg js2-NEG 'js2-parse-unary-expr))
      ((or (= tt js2-INC)
           (= tt js2-DEC))
       (js2-get-token)
-      (prog1
-          (setq beg (js2-current-token-beg)
-                end (js2-current-token-end)
-                expr (js2-make-unary tt 'js2-parse-member-expr t))
-        (js2-check-bad-inc-dec tt beg end expr)))
+      (let ((beg2 (js2-current-token-beg))
+            (end (js2-current-token-end))
+            (expr (js2-make-unary beg tt 'js2-parse-member-expr t)))
+        (js2-check-bad-inc-dec tt beg2 end expr)
+        expr))
      ((= tt js2-DELPROP)
       (js2-get-token)
-      (js2-make-unary js2-DELPROP 'js2-parse-unary-expr))
+      (js2-make-unary beg js2-DELPROP 'js2-parse-unary-expr))
      ((js2-parse-await-maybe tt))
      ((= tt js2-ERROR)
       (js2-get-token)
@@ -10156,16 +10097,17 @@ to parse the operand (for prefix operators)."
       ;; XML stream encountered in expression.
       (js2-parse-member-expr-tail t (js2-parse-xml-initializer)))
      (t
-      (setq pn (js2-parse-member-expr t)
+      (let ((pn (js2-parse-member-expr t))
             ;; Don't look across a newline boundary for a postfix incop.
-            tt (js2-peek-token-or-eol))
-      (when (or (= tt js2-INC) (= tt js2-DEC))
-        (js2-get-token)
-        (setf expr pn
-              pn (js2-make-unary tt expr))
-        (js2-node-set-prop pn 'postfix t)
-        (js2-check-bad-inc-dec tt (js2-current-token-beg) 
(js2-current-token-end) pn))
-      pn))))
+            (tt (js2-peek-token-or-eol))
+            expr)
+        (when (or (= tt js2-INC) (= tt js2-DEC))
+          (js2-get-token)
+          (setf expr pn
+                pn (js2-make-unary (js2-node-pos expr) tt expr))
+          (js2-node-set-prop pn 'postfix t)
+          (js2-check-bad-inc-dec tt (js2-current-token-beg) 
(js2-current-token-end) pn))
+        pn)))))
 
 (defun js2-parse-xml-initializer ()
   "Parse an E4X XML initializer.
@@ -10225,14 +10167,17 @@ Returns the list in reverse order.  Consumes the 
right-paren token."
   (let (result)
     (unless (js2-match-token js2-RP)
       (cl-loop do
-               (let ((tt (js2-get-token)))
+               (let ((tt (js2-get-token))
+                     (beg (js2-current-token-beg)))
                  (if (and (= tt js2-TRIPLEDOT)
                           (>= js2-language-version 200))
-                     (push (js2-make-unary tt 'js2-parse-assign-expr) result)
+                     (push (js2-make-unary beg tt 'js2-parse-assign-expr) 
result)
                    (js2-unget-token)
                    (push (js2-parse-assign-expr) result)))
                while
-               (js2-match-token js2-COMMA))
+               (and (js2-match-token js2-COMMA)
+                    (or (< js2-language-version 200)
+                        (not (= js2-RP (js2-peek-token))))))
       (js2-must-match js2-RP "msg.no.paren.arg")
       result)))
 
@@ -10699,7 +10644,7 @@ array-literals, array comprehensions and regular 
expressions."
                  (>= js2-language-version 200))
             ;; rest/spread operator
             (progn
-              (push (js2-make-unary tt 'js2-parse-assign-expr)
+              (push (js2-make-unary nil tt 'js2-parse-assign-expr)
                     elems)
               (if js2-is-in-destructuring
                   (setq was-rest t)))
@@ -10953,7 +10898,7 @@ expression)."
              (not class-p) (not static) (not previous-token)
              (= js2-TRIPLEDOT tt))
         (setq after-comma nil
-              elem (js2-make-unary js2-TRIPLEDOT 'js2-parse-assign-expr)))
+              elem (js2-make-unary nil js2-TRIPLEDOT 'js2-parse-assign-expr)))
        ;; Found a key/value property (of any sort)
        ((member tt (list js2-NAME js2-STRING js2-NUMBER js2-LB))
         (setq after-comma nil
@@ -11110,9 +11055,10 @@ string or expression."
                   (js2-name-node-p prop))))
       (setq result (make-js2-object-prop-node
                     :pos pos
+                    :len (js2-node-len prop)
                     :left prop
                     :right prop
-                    :op-pos (js2-current-token-len)))
+                    :op-pos (- (js2-current-token-beg) pos)))
       (js2-node-add-children result prop)
       (js2-node-set-prop result 'SHORTHAND t)
       result)
@@ -11147,7 +11093,7 @@ and expression closure style is also supported
 
   { get foo() x, set foo(x) _x = x }
 
-POS is the start position of the `get' or `set' keyword.
+POS is the start position of the `get' or `set' keyword, if any.
 PROP is the `js2-name-node' representing the property name.
 TYPE-STRING is a string `get', `set', `*', or nil, indicating a found keyword."
   (let* ((type (or (cdr (assoc type-string '(("get" . GET)
@@ -11155,7 +11101,7 @@ TYPE-STRING is a string `get', `set', `*', or nil, 
indicating a found keyword."
                                              ("async" . ASYNC))))
                    'FUNCTION))
          result end
-         (pos (js2-current-token-beg))
+         (pos (or pos (js2-current-token-beg)))
          (_ (js2-must-match js2-LP "msg.no.paren.parms"))
          (fn (js2-parse-function 'FUNCTION_EXPRESSION pos
                                  (string= type-string "*")
diff --git a/packages/js2-mode/js2-old-indent.el 
b/packages/js2-mode/js2-old-indent.el
index 5480695..8711d7d 100644
--- a/packages/js2-mode/js2-old-indent.el
+++ b/packages/js2-mode/js2-old-indent.el
@@ -355,7 +355,8 @@ In particular, return the buffer position of the first 
`for' kwd."
                      (re-search-forward "[^,]]* \\(for\\) " end t)
                      ;; not inside comment or string literal
                      (let ((state (parse-partial-sexp bracket (point))))
-                       (not (or (nth 3 state) (nth 4 state)))))
+                       (and (= 1 (car state))
+                            (not (nth 8 state)))))
                 (match-beginning 1))))))))
 
 (defun js2-array-comp-indentation (parse-status for-kwd)
diff --git a/packages/js2-mode/tests/consume.el 
b/packages/js2-mode/tests/consume.el
index 935cdeb..8e6ca17 100644
--- a/packages/js2-mode/tests/consume.el
+++ b/packages/js2-mode/tests/consume.el
@@ -20,6 +20,7 @@
 ;;; Code:
 
 (require 'ert)
+(require 'ert-x)
 (require 'js2-mode)
 
 (defun js2-mode--and-parse ()
@@ -57,3 +58,27 @@
       (setq comments (js2-comments-between 8 9 comments))
       (should (= (length comments) 1))
       )))
+
+;;; Visitors
+
+(ert-deftest js2-visit-import-clause-in-order ()
+  (with-temp-buffer
+    (insert "import defaultImport, { a, b, c} from 'xyz';")
+    (js2-mode--and-parse)
+    (let (visit-log)
+     (js2-visit-ast js2-mode-ast (lambda (node end-p)
+                                   (when (and (not end-p) (js2-name-node-p 
node))
+                                     (let* ((start (js2-node-abs-pos node))
+                                            (end (+ start (js2-node-len 
node))))
+                                       (push (buffer-substring-no-properties 
start end) visit-log)))
+                                   t))
+     (setq visit-log (nreverse visit-log))
+     (should (equal visit-log (list "defaultImport" "a" "b" "c"))))))
+
+(ert-deftest js2-node-parent-stmt/arrow-function ()
+  (ert-with-test-buffer (:name 'js2-node-parent-stmt/arrow-function)
+    (insert "expect(() => ")
+    (save-excursion (insert "func(undefined)).toThrow(/undefined/);"))
+    (js2-mode--and-parse)
+    (let ((parent-stmt (js2-node-parent-stmt (js2-node-at-point))))
+      (should (= (js2-node-abs-pos parent-stmt) 1)))))
diff --git a/packages/js2-mode/tests/jsdoc.el b/packages/js2-mode/tests/jsdoc.el
new file mode 100644
index 0000000..5b5af6e
--- /dev/null
+++ b/packages/js2-mode/tests/jsdoc.el
@@ -0,0 +1,113 @@
+;;; tests/jsdoc.el --- Tests for js2-mode highlighting of jsdoc comments.
+
+;; Copyright (C) 2009, 2011-2017  Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'js2-mode)
+
+(defun js2-get-font-lock-face-props (beg end)
+  "Return a list of three-tuples (START END FONT-LOCK-FACE).
+BEG and END are the current buffer boundaries to use."
+  (unless (get-char-property beg 'font-lock-face)
+    (setq beg (next-single-char-property-change beg 'font-lock-face nil end)))
+  (let (fontification change)
+    (while (< beg end)
+      (setq change (next-single-char-property-change beg 'font-lock-face nil 
end))
+      (push (list beg change (get-char-property beg 'font-lock-face)) 
fontification)
+      (setq beg (if (get-char-property change 'font-lock-face)
+                    change
+                  (next-single-char-property-change change 'font-lock-face nil 
end))))
+    (nreverse fontification)))
+
+(defmacro js2-jsdoc-deftest (name comment-text fontification)
+  (declare (indent defun))
+  (let ((test-name (intern (format "js2-jsdoc-%s" name))))
+    `(ert-deftest ,test-name ()
+       (ert-with-test-buffer (:name ',test-name)
+         (insert ,comment-text)
+         (js2-mode)
+         (js2-reparse)
+         (should (equal (js2-get-font-lock-face-props (point-min) (point-max))
+                        ,fontification))))))
+
+(js2-jsdoc-deftest param
+  "/**\n * @prop {string} p - The property\n */\n"
+  '((1 8 font-lock-doc-face)
+    (8 13 js2-jsdoc-tag)
+    (13 15 font-lock-doc-face)
+    (15 21 js2-jsdoc-type)
+    (21 23 font-lock-doc-face)
+    (23 24 js2-jsdoc-value)
+    (24 43 font-lock-doc-face)))
+
+(js2-jsdoc-deftest typed
+  "/**\n * @implements {Interface}\n */\n"
+  '((1 8 font-lock-doc-face)
+    (8 19 js2-jsdoc-tag)
+    (19 21 font-lock-doc-face)
+    (21 30 js2-jsdoc-type)
+    (30 35 font-lock-doc-face)))
+
+(js2-jsdoc-deftest arg
+  "/**\n * @name TheName \n */\n"
+  '((1 8 font-lock-doc-face)
+    (8 13 js2-jsdoc-tag)
+    (13 14 font-lock-doc-face)
+    (14 21 js2-jsdoc-value)
+    (21 26 font-lock-doc-face)))
+
+(js2-jsdoc-deftest empty
+  "/**\n * @class \n */\n"
+  '((1 8 font-lock-doc-face)
+    (8 14 js2-jsdoc-tag)
+    (14 19 font-lock-doc-face)))
+
+(js2-jsdoc-deftest param-same-line
+  "/** @prop {string} p - The property */\n"
+  '((1 5 font-lock-doc-face)
+    (5 10 js2-jsdoc-tag)
+    (10 12 font-lock-doc-face)
+    (12 18 js2-jsdoc-type)
+    (18 20 font-lock-doc-face)
+    (20 21 js2-jsdoc-value)
+    (21 39 font-lock-doc-face)))
+
+(js2-jsdoc-deftest typed-same-line
+  "/** @implements {Interface} */\n"
+  '((1 5 font-lock-doc-face)
+    (5 16 js2-jsdoc-tag)
+    (16 18 font-lock-doc-face)
+    (18 27 js2-jsdoc-type)
+    (27 31 font-lock-doc-face)))
+
+(js2-jsdoc-deftest arg-same-line
+  "/** @name TheName */\n"
+  '((1 5 font-lock-doc-face)
+    (5 10 js2-jsdoc-tag)
+    (10 11 font-lock-doc-face)
+    (11 18 js2-jsdoc-value)
+    (18 21 font-lock-doc-face)))
+
+(js2-jsdoc-deftest empty-same-line
+  "/** @class */\n"
+  '((1 5 font-lock-doc-face)
+    (5 11 js2-jsdoc-tag)
+    (11 14 font-lock-doc-face)))
diff --git a/packages/js2-mode/tests/parser.el 
b/packages/js2-mode/tests/parser.el
index 482ec8f..1853f03 100644
--- a/packages/js2-mode/tests/parser.el
+++ b/packages/js2-mode/tests/parser.el
@@ -83,6 +83,21 @@ the test."
                               :warnings-count ,warnings-count
                               :reference ,reference))))
 
+(defun js2-find-node (node predicate)
+  "Find the first descendant of NODE meeting PREDICATE."
+  (let (target)
+    (js2-visit-ast node (lambda (n end-p)
+                          (unless end-p
+                            (if (funcall predicate n)
+                              (progn (setq target n) nil)
+                              t))))
+    target))
+
+(defun js2-node-text (node)
+  "Return the part of the buffer corresponding to NODE as a string."
+  (let ((beg (js2-node-abs-pos node)))
+   (buffer-substring-no-properties beg (+ beg (js2-node-len node)))))
+
 ;;; Basics
 
 (js2-deftest-parse variable-assignment
@@ -106,6 +121,10 @@ the test."
 (js2-deftest-parse function-statement
   "function foo() {\n}")
 
+(js2-deftest-parse trailing-comma-in-function-arguments
+   "f(a, b,);"
+   :reference "f(a, b);")
+
 (js2-deftest-parse function-statement-inside-block
   "if (true) {\n  function foo() {\n  }\n}")
 
@@ -628,6 +647,11 @@ the test."
       (should (equal "lib" (js2-name-node-name name-node)))
       (should (= 5 (js2-node-pos name-node))))))
 
+(js2-deftest-parse parse-namespace-import-error
+  "import * lib from 'lib';"
+  :syntax-error "import"
+  :errors-count 7)
+
 (js2-deftest parse-from-clause "from 'foo/bar';"
   (js2-init-scanner)
   (let ((from (js2-parse-from-clause)))
@@ -869,8 +893,9 @@ the test."
 (js2-deftest-parse parse-re-export-named-list "export {foo, bar as bang} from 
'other/lib';")
 (js2-deftest-parse parse-export-const-declaration "export const PI = Math.PI;")
 (js2-deftest-parse parse-export-let-declaration "export let foo = [1];")
-(js2-deftest-parse parse-export-function-declaration "export default function 
doStuff() {\n}")
-(js2-deftest-parse parse-export-generator-declaration "export default 
function* one() {\n}")
+(js2-deftest-parse parse-export-default-function "export default function() 
{}")
+(js2-deftest-parse parse-export-default-generator "export default function*() 
{}")
+(js2-deftest-parse parse-export-default-class "export default class {\n}")
 (js2-deftest-parse parse-export-assignment-expression "export default a = b;")
 
 (js2-deftest-parse parse-export-function-declaration-no-semi
@@ -947,12 +972,6 @@ the test."
 (js2-deftest-parse parse-harmony-class-allow-semicolon-element
   "class Foo {;}" :reference "class Foo {\n}")
 
-(js2-deftest-parse exponentiation
-  "a **= b ** c ** d * e ** f;")
-
-(js2-deftest-parse exponentiation-prohibits-unary-op
-  "var a = -b ** c" :syntax-error "b")
-
 (js2-deftest-parse parse-class-public-field-with-init
   "class C {\n  x = 42;\n  y = 24;\n  \"z\" = 1\n  456 = 789\n}"
   :reference "class C {\n  x = 42\n  y = 24\n  \"z\" = 1\n  456 = 789\n}")
@@ -963,6 +982,86 @@ the test."
 (js2-deftest-parse parse-class-public-field-computed
   "class C {\n  [a + b] = c\n}")
 
+;;; Operators
+
+(js2-deftest-parse exponentiation
+  "a **= b ** c ** d * e ** f;")
+
+(js2-deftest-parse exponentiation-prohibits-unary-op
+  "var a = -b ** c" :syntax-error "-b")
+
+(js2-deftest unary-void-node-start
+  "var c = void 0"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "void 0"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "0"))))
+
+(js2-deftest unary-pos-node-start
+  "var a = +1;"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "+1"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "1"))))
+
+(js2-deftest unary-minus-node-start
+  "var a = -1;"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "-1"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "1"))))
+
+(js2-deftest unary-await-node-start
+  "var f = async () => await p;"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "await p"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "p"))))
+
+(js2-deftest unary-inc-node-start
+  "var a = 1; a++;"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "a++"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "a"))))
+
+(js2-deftest unary-delete-node-start
+  "var a = {b: 2}; delete a.b;"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "delete a.b"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "a.b"))))
+
+(js2-deftest unary-triple-dot-arg-node-start
+  "var b = f(...args)"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "...args"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "args"))))
+
+(js2-deftest unary-triple-dot-array-node-start
+  "var a = [1, 2, ...b]"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "...b"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "b"))))
+
+(js2-deftest unary-triple-dot-object-node-start
+  "var a = {x: 1, y: 2, ...z}"
+  (js2-mode--and-parse)
+  (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
+    (should node)
+    (should (string= (js2-node-text node) "...z"))
+    (should (string= (js2-node-text (js2-unary-node-operand node)) "z"))))
+
 ;;; Scopes
 
 (js2-deftest ast-symbol-table-includes-fn-node "function foo() {}"



reply via email to

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