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

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

[elpa] master 231ac7f 31/31: Merge commit 'cb57d9b67390ae3ff70ab64169bbc


From: Dmitry Gutov
Subject: [elpa] master 231ac7f 31/31: Merge commit 'cb57d9b67390ae3ff70ab64169bbc4f1264244bc' from js2-mode
Date: Fri, 21 Jul 2017 09:05:00 -0400 (EDT)

branch: master
commit 231ac7f34305e666b56d34d8f56fb1591869921d
Merge: a69e424 cb57d9b
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>

    Merge commit 'cb57d9b67390ae3ff70ab64169bbc4f1264244bc' from js2-mode
---
 packages/js2-mode/NEWS.md           |   9 +
 packages/js2-mode/js2-mode.el       | 473 +++++++++++++++++++++---------------
 packages/js2-mode/js2-old-indent.el |   1 -
 packages/js2-mode/tests/externs.el  |  65 +++++
 packages/js2-mode/tests/parser.el   | 140 ++++++++---
 5 files changed, 458 insertions(+), 230 deletions(-)

diff --git a/packages/js2-mode/NEWS.md b/packages/js2-mode/NEWS.md
index 714bab8..51ff733 100644
--- a/packages/js2-mode/NEWS.md
+++ b/packages/js2-mode/NEWS.md
@@ -1,5 +1,14 @@
 # History of user-visible changes
 
+## 2017-07-21
+
+* Support for async arrow function without parentheses.
+* Support for `/*jslint` declarations.
+* User option `js2-getprop-has-side-effects`.
+* Support for trailing commas in function parameter lists.
+* Support for ES7 public class fields.
+* New user option `js2-ignored-warnings`.
+
 ## 2017-01-16
 
 * `js2-include-*-externs` are now evaluated on demand.  As a result,
diff --git a/packages/js2-mode/js2-mode.el b/packages/js2-mode/js2-mode.el
index 140b6c0..f889935 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
 
-;; Copyright (C) 2009, 2011-2016  Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011-2017  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: 20170116
+;; Version: 20170721
 ;; Keywords: languages, javascript
 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
 
@@ -220,11 +220,12 @@ are enabled, these will also be included.")
 
 ;;; Variables
 
