Function: js--ensure-cache

js--ensure-cache is a byte-compiled function defined in js.el.gz.

Signature

(js--ensure-cache &optional LIMIT)

Documentation

Ensures brace cache is valid up to the character before LIMIT.

LIMIT defaults to point.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/js.el.gz
(defun js--ensure-cache (&optional limit)
  "Ensures brace cache is valid up to the character before LIMIT.
LIMIT defaults to point."
  (setq limit (or limit (point)))
  (when (< js--cache-end limit)

    (c-save-buffer-state
        (open-items
         parse
         prev-parse-point
         name
         case-fold-search
         filtered-class-styles
         goal-point)

      ;; Figure out which class styles we need to look for
      (setq filtered-class-styles
            (cl-loop for style in js--class-styles
                     if (memq (plist-get style :framework)
                              js-enabled-frameworks)
                     collect style))

      (save-excursion
        (save-restriction
          (widen)

          ;; Find last known good position
          (goto-char js--cache-end)
          (unless (bobp)
            (setq open-items (get-text-property
                              (1- (point)) 'js--pstate))

            (unless open-items
              (goto-char (previous-single-property-change
                          (point) 'js--pstate nil (point-min)))

              (unless (bobp)
                (setq open-items (get-text-property (1- (point))
                                                    'js--pstate))
                (cl-assert open-items))))

          (unless open-items
            ;; Make a placeholder for the top-level definition
            (setq open-items (list js--initial-pitem)))

          (setq parse (syntax-ppss))
          (setq prev-parse-point (point))

          (js--clear-stale-cache)

          (narrow-to-region (point-min) limit)

          (cl-loop while (re-search-forward js--quick-match-re-func nil t)
                   for orig-match-start = (goto-char (match-beginning 0))
                   for orig-match-end = (match-end 0)
                   do (js--ensure-cache--update-parse)
                   for orig-depth = (nth 0 parse)

                   ;; Each of these conditions should return non-nil if
                   ;; we should add a new item and leave point at the end
                   ;; of the new item's header (h-end in the
                   ;; js--pitem diagram). This point is the one
                   ;; after the last character we need to unambiguously
                   ;; detect this construct. If one of these evaluates to
                   ;; nil, the location of the point is ignored.
                   if (cond
                       ;; In comment or string
                       ((nth 8 parse) nil)

                       ;; Regular function declaration
                       ((and (looking-at "\\_<function\\_>")
                             (setq name (js--forward-function-decl)))
                        (when (eq name t)
                          (setq name (js--guess-function-name orig-match-end))
                          (if name
                              (when js--guess-function-name-start
                                (setq orig-match-start
                                      js--guess-function-name-start))

                            (setq name t)))

                        (cl-assert (eq (char-after) ?{))
                        (forward-char)
                        (save-excursion
                          (goto-char orig-match-start)
                          (when (looking-back "\\_<async\\_>[ \t\n]+"
                                              (- (point) 30))
                            (setq orig-match-start (match-beginning 0))))
                        (make-js--pitem
                         :paren-depth orig-depth
                         :h-begin orig-match-start
                         :type 'function
                         :name (if (eq name t)
                                   name
                                 (js--split-name name))))

                       ;; Macro
                       ((looking-at js--macro-decl-re)

                        ;; Macros often contain unbalanced parentheses.
                        ;; Make sure that h-end is at the textual end of
                        ;; the macro no matter what the parenthesis say.
                        (c-end-of-macro)
                        (js--ensure-cache--update-parse)

                        (make-js--pitem
                         :paren-depth (nth 0 parse)
                         :h-begin orig-match-start
                         :type 'macro
                         :name (list (match-string-no-properties 1))))

                       ;; "Prototype function" declaration
                       ((looking-at js--plain-method-re)
                        (goto-char (match-beginning 3))
                        (when (save-match-data
                                (js--forward-function-decl))
                          (forward-char)
                          (make-js--pitem
                           :paren-depth orig-depth
                           :h-begin orig-match-start
                           :type 'function
                           :name (nconc (js--split-name
                                         (match-string-no-properties 1))
                                        (list (match-string-no-properties 2))))))

                       ;; Class definition
                       ((cl-loop
                         with syntactic-context =
                         (js--syntactic-context-from-pstate open-items)
                         for class-style in filtered-class-styles
                         if (and (memq syntactic-context
                                       (plist-get class-style :contexts))
                                 (looking-at (plist-get class-style
                                                        :class-decl)))
                         do (goto-char (match-end 0))
                         and return
                         (make-js--pitem
                          :paren-depth orig-depth
                          :h-begin orig-match-start
                          :type class-style
                          :name (js--split-name
                                 (match-string-no-properties 1))))))

                   do (js--ensure-cache--update-parse)
                   and do (push it open-items)
                   and do (put-text-property
                           (1- (point)) (point) 'js--pstate open-items)
                   else do (goto-char orig-match-end))

          (goto-char limit)
          (js--ensure-cache--update-parse)
          (setq js--cache-end limit)
          (setq js--last-parse-pos limit)
          (setq js--state-at-last-parse-pos open-items)
          )))))