         (setq node (js2-node-parent node))))
     node))
 
+(defun js2-node-parent-script-or-fn (node)
+  "Find script or function immediately enclosing NODE.
+If NODE is the ast-root, returns nil."
+  (if (js2-ast-root-p node)
+      nil
+    (setq node (js2-node-parent node))
+    (while (and node (not (or (js2-function-node-p node)
+                              (js2-script-node-p node))))
+      (setq node (js2-node-parent node)))
+    node))
+
 (defsubst js2-mode-find-first-stmt (node)
   "Search upward starting from NODE looking for a statement.
 For purposes of this function, a `js2-function-node' counts."

(defsubst js2-match-token (match)
  "Consume and return t if next token matches MATCH, a bytecode.
Returns nil and consumes nothing if MATCH is not the next token."
  (if (/= (js2-peek-token) match)
      nil
    (js2-consume-token)
    t))

(defsubst js2-peek-token-or-eol ()
  "Return js2-EOL if the current token immediately follows a newline.

             ;; create array-literal or object-literal nodes for any
             ;; destructuring-assignment parameters we find.
             (cond
              ((eq tt js2-LB)
               (js2-consume-token)
               (push (js2-parse-array-literal) params))
              ((eq tt js2-LC)
               (js2-consume-token)
               (push (js2-parse-object-literal) params))
              (t