-(defun js2-mark-safe-local (name pred)
-  "Make the variable NAME buffer-local and mark it as safe file-local
-variable with predicate PRED."
-  (make-variable-buffer-local name)
-  (put name 'safe-local-variable pred))
+(defcustom js2-ignored-warnings nil
+  "A list of warning message types that will not be reported.
+
+Possible values are the keys of `js2-message-table'."
+  :group 'js2-mode
+  :type '(repeat string))
 
 (defcustom js2-highlight-level 2
   "Amount of syntax highlighting to perform.
@@ -358,6 +359,13 @@ This is useful for xulrunner apps."
   :type 'boolean
   :group 'js2-mode)
 
+(defcustom js2-getprop-has-side-effects nil
+  "If non-nil, treats the getprop operator as having side effects.
+This is useful for testing libraries with nontrivial getters and for
+compilers that use empty getprops to declare interface properties."
+  :type 'boolean
+  :group 'js2-mode)
+
 (defcustom js2-move-point-on-right-click t
   "Non-nil to move insertion point when you right-click.
 This makes right-click context menu behavior a bit more intuitive,
@@ -1110,9 +1118,16 @@ information."
   :type 'boolean
   :group 'js2-mode)
 
+(defcustom js2-include-jslint-declaration-externs t
+  "Non-nil to include the identifiers JSLint assumes to be there
+under certain declarations in the buffer-local externs list.  See
+`js2-additional-externs' for more information."
+  :type 'boolean
+  :group 'js2-mode)
+
 (defvar js2-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M-j") #'js2-line-break)
+    (define-key map [remap indent-new-comment-line] #'js2-line-break)
     (define-key map (kbd "C-c C-e") #'js2-mode-hide-element)
     (define-key map (kbd "C-c C-s") #'js2-mode-show-element)
     (define-key map (kbd "C-c C-a") #'js2-mode-show-all)
@@ -1352,9 +1367,6 @@ the correct number of ARGS must be provided."
 (js2-msg "msg.bad.yield"
          "yield must be in a function.")
 
-(js2-msg "msg.yield.parenthesized"
-         "yield expression must be parenthesized.")
-
 (js2-msg "msg.bad.await"
          "await must be in async functions.")
 
@@ -2230,6 +2242,10 @@ If any given node in NODES is nil, doesn't record that 
link."
   "Return absolute buffer position of end of N."
   (+ (js2-node-abs-pos n) (js2-node-len n)))
 
+(defun js2--struct-put (name key value)
+  (put name key value)
+  (put (intern (format "cl-struct-%s" name)) key value))
+
 ;; It's important to make sure block nodes have a Lisp list for the
 ;; child nodes, to limit printing recursion depth in an AST that
 ;; otherwise consists of defstruct vectors.  Emacs will crash printing
@@ -2246,8 +2262,8 @@ If any given node in NODES is nil, doesn't record that 
link."
   "A block of statements."
   kids)  ; a Lisp list of the child statement nodes
 
-(put 'cl-struct-js2-block-node 'js2-visitor 'js2-visit-block)
-(put 'cl-struct-js2-block-node 'js2-printer 'js2-print-block)
+(js2--struct-put 'js2-block-node 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-block-node 'js2-printer 'js2-print-block)
 
 (defun js2-visit-block (ast callback)
   "Visit the `js2-block-node' children of AST."
@@ -2278,8 +2294,8 @@ If any given node in NODES is nil, doesn't record that 
link."
   parent-scope  ; a `js2-scope'
   top)          ; top-level `js2-scope' (script/function)
 
-(put 'cl-struct-js2-scope 'js2-visitor 'js2-visit-block)
-(put 'cl-struct-js2-scope 'js2-printer 'js2-print-none)
+(js2--struct-put 'js2-scope 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-scope 'js2-printer 'js2-print-none)
 
 (defun js2-node-get-enclosing-scope (node)
   "Return the innermost `js2-scope' node surrounding NODE.
@@ -2352,8 +2368,8 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
                                                        len)))
   "AST node representing a parse error.")
 
-(put 'cl-struct-js2-error-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-error-node 'js2-printer 'js2-print-none)
+(js2--struct-put 'js2-error-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-error-node 'js2-printer 'js2-print-none)
 
 (cl-defstruct (js2-script-node
                (:include js2-scope)
@@ -2372,8 +2388,8 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
   consts      ; bool-vector matching var-decls
   (temp-number 0))  ; for generating temp variables
 
-(put 'cl-struct-js2-script-node 'js2-visitor 'js2-visit-block)
-(put 'cl-struct-js2-script-node 'js2-printer 'js2-print-script)
+(js2--struct-put 'js2-script-node 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-script-node 'js2-printer 'js2-print-script)
 
 (defun js2-print-script (node indent)
   (dolist (kid (js2-block-node-kids node))
@@ -2393,8 +2409,8 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
   warnings       ; a Lisp list of warnings found during parsing
   node-count)    ; number of nodes in the tree, including the root
 
-(put 'cl-struct-js2-ast-root 'js2-visitor 'js2-visit-ast-root)
-(put 'cl-struct-js2-ast-root 'js2-printer 'js2-print-script)
+(js2--struct-put 'js2-ast-root 'js2-visitor 'js2-visit-ast-root)
+(js2--struct-put 'js2-ast-root 'js2-printer 'js2-print-script)
 
 (defun js2-visit-ast-root (ast callback)
   (dolist (kid (js2-ast-root-kids ast))
@@ -2411,8 +2427,8 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
                                                          format)))
   format)  ; 'line, 'block, 'jsdoc or 'html
 
-(put 'cl-struct-js2-comment-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-comment-node 'js2-printer 'js2-print-comment)
+(js2--struct-put 'js2-comment-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-comment-node 'js2-printer 'js2-print-comment)
 
 (defun js2-print-comment (n i)
   ;; We really ought to link end-of-line comments to their nodes.
@@ -2434,8 +2450,8 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
   "Change NODE type to `js2-EXPR_RESULT'.  Used for code generation."
   (setf (js2-node-type node) js2-EXPR_RESULT))
 
-(put 'cl-struct-js2-expr-stmt-node 'js2-visitor 'js2-visit-expr-stmt-node)
-(put 'cl-struct-js2-expr-stmt-node 'js2-printer 'js2-print-expr-stmt-node)
+(js2--struct-put 'js2-expr-stmt-node 'js2-visitor 'js2-visit-expr-stmt-node)
+(js2--struct-put 'js2-expr-stmt-node 'js2-printer 'js2-print-expr-stmt-node)
 
 (defun js2-visit-expr-stmt-node (n v)
   (js2-visit-ast (js2-expr-stmt-node-expr n) v))
@@ -2467,8 +2483,8 @@ NAME can be a Lisp symbol or string.  SYMBOL is a 
`js2-symbol'."
   condition  ; while (expression)
   while-pos) ; buffer position of 'while' keyword
 
-(put 'cl-struct-js2-do-node 'js2-visitor 'js2-visit-do-node)
-(put 'cl-struct-js2-do-node 'js2-printer 'js2-print-do-node)
+(js2--struct-put 'js2-do-node 'js2-visitor 'js2-visit-do-node)
+(js2--struct-put 'js2-do-node 'js2-printer 'js2-print-do-node)
 
 (defun js2-visit-do-node (n v)
   (js2-visit-ast (js2-do-node-body n) v)
@@ -2501,8 +2517,8 @@ so many of its properties will be nil.
   declaration ; js2-var-decl-node (var, let, const) or js2-class-node
   default) ; js2-function-node or js2-assign-node
 
-(put 'cl-struct-js2-export-node 'js2-visitor 'js2-visit-export-node)
-(put 'cl-struct-js2-export-node 'js2-printer 'js2-print-export-node)
+(js2--struct-put 'js2-export-node 'js2-visitor 'js2-visit-export-node)
+(js2--struct-put 'js2-export-node 'js2-printer 'js2-print-export-node)
 
 (defun js2-visit-export-node (n v)
   (let ((exports-list (js2-export-node-exports-list n))
@@ -2557,8 +2573,8 @@ so many of its properties will be nil.
   "AST node for while-loop."
   condition)    ; while-condition
 
-(put 'cl-struct-js2-while-node 'js2-visitor 'js2-visit-while-node)
-(put 'cl-struct-js2-while-node 'js2-printer 'js2-print-while-node)
+(js2--struct-put 'js2-while-node 'js2-visitor 'js2-visit-while-node)
+(js2--struct-put 'js2-while-node 'js2-printer 'js2-print-while-node)
 
 (defun js2-visit-while-node (n v)
   (js2-visit-ast (js2-while-node-condition n) v)
@@ -2585,8 +2601,8 @@ so many of its properties will be nil.
   condition  ; loop condition
   update)    ; update clause
 
-(put 'cl-struct-js2-for-node 'js2-visitor 'js2-visit-for-node)
-(put 'cl-struct-js2-for-node 'js2-printer 'js2-print-for-node)
+(js2--struct-put 'js2-for-node 'js2-visitor 'js2-visit-for-node)
+(js2--struct-put 'js2-for-node 'js2-printer 'js2-print-for-node)
 
 (defun js2-visit-for-node (n v)
   (js2-visit-ast (js2-for-node-init n) v)
@@ -2626,8 +2642,8 @@ so many of its properties will be nil.
   foreach-p ; t if it's a for-each loop
   forof-p)  ; t if it's a for-of loop
 
-(put 'cl-struct-js2-for-in-node 'js2-visitor 'js2-visit-for-in-node)
-(put 'cl-struct-js2-for-in-node 'js2-printer 'js2-print-for-in-node)
+(js2--struct-put 'js2-for-in-node 'js2-visitor 'js2-visit-for-in-node)
+(js2--struct-put 'js2-for-in-node 'js2-printer 'js2-print-for-in-node)
 
 (defun js2-visit-for-in-node (n v)
   (js2-visit-ast (js2-for-in-node-iterator n) v)
@@ -2659,8 +2675,8 @@ so many of its properties will be nil.
   "AST node for a return statement."
   retval)  ; expression to return, or 'undefined
 
-(put 'cl-struct-js2-return-node 'js2-visitor 'js2-visit-return-node)
-(put 'cl-struct-js2-return-node 'js2-printer 'js2-print-return-node)
+(js2--struct-put 'js2-return-node 'js2-visitor 'js2-visit-return-node)
+(js2--struct-put 'js2-return-node 'js2-printer 'js2-print-return-node)
 
 (defun js2-visit-return-node (n v)
   (js2-visit-ast (js2-return-node-retval n) v))
@@ -2690,8 +2706,8 @@ so many of its properties will be nil.
   lp          ; position of left-paren, nil if omitted
   rp)         ; position of right-paren, nil if omitted
 
-(put 'cl-struct-js2-if-node 'js2-visitor 'js2-visit-if-node)
-(put 'cl-struct-js2-if-node 'js2-printer 'js2-print-if-node)
+(js2--struct-put 'js2-if-node 'js2-visitor 'js2-visit-if-node)
+(js2--struct-put 'js2-if-node 'js2-printer 'js2-print-if-node)
 
 (defun js2-visit-if-node (n v)
   (js2-visit-ast (js2-if-node-condition n) v)
@@ -2735,8 +2751,8 @@ containing `foo' and a local-name node containing `bar'."
   local-name ; js2-name-node with the variable name in this scope
   extern-name)   ; js2-name-node with the value name in the exporting module
 
-(put 'cl-struct-js2-export-binding-node 'js2-printer 'js2-print-extern-binding)
-(put 'cl-struct-js2-export-binding-node 'js2-visitor 'js2-visit-extern-binding)
+(js2--struct-put 'js2-export-binding-node 'js2-printer 
'js2-print-extern-binding)
+(js2--struct-put 'js2-export-binding-node 'js2-visitor 
'js2-visit-extern-binding)
 
 (defun js2-visit-extern-binding (n v)
   "Visit an extern binding node. First visit the local-name, and, if
@@ -2776,8 +2792,8 @@ import ImportClause FromClause;"
   from       ; js2-from-clause-node indicating the module from which to import.
   module-id) ; module-id of the import. E.g. 'src/mylib'.
 
-(put 'cl-struct-js2-import-node 'js2-printer 'js2-print-import)
-(put 'cl-struct-js2-import-node 'js2-visitor 'js2-visit-import)
+(js2--struct-put 'js2-import-node 'js2-printer 'js2-print-import)
+(js2--struct-put 'js2-import-node 'js2-visitor 'js2-visit-import)
 
 (defun js2-visit-import (n v)
   (let ((import-clause (js2-import-node-import n))
@@ -2820,8 +2836,8 @@ local context."
   named-imports    ; lisp list of js2-export-binding-node for all named 
imports.
   default-binding) ; js2-export-binding-node for the default import binding
 
-(put 'cl-struct-js2-import-clause-node 'js2-visitor 'js2-visit-import-clause)
-(put 'cl-struct-js2-import-clause-node 'js2-printer 'js2-print-import-clause)
+(js2--struct-put 'js2-import-clause-node 'js2-visitor 'js2-visit-import-clause)
+(js2--struct-put 'js2-import-clause-node 'js2-printer 'js2-print-import-clause)
 
 (defun js2-visit-import-clause (n v)
   (let ((ns-import (js2-import-clause-node-namespace-import n))
@@ -2888,8 +2904,8 @@ It contains a single name node referring to the bound 
name."
 (defun js2-visit-namespace-import (n v)
   (js2-visit-ast (js2-namespace-import-node-name n) v))
 
-(put 'cl-struct-js2-namespace-import-node 'js2-visitor 
'js2-visit-namespace-import)
-(put 'cl-struct-js2-namespace-import-node 'js2-printer 
'js2-print-namespace-import)
+(js2--struct-put 'js2-namespace-import-node 'js2-visitor 
'js2-visit-namespace-import)
+(js2--struct-put 'js2-namespace-import-node 'js2-printer 
'js2-print-namespace-import)
 
 (cl-defstruct (js2-from-clause-node
                (:include js2-node)
@@ -2905,8 +2921,8 @@ modules metadata itself."
   module-id ; string containing the module specifier.
   metadata-p) ; true if this clause refers to the module's metadata
 
-(put 'cl-struct-js2-from-clause-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-from-clause-node 'js2-printer 'js2-print-from-clause)
+(js2--struct-put 'js2-from-clause-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-from-clause-node 'js2-printer 'js2-print-from-clause)
 
 (defun js2-print-from-clause (n)
   (insert "from ")
@@ -2930,8 +2946,8 @@ modules metadata itself."
   catch-clauses  ; a Lisp list of `js2-catch-node'
   finally-block) ; a `js2-finally-node'
 
-(put 'cl-struct-js2-try-node 'js2-visitor 'js2-visit-try-node)
-(put 'cl-struct-js2-try-node 'js2-printer 'js2-print-try-node)
+(js2--struct-put 'js2-try-node 'js2-visitor 'js2-visit-try-node)
+(js2--struct-put 'js2-try-node 'js2-printer 'js2-print-try-node)
 
 (defun js2-visit-try-node (n v)
   (js2-visit-ast (js2-try-node-try-block n) v)
@@ -2970,8 +2986,8 @@ modules metadata itself."
   lp          ; buffer position of left-paren, nil if omitted
   rp)         ; buffer position of right-paren, nil if omitted
 
-(put 'cl-struct-js2-catch-node 'js2-visitor 'js2-visit-catch-node)
-(put 'cl-struct-js2-catch-node 'js2-printer 'js2-print-catch-node)
+(js2--struct-put 'js2-catch-node 'js2-visitor 'js2-visit-catch-node)
+(js2--struct-put 'js2-catch-node 'js2-printer 'js2-print-catch-node)
 
 (defun js2-visit-catch-node (n v)
   (js2-visit-ast (js2-catch-node-param n) v)
@@ -3001,8 +3017,8 @@ modules metadata itself."
   "AST node for a finally clause."
   body)  ; a `js2-node', often but not always a block node
 
-(put 'cl-struct-js2-finally-node 'js2-visitor 'js2-visit-finally-node)
-(put 'cl-struct-js2-finally-node 'js2-printer 'js2-print-finally-node)
+(js2--struct-put 'js2-finally-node 'js2-visitor 'js2-visit-finally-node)
+(js2--struct-put 'js2-finally-node 'js2-printer 'js2-print-finally-node)
 
 (defun js2-visit-finally-node (n v)
   (js2-visit-ast (js2-finally-node-body n) v))
@@ -3028,8 +3044,8 @@ modules metadata itself."
   lp     ; position of open-paren for discriminant, nil if omitted
   rp)    ; position of close-paren for discriminant, nil if omitted
 
-(put 'cl-struct-js2-switch-node 'js2-visitor 'js2-visit-switch-node)
-(put 'cl-struct-js2-switch-node 'js2-printer 'js2-print-switch-node)
+(js2--struct-put 'js2-switch-node 'js2-visitor 'js2-visit-switch-node)
+(js2--struct-put 'js2-switch-node 'js2-printer 'js2-print-switch-node)
 
 (defun js2-visit-switch-node (n v)
   (js2-visit-ast (js2-switch-node-discriminant n) v)
@@ -3055,8 +3071,8 @@ modules metadata itself."
   "AST node for a case clause of a switch statement."
   expr)   ; the case expression (nil for default)
 
-(put 'cl-struct-js2-case-node 'js2-visitor 'js2-visit-case-node)
-(put 'cl-struct-js2-case-node 'js2-printer 'js2-print-case-node)
+(js2--struct-put 'js2-case-node 'js2-visitor 'js2-visit-case-node)
+(js2--struct-put 'js2-case-node 'js2-printer 'js2-print-case-node)
 
 (defun js2-visit-case-node (n v)
   (js2-visit-ast (js2-case-node-expr n) v)
@@ -3083,8 +3099,8 @@ modules metadata itself."
   "AST node for a throw statement."
   expr)   ; the expression to throw
 
-(put 'cl-struct-js2-throw-node 'js2-visitor 'js2-visit-throw-node)
-(put 'cl-struct-js2-throw-node 'js2-printer 'js2-print-throw-node)
+(js2--struct-put 'js2-throw-node 'js2-visitor 'js2-visit-throw-node)
+(js2--struct-put 'js2-throw-node 'js2-printer 'js2-print-throw-node)
 
 (defun js2-visit-throw-node (n v)
   (js2-visit-ast (js2-throw-node-expr n) v))
@@ -3107,8 +3123,8 @@ modules metadata itself."
   lp    ; buffer position of left-paren around object, nil if omitted
   rp)   ; buffer position of right-paren around object, nil if omitted
 
-(put 'cl-struct-js2-with-node 'js2-visitor 'js2-visit-with-node)
-(put 'cl-struct-js2-with-node 'js2-printer 'js2-print-with-node)
+(js2--struct-put 'js2-with-node 'js2-visitor 'js2-visit-with-node)
+(js2--struct-put 'js2-with-node 'js2-printer 'js2-print-with-node)
 
 (defun js2-visit-with-node (n v)
   (js2-visit-ast (js2-with-node-object n) v)
@@ -3132,8 +3148,8 @@ modules metadata itself."
   name   ; a string
   loop)  ; for validating and code-generating continue-to-label
 
-(put 'cl-struct-js2-label-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-label-node 'js2-printer 'js2-print-label)
+(js2--struct-put 'js2-label-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-label-node 'js2-printer 'js2-print-label)
 
 (defun js2-print-label (n i)
   (insert (js2-make-pad i)
@@ -3153,8 +3169,8 @@ Multiple labels for a statement are collapsed into the 
labels field."
   labels  ; Lisp list of `js2-label-node'
   stmt)   ; the statement these labels are for
 
-(put 'cl-struct-js2-labeled-stmt-node 'js2-visitor 'js2-visit-labeled-stmt)
-(put 'cl-struct-js2-labeled-stmt-node 'js2-printer 'js2-print-labeled-stmt)
+(js2--struct-put 'js2-labeled-stmt-node 'js2-visitor 'js2-visit-labeled-stmt)
+(js2--struct-put 'js2-labeled-stmt-node 'js2-printer 'js2-print-labeled-stmt)
 
 (defun js2-get-label-by-name (lbl-stmt name)
   "Return a `js2-label-node' by NAME from LBL-STMT's labels list.
@@ -3212,8 +3228,8 @@ The label field is a `js2-name-node', possibly nil, for 
the named label
 if provided.  E.g. in `break foo', it represents `foo'.  The target field
 is the target of the break - a label node or enclosing loop/switch statement.")
 
-(put 'cl-struct-js2-break-node 'js2-visitor 'js2-visit-jump-node)
-(put 'cl-struct-js2-break-node 'js2-printer 'js2-print-break-node)
+(js2--struct-put 'js2-break-node 'js2-visitor 'js2-visit-jump-node)
+(js2--struct-put 'js2-break-node 'js2-printer 'js2-print-break-node)
 
 (defun js2-print-break-node (n i)
   (insert (js2-make-pad i) "break")
@@ -3233,8 +3249,8 @@ The label field is the user-supplied enclosing label 
name, a `js2-name-node'.
 It is nil if continue specifies no label.  The target field is the jump target:
 a `js2-label-node' or the innermost enclosing loop.")
 
-(put 'cl-struct-js2-continue-node 'js2-visitor 'js2-visit-jump-node)
-(put 'cl-struct-js2-continue-node 'js2-printer 'js2-print-continue-node)
+(js2--struct-put 'js2-continue-node 'js2-visitor 'js2-visit-jump-node)
+(js2--struct-put 'js2-continue-node 'js2-printer 'js2-print-continue-node)
 
 (defun js2-print-continue-node (n i)
   (insert (js2-make-pad i) "continue")
@@ -3275,8 +3291,8 @@ The `params' field is a Lisp list of nodes.  Each node is 
either a simple
   async            ; t if the function is defined as `async function`
   member-expr)     ; nonstandard Ecma extension from Rhino
 
-(put 'cl-struct-js2-function-node 'js2-visitor 'js2-visit-function-node)
-(put 'cl-struct-js2-function-node 'js2-printer 'js2-print-function-node)
+(js2--struct-put 'js2-function-node 'js2-visitor 'js2-visit-function-node)
+(js2--struct-put 'js2-function-node 'js2-printer 'js2-print-function-node)
 
 (defun js2-visit-function-node (n v)
   (js2-visit-ast (js2-function-node-name n) v)
@@ -3351,8 +3367,8 @@ declarations, the node begins at the position of the 
first child."
   kids        ; a Lisp list of `js2-var-init-node' structs.
   decl-type)  ; js2-VAR, js2-CONST or js2-LET
 
-(put 'cl-struct-js2-var-decl-node 'js2-visitor 'js2-visit-var-decl)
-(put 'cl-struct-js2-var-decl-node 'js2-printer 'js2-print-var-decl)
+(js2--struct-put 'js2-var-decl-node 'js2-visitor 'js2-visit-var-decl)
+(js2--struct-put 'js2-var-decl-node 'js2-printer 'js2-print-var-decl)
 
 (defun js2-visit-var-decl (n v)
   (dolist (kid (js2-var-decl-node-kids n))
@@ -3389,8 +3405,8 @@ The type field will be js2-CONST for a const decl."
   target        ; `js2-name-node', `js2-object-node', or `js2-array-node'
   initializer)  ; initializer expression, a `js2-node'
 
-(put 'cl-struct-js2-var-init-node 'js2-visitor 'js2-visit-var-init-node)
-(put 'cl-struct-js2-var-init-node 'js2-printer 'js2-print-var-init-node)
+(js2--struct-put 'js2-var-init-node 'js2-visitor 'js2-visit-var-init-node)
+(js2--struct-put 'js2-var-init-node 'js2-printer 'js2-print-var-init-node)
 
 (defun js2-visit-var-init-node (n v)
   (js2-visit-ast (js2-var-init-node-target n) v)
@@ -3423,8 +3439,8 @@ The type field will be js2-CONST for a const decl."
   q-pos   ; buffer position of ?
   c-pos)  ; buffer position of :
 
-(put 'cl-struct-js2-cond-node 'js2-visitor 'js2-visit-cond-node)
-(put 'cl-struct-js2-cond-node 'js2-printer 'js2-print-cond-node)
+(js2--struct-put 'js2-cond-node 'js2-visitor 'js2-visit-cond-node)
+(js2--struct-put 'js2-cond-node 'js2-printer 'js2-print-cond-node)
 
 (defun js2-visit-cond-node (n v)
   (js2-visit-ast (js2-cond-node-test-expr n) v)
@@ -3454,8 +3470,8 @@ The type field inherited from `js2-node' holds the 
operator."
   left      ; any `js2-node'
   right)    ; any `js2-node'
 
-(put 'cl-struct-js2-infix-node 'js2-visitor 'js2-visit-infix-node)
-(put 'cl-struct-js2-infix-node 'js2-printer 'js2-print-infix-node)
+(js2--struct-put 'js2-infix-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-infix-node 'js2-printer 'js2-print-infix-node)
 
 (defun js2-visit-infix-node (n v)
   (js2-visit-ast (js2-infix-node-left n) v)
@@ -3541,8 +3557,8 @@ The type field inherited from `js2-node' holds the 
operator."
   "Represents any assignment.
 The type field holds the actual assignment operator.")
 
-(put 'cl-struct-js2-assign-node 'js2-visitor 'js2-visit-infix-node)
-(put 'cl-struct-js2-assign-node 'js2-printer 'js2-print-infix-node)
+(js2--struct-put 'js2-assign-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-assign-node 'js2-printer 'js2-print-infix-node)
 
 (cl-defstruct (js2-unary-node
                (:include js2-node)
@@ -3556,8 +3572,8 @@ TYPEOF, DELPROP, TRIPLEDOT or AWAIT.  For INC or DEC, a 
'postfix node
 property is added if the operator follows the operand."
   operand)  ; a `js2-node' expression
 
-(put 'cl-struct-js2-unary-node 'js2-visitor 'js2-visit-unary-node)
-(put 'cl-struct-js2-unary-node 'js2-printer 'js2-print-unary-node)
+(js2--struct-put 'js2-unary-node 'js2-visitor 'js2-visit-unary-node)
+(js2--struct-put 'js2-unary-node 'js2-printer 'js2-print-unary-node)
 
 (defun js2-visit-unary-node (n v)
   (js2-visit-ast (js2-unary-node-operand n) v))
@@ -3594,8 +3610,8 @@ Note that a let declaration such as let x=6, y=7 is a 
`js2-var-decl-node'."
   lp
   rp)
 
-(put 'cl-struct-js2-let-node 'js2-visitor 'js2-visit-let-node)
-(put 'cl-struct-js2-let-node 'js2-printer 'js2-print-let-node)
+(js2--struct-put 'js2-let-node 'js2-visitor 'js2-visit-let-node)
+(js2--struct-put 'js2-let-node 'js2-printer 'js2-print-let-node)
 
 (defun js2-visit-let-node (n v)
   (js2-visit-ast (js2-let-node-vars n) v)
@@ -3619,8 +3635,8 @@ Note that a let declaration such as let x=6, y=7 is a 
`js2-var-decl-node'."
 Used for `null', `this', `true', `false' and `debugger'.
 The node type is set to js2-NULL, js2-THIS, etc.")
 
-(put 'cl-struct-js2-keyword-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-keyword-node 'js2-printer 'js2-print-keyword-node)
+(js2--struct-put 'js2-keyword-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-keyword-node 'js2-printer 'js2-print-keyword-node)
 
 (defun js2-print-keyword-node (n i)
   (insert (js2-make-pad i)
@@ -3654,8 +3670,8 @@ The node type is set to js2-NULL, js2-THIS, etc.")
   rp      ; position of right-paren, nil if omitted
   initializer) ; experimental Rhino syntax:  optional `js2-object-node'
 
-(put 'cl-struct-js2-new-node 'js2-visitor 'js2-visit-new-node)
-(put 'cl-struct-js2-new-node 'js2-printer 'js2-print-new-node)
+(js2--struct-put 'js2-new-node 'js2-visitor 'js2-visit-new-node)
+(js2--struct-put 'js2-new-node 'js2-printer 'js2-print-new-node)
 
 (defun js2-visit-new-node (n v)
   (js2-visit-ast (js2-new-node-target n) v)
@@ -3685,8 +3701,8 @@ The node type is set to js2-NULL, js2-THIS, etc.")
   name   ; a string
   scope) ; a `js2-scope' (optional, used for codegen)
 
-(put 'cl-struct-js2-name-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-name-node 'js2-printer 'js2-print-name-node)
+(js2--struct-put 'js2-name-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-name-node 'js2-printer 'js2-print-name-node)
 
 (defun js2-print-name-node (n i)
   (insert (js2-make-pad i)
@@ -3719,8 +3735,8 @@ Returns 0 if NODE is nil or its identifier field is nil."
   num-base  ; the number's base
   legacy-octal-p)  ; whether the number is a legacy octal (0123 instead of 
0o123)
 
-(put 'cl-struct-js2-number-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-number-node 'js2-printer 'js2-print-number-node)
+(js2--struct-put 'js2-number-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-number-node 'js2-printer 'js2-print-number-node)
 
 (defun js2-print-number-node (n i)
   (insert (js2-make-pad i)
@@ -3738,8 +3754,8 @@ Returns 0 if NODE is nil or its identifier field is nil."
   value  ; the regexp string, without // delimiters
   flags) ; a string of flags, e.g. `mi'.
 
-(put 'cl-struct-js2-regexp-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-regexp-node 'js2-printer 'js2-print-regexp)
+(js2--struct-put 'js2-regexp-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-regexp-node 'js2-printer 'js2-print-regexp)
 
 (defun js2-print-regexp (n i)
   (insert (js2-make-pad i)
@@ -3762,8 +3778,8 @@ Escape characters are not evaluated; e.g. \n is 2 chars 
in value field.
 You can tell the quote type by looking at the first character."
   value) ; the characters of the string, including the quotes
 
-(put 'cl-struct-js2-string-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-string-node 'js2-printer 'js2-print-string-node)
+(js2--struct-put 'js2-string-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-string-node 'js2-printer 'js2-print-string-node)
 
 (defun js2-print-string-node (n i)
   (insert (js2-make-pad i)
@@ -3778,8 +3794,8 @@ You can tell the quote type by looking at the first 
character."
   kids)  ; `js2-string-node' is used for string segments, other nodes
          ; for substitutions inside.
 
-(put 'cl-struct-js2-template-node 'js2-visitor 'js2-visit-template)
-(put 'cl-struct-js2-template-node 'js2-printer 'js2-print-template)
+(js2--struct-put 'js2-template-node 'js2-visitor 'js2-visit-template)
+(js2--struct-put 'js2-template-node 'js2-printer 'js2-print-template)
 
 (defun js2-visit-template (n callback)
   (dolist (kid (js2-template-node-kids n))
@@ -3801,8 +3817,8 @@ You can tell the quote type by looking at the first 
character."
   tag       ; `js2-node' with the tag expression.
   template) ; `js2-template-node' with the template.
 
-(put 'cl-struct-js2-tagged-template-node 'js2-visitor 
'js2-visit-tagged-template)
-(put 'cl-struct-js2-tagged-template-node 'js2-printer 
'js2-print-tagged-template)
+(js2--struct-put 'js2-tagged-template-node 'js2-visitor 
'js2-visit-tagged-template)
+(js2--struct-put 'js2-tagged-template-node 'js2-printer 
'js2-print-tagged-template)
 
 (defun js2-visit-tagged-template (n callback)
   (js2-visit-ast (js2-tagged-template-node-tag n) callback)
@@ -3822,8 +3838,8 @@ You can tell the quote type by looking at the first 
character."
   "AST node for an array literal."
   elems)  ; list of expressions.  [foo,,bar] yields a nil middle element.
 
-(put 'cl-struct-js2-array-node 'js2-visitor 'js2-visit-array-node)
-(put 'cl-struct-js2-array-node 'js2-printer 'js2-print-array-node)
+(js2--struct-put 'js2-array-node 'js2-visitor 'js2-visit-array-node)
+(js2--struct-put 'js2-array-node 'js2-printer 'js2-print-array-node)
 
 (defun js2-visit-array-node (n v)
   (dolist (e (js2-array-node-elems n))
@@ -3848,8 +3864,8 @@ You can tell the quote type by looking at the first 
character."
 `elems' is a list of `js2-object-prop-node'."
   elems)
 
-(put 'cl-struct-js2-object-node 'js2-visitor 'js2-visit-object-node)
-(put 'cl-struct-js2-object-node 'js2-printer 'js2-print-object-node)
+(js2--struct-put 'js2-object-node 'js2-visitor 'js2-visit-object-node)
+(js2--struct-put 'js2-object-node 'js2-printer 'js2-print-object-node)
 
 (defun js2-visit-object-node (n v)
   (dolist (e (js2-object-node-elems n))
@@ -3876,8 +3892,8 @@ optional `js2-expr-node'"
   extends          ; class heritage (a `js2-expr-node', or nil if none)
   )
 
-(put 'cl-struct-js2-class-node 'js2-visitor 'js2-visit-class-node)
-(put 'cl-struct-js2-class-node 'js2-printer 'js2-print-class-node)
+(js2--struct-put 'js2-class-node 'js2-visitor 'js2-visit-class-node)
+(js2--struct-put 'js2-class-node 'js2-printer 'js2-print-class-node)
 
 (defun js2-visit-class-node (n v)
   (js2-visit-ast (js2-class-node-name n) v)
@@ -3919,8 +3935,8 @@ optional `js2-expr-node'"
   "AST node for a `ComputedPropertyName'."
   expr)
 
-(put 'cl-struct-js2-computed-prop-name-node 'js2-visitor 
'js2-visit-computed-prop-name-node)
-(put 'cl-struct-js2-computed-prop-name-node 'js2-printer 
'js2-print-computed-prop-name-node)
+(js2--struct-put 'js2-computed-prop-name-node 'js2-visitor 
'js2-visit-computed-prop-name-node)
+(js2--struct-put 'js2-computed-prop-name-node 'js2-printer 
'js2-print-computed-prop-name-node)
 
 (defun js2-visit-computed-prop-name-node (n v)
   (js2-visit-ast (js2-computed-prop-name-node-expr n) v))
@@ -3944,8 +3960,8 @@ number node or expression node.  The `right' field is a
 is abbreviated, the node's `SHORTHAND' property is non-nil and
 both fields have the same value.")
 
-(put 'cl-struct-js2-object-prop-node 'js2-visitor 'js2-visit-infix-node)
-(put 'cl-struct-js2-object-prop-node 'js2-printer 'js2-print-object-prop-node)
+(js2--struct-put 'js2-object-prop-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-object-prop-node 'js2-printer 
'js2-print-object-prop-node)
 
 (defun js2-print-object-prop-node (n i)
   (let* ((left (js2-object-prop-node-left n))
@@ -3966,8 +3982,8 @@ The `left' field is the `js2-name-node' naming the method.
 The `right' field is always an anonymous `js2-function-node' with a node
 property `METHOD_TYPE' set to 'GET or 'SET. ")
 
-(put 'cl-struct-js2-method-node 'js2-visitor 'js2-visit-infix-node)
-(put 'cl-struct-js2-method-node 'js2-printer 'js2-print-method)
+(js2--struct-put 'js2-method-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-method-node 'js2-printer 'js2-print-method)
 
 (defun js2-print-method (n i)
   (let* ((pad (js2-make-pad i))
@@ -3994,8 +4010,8 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
                                                           len left right)))
   "AST node for a dotted property reference, e.g. foo.bar or foo().bar")
 
-(put 'cl-struct-js2-prop-get-node 'js2-visitor 'js2-visit-prop-get-node)
-(put 'cl-struct-js2-prop-get-node 'js2-printer 'js2-print-prop-get-node)
+(js2--struct-put 'js2-prop-get-node 'js2-visitor 'js2-visit-prop-get-node)
+(js2--struct-put 'js2-prop-get-node 'js2-printer 'js2-print-prop-get-node)
 
 (defun js2-visit-prop-get-node (n v)
   (js2-visit-ast (js2-prop-get-node-left n) v)
@@ -4020,8 +4036,8 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
   lb      ; position of left-bracket, nil if omitted
   rb)     ; position of right-bracket, nil if omitted
 
-(put 'cl-struct-js2-elem-get-node 'js2-visitor 'js2-visit-elem-get-node)
-(put 'cl-struct-js2-elem-get-node 'js2-printer 'js2-print-elem-get-node)
+(js2--struct-put 'js2-elem-get-node 'js2-visitor 'js2-visit-elem-get-node)
+(js2--struct-put 'js2-elem-get-node 'js2-printer 'js2-print-elem-get-node)
 
 (defun js2-visit-elem-get-node (n v)
   (js2-visit-ast (js2-elem-get-node-target n) v)
@@ -4047,8 +4063,8 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
   lp    ; position of open-paren, or nil if missing
   rp)   ; position of close-paren, or nil if missing
 
-(put 'cl-struct-js2-call-node 'js2-visitor 'js2-visit-call-node)
-(put 'cl-struct-js2-call-node 'js2-printer 'js2-print-call-node)
+(js2--struct-put 'js2-call-node 'js2-visitor 'js2-visit-call-node)
+(js2--struct-put 'js2-call-node 'js2-printer 'js2-print-call-node)
 
 (defun js2-visit-call-node (n v)
   (js2-visit-ast (js2-call-node-target n) v)
@@ -4072,8 +4088,8 @@ property `METHOD_TYPE' set to 'GET or 'SET. ")
   star-p ; whether it's yield*
   value) ; optional:  value to be yielded
 
-(put 'cl-struct-js2-yield-node 'js2-visitor 'js2-visit-yield-node)
-(put 'cl-struct-js2-yield-node 'js2-printer 'js2-print-yield-node)
+(js2--struct-put 'js2-yield-node 'js2-visitor 'js2-visit-yield-node)
+(js2--struct-put 'js2-yield-node 'js2-printer 'js2-print-yield-node)
 
 (defun js2-visit-yield-node (n v)
   (js2-visit-ast (js2-yield-node-value n) v))
@@ -4098,8 +4114,8 @@ In particular, used when the parens are syntactically 
optional,
 as opposed to required parens such as those enclosing an if-conditional."
   expr)   ; `js2-node'
 
-(put 'cl-struct-js2-paren-node 'js2-visitor 'js2-visit-paren-node)
-(put 'cl-struct-js2-paren-node 'js2-printer 'js2-print-paren-node)
+(js2--struct-put 'js2-paren-node 'js2-visitor 'js2-visit-paren-node)
+(js2--struct-put 'js2-paren-node 'js2-printer 'js2-print-paren-node)
 
 (defun js2-visit-paren-node (n v)
   (js2-visit-ast (js2-paren-node-expr n) v))
@@ -4126,8 +4142,8 @@ as opposed to required parens such as those enclosing an 
if-conditional."
           ; SpiderMonkey also supports "legacy generator expressions", but we 
dont.
   )
 
-(put 'cl-struct-js2-comp-node 'js2-visitor 'js2-visit-comp-node)
-(put 'cl-struct-js2-comp-node 'js2-printer 'js2-print-comp-node)
+(js2--struct-put 'js2-comp-node 'js2-visitor 'js2-visit-comp-node)
+(js2--struct-put 'js2-comp-node 'js2-printer 'js2-print-comp-node)
 
 (defun js2-visit-comp-node (n v)
   (js2-visit-ast (js2-comp-node-result n) v)
@@ -4177,8 +4193,8 @@ as opposed to required parens such as those enclosing an 
if-conditional."
                                                            lp rp)))
   "AST subtree for each 'for (foo in bar)' loop in an array comprehension.")
 
-(put 'cl-struct-js2-comp-loop-node 'js2-visitor 'js2-visit-comp-loop)
-(put 'cl-struct-js2-comp-loop-node 'js2-printer 'js2-print-comp-loop)
+(js2--struct-put 'js2-comp-loop-node 'js2-visitor 'js2-visit-comp-loop)
+(js2--struct-put 'js2-comp-loop-node 'js2-printer 'js2-print-comp-loop)
 
 (defun js2-visit-comp-loop (n v)
   (js2-visit-ast (js2-comp-loop-node-iterator n) v)
@@ -4202,8 +4218,8 @@ as opposed to required parens such as those enclosing an 
if-conditional."
                                                             len)))
   "AST node for an empty expression.")
 
-(put 'cl-struct-js2-empty-expr-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-empty-expr-node 'js2-printer 'js2-print-none)
+(js2--struct-put 'js2-empty-expr-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-empty-expr-node 'js2-printer 'js2-print-none)
 
 (cl-defstruct (js2-xml-node
                (:include js2-block-node)
@@ -4215,8 +4231,8 @@ as opposed to required parens such as those enclosing an 
if-conditional."
 The kids field is a list of XML fragments, each a `js2-string-node' or
 a `js2-xml-js-expr-node'.  Equivalent to Rhino's XmlLiteral node.")
 
-(put 'cl-struct-js2-xml-node 'js2-visitor 'js2-visit-block)
-(put 'cl-struct-js2-xml-node 'js2-printer 'js2-print-xml-node)
+(js2--struct-put 'js2-xml-node 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-xml-node 'js2-printer 'js2-print-xml-node)
 
 (defun js2-print-xml-node (n i)
   (dolist (kid (js2-xml-node-kids n))
@@ -4232,8 +4248,8 @@ a `js2-xml-js-expr-node'.  Equivalent to Rhino's 
XmlLiteral node.")
 The start and end fields correspond to the curly-braces."
   expr)  ; a `js2-expr-node' of some sort
 
-(put 'cl-struct-js2-xml-js-expr-node 'js2-visitor 'js2-visit-xml-js-expr)
-(put 'cl-struct-js2-xml-js-expr-node 'js2-printer 'js2-print-xml-js-expr)
+(js2--struct-put 'js2-xml-js-expr-node 'js2-visitor 'js2-visit-xml-js-expr)
+(js2--struct-put 'js2-xml-js-expr-node 'js2-printer 'js2-print-xml-js-expr)
 
 (defun js2-visit-xml-js-expr (n v)
   (js2-visit-ast (js2-xml-js-expr-node-expr n) v))
@@ -4257,8 +4273,8 @@ following the dot (.) in the operator.  No whitespace is 
permitted
 between the dot and the lp by the scanner."
   rp)
 
-(put 'cl-struct-js2-xml-dot-query-node 'js2-visitor 'js2-visit-infix-node)
-(put 'cl-struct-js2-xml-dot-query-node 'js2-printer 'js2-print-xml-dot-query)
+(js2--struct-put 'js2-xml-dot-query-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-xml-dot-query-node 'js2-printer 'js2-print-xml-dot-query)
 
 (defun js2-print-xml-dot-query (n i)
   (insert (js2-make-pad i))
@@ -4323,8 +4339,8 @@ or if it is missing due to a syntax error, through the 
end of the index
 expression."
   propname)
 
-(put 'cl-struct-js2-xml-prop-ref-node 'js2-visitor 
'js2-visit-xml-prop-ref-node)
-(put 'cl-struct-js2-xml-prop-ref-node 'js2-printer 
'js2-print-xml-prop-ref-node)
+(js2--struct-put 'js2-xml-prop-ref-node 'js2-visitor 
'js2-visit-xml-prop-ref-node)
+(js2--struct-put 'js2-xml-prop-ref-node 'js2-printer 
'js2-print-xml-prop-ref-node)
 
 (defun js2-visit-xml-prop-ref-node (n v)
   (js2-visit-ast (js2-xml-prop-ref-node-namespace n) v)
@@ -4369,8 +4385,8 @@ end of the index expression."
   lb
   rb)
 
-(put 'cl-struct-js2-xml-elem-ref-node 'js2-visitor 
'js2-visit-xml-elem-ref-node)
-(put 'cl-struct-js2-xml-elem-ref-node 'js2-printer 
'js2-print-xml-elem-ref-node)
+(js2--struct-put 'js2-xml-elem-ref-node 'js2-visitor 
'js2-visit-xml-elem-ref-node)
+(js2--struct-put 'js2-xml-elem-ref-node 'js2-printer 
'js2-print-xml-elem-ref-node)
 
 (defun js2-visit-xml-elem-ref-node (n v)
   (js2-visit-ast (js2-xml-elem-ref-node-namespace n) v)
@@ -4403,8 +4419,8 @@ The `kids' field is a Lisp list of child content nodes."
   attrs     ; a Lisp list of `js2-xml-attr-node'
   empty-p)  ; t if this is an empty element such as <foo bar="baz"/>
 
-(put 'cl-struct-js2-xml-start-tag-node 'js2-visitor 'js2-visit-xml-start-tag)
-(put 'cl-struct-js2-xml-start-tag-node 'js2-printer 'js2-print-xml-start-tag)
+(js2--struct-put 'js2-xml-start-tag-node 'js2-visitor 'js2-visit-xml-start-tag)
+(js2--struct-put 'js2-xml-start-tag-node 'js2-printer 'js2-print-xml-start-tag)
 
 (defun js2-visit-xml-start-tag (n v)
   (js2-visit-ast (js2-xml-start-tag-node-name n) v)
@@ -4431,8 +4447,8 @@ The `kids' field is a Lisp list of child content nodes."
   "AST node for an XML end-tag.  Not currently used."
   name)  ; a `js2-xml-name-node'
 
-(put 'cl-struct-js2-xml-end-tag-node 'js2-visitor 'js2-visit-xml-end-tag)
-(put 'cl-struct-js2-xml-end-tag-node 'js2-printer 'js2-print-xml-end-tag)
+(js2--struct-put 'js2-xml-end-tag-node 'js2-visitor 'js2-visit-xml-end-tag)
+(js2--struct-put 'js2-xml-end-tag-node 'js2-printer 'js2-print-xml-end-tag)
 
 (defun js2-visit-xml-end-tag (n v)
   (js2-visit-ast (js2-xml-end-tag-node-name n) v))
@@ -4456,8 +4472,8 @@ The kids field is a list of `js2-name-node' and 
`js2-xml-js-expr-node'.
 For a simple name, the kids list has exactly one node, a `js2-name-node'."
   namespace)  ; a `js2-string-node'
 
-(put 'cl-struct-js2-xml-name-node 'js2-visitor 'js2-visit-xml-name-node)
-(put 'cl-struct-js2-xml-name-node 'js2-printer 'js2-print-xml-name-node)
+(js2--struct-put 'js2-xml-name-node 'js2-visitor 'js2-visit-xml-name-node)
+(js2--struct-put 'js2-xml-name-node 'js2-printer 'js2-print-xml-name-node)
 
 (defun js2-visit-xml-name-node (n v)
   (js2-visit-ast (js2-xml-name-node-namespace n) v))
@@ -4480,8 +4496,8 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
   name   ; a `js2-xml-name-node'
   attrs) ; a list of `js2-xml-attr-node'
 
-(put 'cl-struct-js2-xml-pi-node 'js2-visitor 'js2-visit-xml-pi-node)
-(put 'cl-struct-js2-xml-pi-node 'js2-printer 'js2-print-xml-pi-node)
+(js2--struct-put 'js2-xml-pi-node 'js2-visitor 'js2-visit-xml-pi-node)
+(js2--struct-put 'js2-xml-pi-node 'js2-printer 'js2-print-xml-pi-node)
 
 (defun js2-visit-xml-pi-node (n v)
   (js2-visit-ast (js2-xml-pi-node-name n) v)
@@ -4505,8 +4521,8 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
   "AST node for a CDATA escape section.  Not currently used."
   content)  ; a `js2-string-node' with node-property 'quote-type 'cdata
 
-(put 'cl-struct-js2-xml-cdata-node 'js2-visitor 'js2-visit-xml-cdata-node)
-(put 'cl-struct-js2-xml-cdata-node 'js2-printer 'js2-print-xml-cdata-node)
+(js2--struct-put 'js2-xml-cdata-node 'js2-visitor 'js2-visit-xml-cdata-node)
+(js2--struct-put 'js2-xml-cdata-node 'js2-printer 'js2-print-xml-cdata-node)
 
 (defun js2-visit-xml-cdata-node (n v)
   (js2-visit-ast (js2-xml-cdata-node-content n) v))
@@ -4528,8 +4544,8 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
   eq-pos ; buffer position of "=" sign
   quote-type) ; 'single or 'double
 
-(put 'cl-struct-js2-xml-attr-node 'js2-visitor 'js2-visit-xml-attr-node)
-(put 'cl-struct-js2-xml-attr-node 'js2-printer 'js2-print-xml-attr-node)
+(js2--struct-put 'js2-xml-attr-node 'js2-visitor 'js2-visit-xml-attr-node)
+(js2--struct-put 'js2-xml-attr-node 'js2-printer 'js2-print-xml-attr-node)
 
 (defun js2-visit-xml-attr-node (n v)
   (js2-visit-ast (js2-xml-attr-node-name n) v)
@@ -4554,8 +4570,8 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
   "AST node for an E4X XML text node.  Not currently used."
   content)  ; a Lisp list of `js2-string-node' and `js2-xml-js-expr-node'
 
-(put 'cl-struct-js2-xml-text-node 'js2-visitor 'js2-visit-xml-text-node)
-(put 'cl-struct-js2-xml-text-node 'js2-printer 'js2-print-xml-text-node)
+(js2--struct-put 'js2-xml-text-node 'js2-visitor 'js2-visit-xml-text-node)
+(js2--struct-put 'js2-xml-text-node 'js2-printer 'js2-print-xml-text-node)
 
 (defun js2-visit-xml-text-node (n v)
   (js2-visit-ast (js2-xml-text-node-content n) v))
@@ -4573,8 +4589,8 @@ For a simple name, the kids list has exactly one node, a 
`js2-name-node'."
                                                              len)))
   "AST node for E4X XML comment.  Not currently used.")
 
-(put 'cl-struct-js2-xml-comment-node 'js2-visitor 'js2-visit-none)
-(put 'cl-struct-js2-xml-comment-node 'js2-printer 'js2-print-xml-comment)
+(js2--struct-put 'js2-xml-comment-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-xml-comment-node 'js2-printer 'js2-print-xml-comment)
 
 (defun js2-print-xml-comment (n i)
   (insert (js2-make-pad i)
@@ -5141,8 +5157,6 @@ You should use `js2-print-tree' instead of this function."
                       js2-WITHEXPR
                       js2-YIELD))
       (aset tokens tt t))
-    (if js2-instanceof-has-side-effects
-        (aset tokens js2-INSTANCEOF t))
     tokens))
 
 (defun js2-node-has-side-effects (node)
@@ -5159,8 +5173,7 @@ You should use `js2-print-tree' instead of this function."
           (or (js2-node-has-side-effects expr)
               (when (js2-string-node-p expr)
                 (member (js2-string-node-value expr) '("use strict" "use 
asm"))))))
-       ((= tt js2-AWAIT)
-        (js2-node-has-side-effects (js2-unary-node-operand node)))
+       ((= tt js2-AWAIT) t)
        ((= tt js2-COMMA)
         (js2-node-has-side-effects (js2-infix-node-right node)))
        ((or (= tt js2-AND)
@@ -5174,6 +5187,9 @@ You should use `js2-print-tree' instead of this function."
         (js2-node-has-side-effects (js2-paren-node-expr node)))
        ((= tt js2-ERROR) ; avoid cascaded error messages
         nil)
+       ((or (and js2-instanceof-has-side-effects (= tt js2-INSTANCEOF))
+            (and js2-getprop-has-side-effects (= tt js2-GETPROP)))
+        t)
        (t
         (aref js2-side-effecting-tokens tt))))))
 
@@ -6941,7 +6957,7 @@ of a simple name.  Called before EXPR has a parent node."
              "throws"
              "type"
              "version"))
-          "\\)\\)\\s-+\\([^ \t]+\\)")
+          "\\)\\)\\s-+\\([^ \t\n]+\\)")
   "Matches jsdoc tags with a single argument.")
 
 (defconst js2-jsdoc-empty-tag-regexp
@@ -7188,6 +7204,10 @@ When STRICT, signal an error if NODE is not one of the 
expected types."
             (setq targets (append
                            (js2--collect-target-symbols subexpr strict)
                            targets))))))
+     ((js2-assign-node-p node)
+      (setq targets (append (js2--collect-target-symbols
+                             (js2-assign-node-left node) strict)
+                            targets)))
      (strict
       (js2-report-error "msg.no.parm" nil (js2-node-abs-pos node)
                         (js2-node-len node))
@@ -7362,23 +7382,23 @@ are ignored."
     (remove-hook 'js2-post-parse-callbacks
                  #'js2-highlight-unused-variables t)))
 
-(defun js2-apply-jslint-globals ()
+(defun js2-add-additional-externs (externs)
   (setq js2-additional-externs
-        (nconc (js2-get-jslint-globals)
+        (nconc externs
                js2-additional-externs)))
 
-(defun js2-get-jslint-globals ()
+(defun js2-get-jslint-comment-identifiers (comment)
   (js2-reparse)
   (cl-loop for node in (js2-ast-root-comments js2-mode-ast)
            when (and (eq 'block (js2-comment-node-format node))
                      (save-excursion
                        (goto-char (js2-node-abs-pos node))
-                       (looking-at "/\\* *global\\(?: \\|$\\)")))
-           append (js2-get-jslint-globals-in
+                       (looking-at (concat "/\\* *" comment "\\(?: \\|$\\)"))))
+           append (js2-get-jslint-comment-identifiers-in
                    (match-end 0)
                    (js2-node-abs-end node))))
 
-(defun js2-get-jslint-globals-in (beg end)
+(defun js2-get-jslint-comment-identifiers-in (beg end)
   (let (res)
     (save-excursion
       (goto-char beg)
@@ -7388,6 +7408,48 @@ are ignored."
             (push match res)))))
     (nreverse res)))
 
+(defun js2-apply-jslint-globals ()
+  (js2-add-additional-externs (js2-get-jslint-globals)))
+
+(defun js2-get-jslint-globals ()
+  (js2-get-jslint-comment-identifiers "global"))
+
+(defun js2-apply-jslint-declaration-externs ()
+  (js2-add-additional-externs (js2-get-jslint-declaration-externs)))
+
+(defvar js2-jslint-declaration-externs
+  `(("browser" . ,(mapcar 'symbol-name
+                          '(Audio clearInterval clearTimeout document
+                            event history Image location name
+                            navigator Option screen setInterval
+                            setTimeout XMLHttpRequest)))
+    ("node" . ,(mapcar 'symbol-name
+                       '(Buffer clearImmediate clearInterval
+                         clearTimeout console exports global module
+                         process querystring require setImmediate
+                         setInterval setTimeout __dirname
+                         __filename)))
+    ("es6" . ,(mapcar 'symbol-name
+                      '(ArrayBuffer DataView Float32Array
+                        Float64Array Int8Array Int16Array Int32Array
+                        Intl Map Promise Proxy Reflect Set Symbol
+                        System Uint8Array Uint8ClampedArray
+                        Uint16Array Uint32Array WeakMap WeakSet)))
+    ("couch" . ,(mapcar 'symbol-name
+                        '(emit getRow isArray log provides
+                          registerType require send start sum
+                          toJSON)))
+    ("devel" . ,(mapcar 'symbol-name
+                        '(alert confirm console Debug opera prompt
+                          WSH)))))
+
+(defun js2-get-jslint-declaration-externs ()
+  (apply 'append
+         (mapcar (lambda (identifier)
+                   (cdr (assoc identifier
+                               js2-jslint-declaration-externs)))
+                 (js2-get-jslint-comment-identifiers "jslint"))))
+
 ;;; IMenu support
 
 ;; We currently only support imenu, but eventually should support speedbar and
@@ -7486,9 +7548,12 @@ returns nil.  Otherwise returns the string name/value of 
the node."
 Returns nil if the node doesn't contribute."
   (copy-sequence
    (or (js2-prop-node-name node)
-       (if (and (js2-function-node-p node)
-                (js2-function-node-name node))
-           (js2-name-node-name (js2-function-node-name node))))))
+       (cond
+        ((and (js2-function-node-p node)
+              (js2-function-node-name node))
+         (js2-name-node-name (js2-function-node-name node)))
+        ((js2-computed-prop-name-node-p node)
+         "[computed]")))))
 
 (defun js2-record-imenu-entry (fn-node qname pos)
   "Add an entry to `js2-imenu-recorder'.
@@ -8130,11 +8195,23 @@ Scanner should be initialized."
     (setq js2-mode-ast root)  ; Make sure this is available for callbacks.
     ;; Give extensions a chance to muck with things before highlighting starts.
     (let ((js2-additional-externs js2-additional-externs))
+      (js2-filter-parsed-warnings)
       (save-excursion
         (run-hooks 'js2-post-parse-callbacks))
       (js2-highlight-undeclared-vars))
     root))
 
+(defun js2-filter-parsed-warnings ()
+  "Remove `js2-parsed-warnings' elements that match `js2-ignored-warnings'."
+  (when js2-ignored-warnings
+    (setq js2-parsed-warnings
+          (cl-remove-if
+           (lambda (warning)
+             (let ((msg (caar warning)))
+               (member msg js2-ignored-warnings)))
+           js2-parsed-warnings)))
+  js2-parsed-warnings)
+
 (defun js2-parse-function-closure-body (fn-node)
   "Parse a JavaScript 1.8 function closure body."
   (let ((js2-nesting-of-function (1+ js2-nesting-of-function)))
@@ -8291,7 +8368,9 @@ represented by FN-NODE at POS."
                  (js2-report-error "msg.param.after.rest" nil
                                    (js2-node-pos param) (js2-node-len param)))
                while
-               (js2-match-token js2-COMMA))
+               (and (js2-match-token js2-COMMA)
+                    (or (< js2-language-version 200)
+                        (not (= js2-RP (js2-peek-token))))))
       (when (and (not paren-free-arrow)
                  (js2-must-match js2-RP "msg.no.paren.after.parms"))
         (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos)))
@@ -9345,7 +9424,7 @@ Last matched token must be js2-CONST or js2-VAR."
   (js2-parse-return-or-yield (js2-current-token-type) nil))
 
 (defconst js2-parse-return-stmt-enders
-  (list js2-SEMI js2-RC js2-EOF js2-EOL js2-ERROR js2-RB js2-RP js2-YIELD))
+  (list js2-SEMI js2-RC js2-EOF js2-EOL js2-ERROR js2-RB js2-RP))
 
 (defsubst js2-now-all-set (before after mask)
   "Return whether or not the bits in the mask have changed to all set.
@@ -9373,7 +9452,9 @@ but not BEFORE."
       (setq yield-star-p t))
     ;; This is ugly, but we don't want to require a semicolon.
     (unless (memq (js2-peek-token-or-eol) js2-parse-return-stmt-enders)
-      (setq e (js2-parse-expr)
+      (setq e (if (eq gen-type 'STAR)
+                  (js2-parse-assign-expr)
+                (js2-parse-expr))
             end (js2-node-end e)))
     (cond
      ((eq tt js2-RETURN)
@@ -9754,8 +9835,6 @@ If NODE is non-nil, it is the AST node associated with 
the symbol."
     (while (and (not oneshot)
                 (js2-match-token js2-COMMA))
       (setq op-pos (- (js2-current-token-beg) pos))  ; relative
-      (if (= (js2-peek-token) js2-YIELD)
-          (js2-report-error "msg.yield.parenthesized"))
       (setq right (js2-parse-assign-expr)
             left pn
             pn (make-js2-infix-node :type js2-COMMA
@@ -9815,8 +9894,11 @@ If NODE is non-nil, it is the AST node associated with 
the symbol."
           (js2-record-imenu-functions right left))
         ;; do this last so ide checks above can use absolute positions
         (js2-node-add-children pn left right))
-       ((and (= tt js2-ARROW)
-             (>= js2-language-version 200))
+       ((and (>= js2-language-version 200)
+             (or
+              (= tt js2-ARROW)
+              (and async-p
+                   (= (js2-peek-token) js2-ARROW))))
         (js2-ts-seek ts-state)
         (when async-p
           (js2-record-face 'font-lock-keyword-face)
@@ -10144,8 +10226,6 @@ Returns the list in reverse order.  Consumes the 
right-paren token."
     (unless (js2-match-token js2-RP)
       (cl-loop do
                (let ((tt (js2-get-token)))
-                 (if (= tt js2-YIELD)
-                     (js2-report-error "msg.yield.parenthesized"))
                  (if (and (= tt js2-TRIPLEDOT)
                           (>= js2-language-version 200))
                      (push (js2-make-unary tt 'js2-parse-assign-expr) result)
@@ -10877,7 +10957,7 @@ expression)."
        ;; Found a key/value property (of any sort)
        ((member tt (list js2-NAME js2-STRING js2-NUMBER js2-LB))
         (setq after-comma nil
-              elem (js2-parse-named-prop tt previous-token))
+              elem (js2-parse-named-prop tt previous-token class-p))
         (if (and (null elem)
                  (not js2-recover-from-parse-errors))
             (setq continue nil)))
@@ -10936,7 +11016,7 @@ expression)."
     (js2-must-match js2-RC "msg.no.brace.prop")
     (nreverse elems)))
 
-(defun js2-parse-named-prop (tt previous-token)
+(defun js2-parse-named-prop (tt previous-token &optional class-p)
   "Parse a name, string, or getter/setter object property.
 When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted."
   (let ((key (js2-parse-prop-name tt))
@@ -10959,17 +11039,18 @@ When `js2-is-in-destructuring' is t, forms like {a, 
b, c} will be permitted."
         ;; highlight function name properties
         (js2-record-face 'font-lock-function-name-face))
       (js2-parse-method-prop pos key property-type))
-     ;; binding element with initializer
+     ;; class field or binding element with initializer
      ((and (= (js2-peek-token) js2-ASSIGN)
            (>= js2-language-version 200))
-      (if (not js2-is-in-destructuring)
+      (if (not (or class-p
+                   js2-is-in-destructuring))
           (js2-report-error "msg.init.no.destruct"))
       (js2-parse-initialized-binding key))
      ;; regular prop
      (t
       (let ((beg (js2-current-token-beg))
             (end (js2-current-token-end))
-            (expr (js2-parse-plain-property key)))
+            (expr (js2-parse-plain-property key class-p)))
         (when (and (= tt js2-NAME)
                    (not js2-is-in-destructuring)
                    js2-highlight-external-variables
@@ -11011,20 +11092,22 @@ When `js2-is-in-destructuring' is t, forms like {a, 
b, c} will be permitted."
    ;; Anything else is an error
    (t (js2-report-error "msg.bad.prop"))))
 
-(defun js2-parse-plain-property (prop)
+(defun js2-parse-plain-property (prop &optional class-p)
   "Parse a non-getter/setter property in an object literal.
 PROP is the node representing the property: a number, name,
 string or expression."
-  (let* ((tt (js2-get-token))
+  (let* (tt
          (pos (js2-node-pos prop))
          colon expr result)
     (cond
-     ;; Abbreviated property, as in {foo, bar}
+     ;; Abbreviated property, as in {foo, bar} or class {a; b}
      ((and (>= js2-language-version 200)
-           (or (= tt js2-COMMA)
-               (= tt js2-RC))
-           (not (js2-number-node-p prop)))
-      (js2-unget-token)
+           (if class-p
+               (and (setq tt (js2-peek-token-or-eol))
+                    (member tt (list js2-EOL js2-RC js2-SEMI)))
+             (and (setq tt (js2-peek-token))
+                  (member tt (list js2-COMMA js2-RC))
+                  (js2-name-node-p prop))))
       (setq result (make-js2-object-prop-node
                     :pos pos
                     :left prop
@@ -11035,6 +11118,7 @@ string or expression."
       result)
      ;; Normal property
      (t
+      (setq tt (js2-get-token))
       (if (= tt js2-COLON)
           (setq colon (- (js2-current-token-beg) pos)
                 expr (js2-parse-assign-expr))
@@ -11491,6 +11575,8 @@ highlighting features of `js2-mode'."
   (add-hook 'change-major-mode-hook #'js2-minor-mode-exit nil t)
   (when js2-include-jslint-globals
     (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
+  (when js2-include-jslint-declaration-externs
+    (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs 
nil t))
   (run-hooks 'js2-init-hook)
   (js2-reparse))
 
@@ -11504,6 +11590,7 @@ highlighting features of `js2-mode'."
     (setq js2-mode-node-overlay nil))
   (js2-remove-overlays)
   (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals t)
+  (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs 
t)
   (setq js2-mode-ast nil))
 
 (defvar js2-source-buffer nil "Linked source buffer for diagnostics view")
@@ -11654,6 +11741,8 @@ Selecting an error will jump it to the corresponding 
source-buffer error.
 
   (when js2-include-jslint-globals
     (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
+  (when js2-include-jslint-declaration-externs
+    (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs 
nil t))
 
   (run-hooks 'js2-init-hook)
 
diff --git a/packages/js2-mode/js2-old-indent.el 
b/packages/js2-mode/js2-old-indent.el
index 0016861..5480695 100644
--- a/packages/js2-mode/js2-old-indent.el
+++ b/packages/js2-mode/js2-old-indent.el
@@ -58,7 +58,6 @@
 
 (defvar js2-language-version)
 
-(declare-function js2-mark-safe-local "js2-mode")
 (declare-function js2-backward-sws "js2-mode")
 (declare-function js2-forward-sws "js2-mode")
 (declare-function js2-same-line "js2-mode")
diff --git a/packages/js2-mode/tests/externs.el 
b/packages/js2-mode/tests/externs.el
index 3540f3c..f383e89 100644
--- a/packages/js2-mode/tests/externs.el
+++ b/packages/js2-mode/tests/externs.el
@@ -59,3 +59,68 @@
 ;;;TODO
 ;; ensure that any symbols bound with the import syntax are added to the 
extern list
 ;; ensure that any symbols bound with the export syntax exist in the file scope
+
+;; Test `/*jslint*/` declarations
+
+(ert-deftest js2-finds-jslint-declaration-externs ()
+  (with-temp-buffer
+    (insert "/*jslint browser: true, node: true*/")
+    (js2-mode)
+    (let ((found-externs (js2-get-jslint-declaration-externs)))
+      (should (and (member "navigator" found-externs)
+                   (member "__filename" found-externs))))))
+
+(ert-deftest js2-finds-jslint-declaration-externs-without-property-value ()
+  (with-temp-buffer
+    (insert "/*jslint devel, es6: true, couch")
+    (js2-mode)
+    (let ((found-externs (js2-get-jslint-declaration-externs)))
+      (should (and (member "prompt" found-externs)
+                   (member "Promise" found-externs)
+                   (member "require" found-externs))))))
+
+(ert-deftest js2-no-jslint-declaration-externs-without-keyword ()
+  (with-temp-buffer
+    (insert "/* browser: true, node: true*/")
+    (js2-mode)
+    (should (null (js2-get-jslint-declaration-externs)))))
+
+(ert-deftest js2-no-jslint-declaration-externs-for-nonexistent-env ()
+  (with-temp-buffer
+    (insert "/*jslint nonexistent: true*/")
+    (js2-mode)
+    (should (null (js2-get-jslint-declaration-externs)))))
+
+(ert-deftest js2-finding-jslint-declaration-externs-ignores-nonexistent ()
+  (with-temp-buffer
+    (insert "/*jslint es6: true, nonexistent: true, couch: true*/")
+    (js2-mode)
+    (let ((found-externs (js2-get-jslint-declaration-externs)))
+      (should (and (member "Map" found-externs)
+                   (member "emit" found-externs))))))
+
+(ert-deftest js2-finds-jslint-declaration-externs-in-other-comments ()
+  (with-temp-buffer
+    (insert "/* foo, bar */\n\n\n/*jslint devel: true, node: true*/")
+    (js2-mode)
+    (let ((found-externs (js2-get-jslint-declaration-externs)))
+      (should (and (member "Debug" found-externs)
+                   (member "exports" found-externs))))))
+
+(ert-deftest js2-finds-jslint-declaration-externs-with-space ()
+  (with-temp-buffer
+    (insert "/* jslint browser: true, couch:true,es6 :true */")
+    (js2-mode)
+    (let ((found-externs (js2-get-jslint-declaration-externs)))
+      (should (and (member "document" found-externs)
+                   (member "getRow" found-externs)
+                   (member "Proxy" found-externs))))))
+
+(ert-deftest js2-finds-jslint-globals-with-newline ()
+  (with-temp-buffer
+    (insert "/*jslint\nbrowser: true,\nnode:\ntrue\n, devel:\ntrue\n*/")
+    (js2-mode)
+    (let ((found-externs (js2-get-jslint-declaration-externs)))
+      (should (and (member "history" found-externs)
+                   (member "Buffer" found-externs)
+                   (member "alert" found-externs))))))
diff --git a/packages/js2-mode/tests/parser.el 
b/packages/js2-mode/tests/parser.el
index de97343..482ec8f 100644
--- a/packages/js2-mode/tests/parser.el
+++ b/packages/js2-mode/tests/parser.el
@@ -1,6 +1,6 @@
 ;;; tests/parser.el --- Some tests for js2-mode.
 
-;; Copyright (C) 2009, 2011-2016  Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2011-2017  Free Software Foundation, Inc.
 
 ;; This file is part of GNU Emacs.
 
@@ -300,6 +300,10 @@ the test."
 (js2-deftest-parse function-with-rest-after-default-parameter
   "function foo(a = 1, ...rest) {\n}")
 
+(js2-deftest-parse function-with-trailing-comma-in-param-list
+  "function foo(a, b,) {\n}"
+  :reference "function foo(a, b) {\n}")
+
 ;;; Strict mode errors
 
 (js2-deftest-parse function-bad-strict-parameters
@@ -456,6 +460,9 @@ the test."
 
 (js2-deftest-parse harmony-generator-yield-star "(function*(a) {  yield* 
a;\n});")
 
+(js2-deftest-parse harmony-generator-yield-assign-expr
+  "(function*() {  return {a: yield a, b: yield b, c: yield c};\n});")
+
 ;;; Comprehensions
 
 (js2-deftest-parse parse-legacy-array-comp-loop-with-filter
@@ -494,6 +501,9 @@ the test."
 (js2-deftest-parse async-arrow-function-expression
   "a = async (b) => {  b;\n};")
 
+(js2-deftest-parse async-arrow-function-without-parens
+  "a = async b => 3;" :reference "a = async (b) => {3};")
+
 (js2-deftest-parse async-method-in-object-literal
   "({async f() {}});")
 
@@ -582,7 +592,7 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-LC))
   (let ((imports (js2-parse-export-bindings)))
-    (should (not (equal nil imports)))
+    (should (not (null imports)))
     (should (= 2 (length imports)))
     (let ((first (nth 0 imports))
           (second (nth 1 imports)))
@@ -610,7 +620,7 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-MUL))
   (let ((namespace-import (js2-parse-namespace-import)))
-    (should (not (equal nil namespace-import)))
+    (should (not (null namespace-import)))
     (should (js2-namespace-import-node-p namespace-import))
     (should (= 1 (js2-node-pos namespace-import)))
     (should (equal 8 (js2-node-len namespace-import)))
@@ -621,7 +631,7 @@ the test."
 (js2-deftest parse-from-clause "from 'foo/bar';"
   (js2-init-scanner)
   (let ((from (js2-parse-from-clause)))
-    (should (not (equal nil from)))
+    (should (not (null from)))
     (should (= 1 (js2-node-pos from)))
     (should (= 14 (js2-node-len from)))
     (should (equal "foo/bar" (js2-from-clause-node-module-id from)))))
@@ -630,25 +640,25 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-IMPORT))
   (let ((import (js2-parse-import)))
-    (should (not (equal nil import)))
+    (should (not (null import)))
     (should (= 1 (js2-node-pos import)))
     (should (= 16 (js2-node-len import)))
-    (should (equal nil (js2-import-node-import import)))
-    (should (equal nil (js2-import-node-from import)))))
+    (should (null (js2-import-node-import import)))
+    (should (null (js2-import-node-from import)))))
 
 (js2-deftest parse-imported-default-binding "import theDefault from 'src/lib'"
   (js2-push-scope (make-js2-scope :pos 0))
   (js2-init-scanner)
   (should (js2-match-token js2-IMPORT))
   (let ((import-node (js2-parse-import)))
-    (should (not (equal nil import-node)))
+    (should (not (null import-node)))
     (should (equal "src/lib" (js2-import-node-module-id import-node)))
     (let ((import (js2-import-node-import import-node)))
-      (should (not (equal nil import)))
-      (should (equal nil (js2-import-clause-node-namespace-import import)))
-      (should (equal nil (js2-import-clause-node-named-imports import)))
+      (should (not (null import)))
+      (should (null (js2-import-clause-node-namespace-import import)))
+      (should (null (js2-import-clause-node-named-imports import)))
       (let ((default (js2-import-clause-node-default-binding import)))
-        (should (not (equal nil default)))
+        (should (not (null default)))
         (should (js2-export-binding-node-p default))
         (should (equal "theDefault" (js2-name-node-name 
(js2-export-binding-node-extern-name default)))))))
   (should (js2-scope-get-symbol js2-current-scope "theDefault")))
@@ -658,14 +668,14 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-IMPORT))
   (let ((import-node (js2-parse-import)))
-    (should (not (equal nil import-node)))
+    (should (not (null import-node)))
     (should (equal "src/lib" (js2-import-node-module-id import-node)))
     (let ((import (js2-import-node-import import-node)))
-      (should (not (equal nil import)))
-      (should (equal nil (js2-import-clause-node-default-binding import)))
-      (should (equal nil (js2-import-clause-node-named-imports import)))
+      (should (not (null import)))
+      (should (null (js2-import-clause-node-default-binding import)))
+      (should (null (js2-import-clause-node-named-imports import)))
       (let ((ns-import (js2-import-clause-node-namespace-import import)))
-        (should (not (equal nil ns-import)))
+        (should (not (null ns-import)))
         (should (js2-namespace-import-node-p ns-import))
         (should (equal "lib" (js2-name-node-name 
(js2-namespace-import-node-name ns-import)))))))
   (should (js2-scope-get-symbol js2-current-scope "lib")))
@@ -675,14 +685,14 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-IMPORT))
   (let ((import-node (js2-parse-import)))
-    (should (not (equal nil import-node)))
+    (should (not (null import-node)))
     (should (equal "src/lib" (js2-import-node-module-id import-node)))
     (let ((import (js2-import-node-import import-node)))
-      (should (not (equal nil import)))
-      (should (equal nil (js2-import-clause-node-default-binding import)))
-      (should (equal nil (js2-import-clause-node-namespace-import import)))
+      (should (not (null import)))
+      (should (null (js2-import-clause-node-default-binding import)))
+      (should (null (js2-import-clause-node-namespace-import import)))
       (let ((named-imports (js2-import-clause-node-named-imports import)))
-        (should (not (equal nil named-imports)))
+        (should (not (null named-imports)))
         (should (listp named-imports))
         (should (= 2 (length named-imports)))
         (let ((first (nth 0 named-imports))
@@ -697,16 +707,16 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-IMPORT))
   (let ((import-node (js2-parse-import)))
-    (should (not (equal nil import-node)))
+    (should (not (null import-node)))
     (should (equal "src/lib" (js2-import-node-module-id import-node)))
     (let ((import (js2-import-node-import import-node)))
-      (should (not (equal nil import)))
-      (should (equal nil (js2-import-clause-node-named-imports import)))
+      (should (not (null import)))
+      (should (null (js2-import-clause-node-named-imports import)))
       (let ((default (js2-import-clause-node-default-binding import))
             (ns-import (js2-import-clause-node-namespace-import import)))
-        (should (not (equal nil default)))
+        (should (not (null default)))
         (should (equal "stuff" (js2-name-node-name 
(js2-export-binding-node-local-name default))))
-        (should (not (equal nil ns-import)))
+        (should (not (null ns-import)))
         (should (js2-namespace-import-node-p ns-import))
         (should (equal "lib" (js2-name-node-name 
(js2-namespace-import-node-name ns-import)))))))
   (should (js2-scope-get-symbol js2-current-scope "stuff"))
@@ -718,16 +728,16 @@ the test."
   (js2-init-scanner)
   (should (js2-match-token js2-IMPORT))
   (let ((import-node (js2-parse-import)))
-    (should (not (equal nil import-node)))
+    (should (not (null import-node)))
     (should (equal "src/lib" (js2-import-node-module-id import-node)))
     (let ((import (js2-import-node-import import-node)))
-      (should (not (equal nil import)))
-      (should (not (equal nil (js2-import-clause-node-named-imports import))))
+      (should (not (null import)))
+      (should (not (null (js2-import-clause-node-named-imports import))))
       (let ((default (js2-import-clause-node-default-binding import))
             (named-imports (js2-import-clause-node-named-imports import)))
-        (should (not (equal nil default)))
+        (should (not (null default)))
         (should (equal "bob" (js2-name-node-name 
(js2-export-binding-node-local-name default))))
-        (should (not (equal nil named-imports)))
+        (should (not (null named-imports)))
         (should (= 2 (length named-imports))))))
   (should (js2-scope-get-symbol js2-current-scope "bob"))
   (should (js2-scope-get-symbol js2-current-scope "cookies"))
@@ -839,20 +849,20 @@ the test."
 
 (js2-deftest export-function-no-semicolon "export default function foo() {}"
   (js2-mode--and-parse)
-  (should (equal nil js2-parsed-warnings)))
+  (should (null js2-parsed-warnings)))
 (js2-deftest export-default-function-no-semicolon "export function foo() {}"
   (js2-mode--and-parse)
-  (should (equal nil js2-parsed-warnings)))
+  (should (null js2-parsed-warnings)))
 (js2-deftest export-anything-else-does-require-a-semicolon "export var obj = 
{}"
   (js2-mode--and-parse)
-  (should (not (equal nil js2-parsed-warnings))))
+  (should (not (null js2-parsed-warnings))))
 
 (js2-deftest export-default-async-function-no-semicolon "export default async 
function foo() {}"
   (js2-mode--and-parse)
-  (should (equal nil js2-parsed-warnings)))
+  (should (null js2-parsed-warnings)))
 (js2-deftest export-async-function-no-semicolon "export async function foo() 
{}"
   (js2-mode--and-parse)
-  (should (equal nil js2-parsed-warnings)))
+  (should (null js2-parsed-warnings)))
 
 (js2-deftest-parse parse-export-rexport "export * from 'other/lib';")
 (js2-deftest-parse parse-export-export-named-list "export {foo, bar as bang};")
@@ -943,6 +953,16 @@ the test."
 (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}")
+
+(js2-deftest-parse parse-class-public-field-no-init
+  "class C {\n  x\n  y\n  \"z\"\n  456\n}")
+
+(js2-deftest-parse parse-class-public-field-computed
+  "class C {\n  [a + b] = c\n}")
+
 ;;; Scopes
 
 (js2-deftest ast-symbol-table-includes-fn-node "function foo() {}"
@@ -1234,3 +1254,49 @@ the test."
 (js2-deftest-classify-variables destructure-object-mixed
   "function foo() { let {a, b, c = 3} = {a: 1, b: 2}; }"
   '("address@hidden:U" "address@hidden:U" "address@hidden:U" 
"address@hidden:U"))
+
+(js2-deftest-classify-variables destructure-object-missing
+  "function foo() { let {foo: missing = 10} = {}; }"
+  '("address@hidden:U" "address@hidden:U"))
+
+;; Side effects
+
+(js2-deftest no-side-effects-at-top-level
+  "var x; x.foo;"
+  (js2-mode--and-parse)
+  (should (null js2-parsed-warnings)))
+
+(js2-deftest getprop-has-no-side-effects
+  "function f() { this.x; }"
+  (js2-mode--and-parse)
+  (should (equal "msg.no.side.effects"
+                 (car (caar js2-parsed-warnings)))))
+
+(js2-deftest getprop-has-side-effects-option
+  "function f() { this.x; }"
+  (let ((js2-getprop-has-side-effects t))
+    (js2-mode--and-parse)
+    (should (null js2-parsed-warnings))))
+
+(js2-deftest arithmetic-has-no-side-effects
+  "function f() { 1 + 2; }"
+  (js2-mode--and-parse)
+  (should (equal "msg.no.side.effects"
+                 (car (caar js2-parsed-warnings)))))
+
+(js2-deftest instanceof-has-no-side-effects
+  "function f() { this instanceof f; }"
+  (js2-mode--and-parse)
+  (should (equal "msg.no.side.effects"
+                 (car (caar js2-parsed-warnings)))))
+
+(js2-deftest instanceof-has-side-effects-option
+  "function f() { this instanceof f; }"
+  (let ((js2-instanceof-has-side-effects t))
+    (js2-mode--and-parse)
+    (should (null js2-parsed-warnings))))
+
+(js2-deftest await-has-side-effects
+  "const p = new Promise();\nasync function f() { await p; return null; }"
+  (js2-mode--and-parse)
+  (should (null js2-parsed-warnings)))



reply via email to

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