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

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

[elpa] 40/46: Support orphan functions on the right side of assignments


From: Dmitry Gutov
Subject: [elpa] 40/46: Support orphan functions on the right side of assignments
Date: Sat, 15 Nov 2014 20:58:12 +0000

dgutov pushed a commit to branch master
in repository elpa.

commit e979e14e45d4814b64c90c01b263d956c9a0e0fe
Author: Dmitry Gutov <address@hidden>
Date:   Thu Nov 13 08:34:06 2014 +0200

    Support orphan functions on the right side of assignments
    
    * js2-imenu-extras.el (js2-imenu-extras-setup): Use the new hook
    instead of `js2-post-parse-callbacks'.
    (js2-imenu-record-orphan-function): Rename, update the caller.
    (js2-imenu-record-orphan-assign-node-function): New function, to
    handle orphan functions on the right side of assignments.
    (js2-imenu-walk-ast): Use it.
    
    * js2-mode.el (js2-build-imenu-callbacks): New hook variable.
    (js2-browse-postprocess-chains): Use it.  Make it take no
    arguments and be aware of `js2-imenu-recorder'.
    (js2-wrapper-function-p): Check that the wrapped function is the
    call's target.
    (js2-build-imenu-index): Run `js2-browse-postprocess-chains' even
    when `js2-imenu-recorder' is empty.  It might get modified in
    callbacks.
    (js2-browse-postprocess-chains): When skipping a function, remove
    its entry from `js2-imenu-function-map'.
    
    Based on
    
https://github.com/redguardtoo/js2-mode/commit/efc5d4704d260522d04b5642c844711ba1cfc7f7#commitcomment-8441004.
---
 js2-imenu-extras.el |   36 +++++++++++++++++++++++++++---------
 js2-mode.el         |   36 ++++++++++++++++++++++++++----------
 2 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/js2-imenu-extras.el b/js2-imenu-extras.el
index e3a2c97..77e247c 100644
--- a/js2-imenu-extras.el
+++ b/js2-imenu-extras.el
@@ -117,13 +117,13 @@ Currently used for jQuery widgets, Dojo and Enyo 
declarations."
 ;;;###autoload
 (defun js2-imenu-extras-setup ()
   (when js2-imenu-enabled-frameworks
-    (add-hook 'js2-post-parse-callbacks 'js2-imenu-record-declarations t t))
+    (add-hook 'js2-build-imenu-callbacks 'js2-imenu-record-declarations t t))
   (when (or js2-imenu-show-other-functions js2-imenu-show-module-pattern)
-    (add-hook 'js2-post-parse-callbacks 'js2-imenu-walk-ast t t)))
+    (add-hook 'js2-build-imenu-callbacks 'js2-imenu-walk-ast t t)))
 
 (defun js2-imenu-extras-remove ()
-  (remove-hook 'js2-post-parse-callbacks 'js2-imenu-record-declarations t)
-  (remove-hook 'js2-post-parse-callbacks 'js2-imenu-walk-ast t))
+  (remove-hook 'js2-build-imenu-callbacks 'js2-imenu-record-declarations t)
+  (remove-hook 'js2-build-imenu-callbacks 'js2-imenu-walk-ast t))
 
 (defun js2-imenu-record-declarations ()
   (let* ((styles (loop for style in js2-imenu-extension-styles
@@ -231,10 +231,15 @@ Currently used for jQuery widgets, Dojo and Enyo 
declarations."
        (cond
         ((and js2-imenu-show-other-functions
               (js2-object-prop-node-p node))
-         (js2-imenu-record-orphan-function node))
-        ((and js2-imenu-show-module-pattern
-              (js2-assign-node-p node))
-         (js2-imenu-record-module-pattern node)))
+         (js2-imenu-record-orphan-prop-node-function node))
+        ((js2-assign-node-p node)
+         (cond
+          ((and js2-imenu-show-other-functions
+                (js2-function-node-p
+                 (js2-assign-node-right node)))
+           (js2-imenu-record-orphan-assign-node-function node))
+          (js2-imenu-show-module-pattern
+           (js2-imenu-record-module-pattern node)))))
        t))))
 
 (defun js2-imenu-parent-key-names (node)
@@ -266,7 +271,7 @@ return the grandparent."
       (setq p3 (js2-node-parent p2))
       (if (and p3 (js2-object-prop-node-p p3)) p3))))
 
-(defun js2-imenu-record-orphan-function (node)
+(defun js2-imenu-record-orphan-prop-node-function (node)
   "Record orphan function when it's the value of NODE.
 NODE must be `js2-object-prop-node'."
   (when (js2-function-node-p (js2-object-prop-node-right node))
@@ -282,6 +287,19 @@ NODE must be `js2-object-prop-node'."
           (js2-record-imenu-entry fn-node chain
                                   (js2-node-abs-pos key-node)))))))
 
+(defun js2-imenu-record-orphan-assign-node-function (node)
+  "Return orphan function entry when it's the right hand of NODE.
+NODE must be `js2-assign-node'."
+  (let ((fn-node (js2-assign-node-right node)))
+    (when (or (not js2-imenu-function-map)
+              (eq 'skip
+                  (gethash fn-node js2-imenu-function-map 'skip)))
+      (let* ((target-node (js2-assign-node-left node))
+             (chain (js2-compute-nested-prop-get target-node)))
+        (when chain
+          (push js2-imenu-other-functions-ns chain)
+          (js2-record-imenu-entry fn-node chain (js2-node-abs-pos 
fn-node)))))))
+
 (defun js2-imenu-record-module-pattern (node)
   "Recognize and record module pattern use instance.
 NODE must be `js2-assign-node'."
diff --git a/js2-mode.el b/js2-mode.el
index d6a0d29..8ac9a0f 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -1112,6 +1112,13 @@ declarations to `js2-recorded-identifiers', which see."
   :type 'hook
   :group 'js2-mode)
 
+(defcustom js2-build-imenu-callbacks nil
+  "List of functions called during Imenu index generation.
+It's a good place to add additional entries to it, using
+`js2-record-imenu-entry'."
+  :type 'hook
+  :group 'js2-mode)
+
 (defcustom js2-highlight-external-variables t
   "Non-nil to highlight undeclared variable identifiers.
 An undeclared variable is any variable not declared with var or let
@@ -6842,7 +6849,8 @@ NODE must be `js2-function-node'."
   (let ((parent (js2-node-parent node)))
     (or
      ;; function(){...}();
-     (js2-call-node-p parent)
+     (and (js2-call-node-p parent)
+          (eq node (js2-call-node-target parent)))
      (and (js2-paren-node-p parent)
           ;; (function(){...})();
           (or (js2-call-node-p (setq parent (js2-node-parent parent)))
@@ -6852,12 +6860,12 @@ NODE must be `js2-function-node'."
                            '("call" "apply"))
                    (js2-call-node-p (js2-node-parent parent))))))))
 
-(defun js2-browse-postprocess-chains (entries)
+(defun js2-browse-postprocess-chains ()
   "Modify function-declaration name chains after parsing finishes.
 Some of the information is only available after the parse tree is complete.
 For instance, processing a nested scope requires a parent function node."
   (let (result fn parent-qname p elem)
-    (dolist (entry entries)
+    (dolist (entry js2-imenu-recorder)
       ;; function node goes first
       (destructuring-bind (current-fn &rest (&whole chain head &rest)) entry
         ;; Examine head's defining scope:
@@ -6879,12 +6887,19 @@ For instance, processing a nested scope requires a 
parent function node."
                             (gethash grandparent js2-imenu-function-map 
'skip)))
                       'skip))
               (puthash fn parent-qname js2-imenu-function-map))
-            (unless (eq parent-qname 'skip)
-              ;; prefix parent fn qname to this chain.
+            (if (eq parent-qname 'skip)
+                ;; We don't show it, let's record that fact.
+                (remhash current-fn js2-imenu-function-map)
+              ;; Prepend parent fn qname to this chain.
               (let ((qname (append parent-qname chain)))
                 (puthash current-fn (butlast qname) js2-imenu-function-map)
                 (push qname result)))))))
-    ;; finally replace each node in each chain with its name.
+    ;; Collect chains obtained by third-party code.
+    (let (js2-imenu-recorder)
+      (run-hooks 'js2-build-imenu-callbacks)
+      (dolist (entry js2-imenu-recorder)
+        (push (cdr entry) result)))
+    ;; Finally replace each node in each chain with its name.
     (dolist (chain result)
       (setq p chain)
       (while p
@@ -6996,10 +7011,11 @@ e.g. key 'c' in the example above."
 
 (defun js2-build-imenu-index ()
   "Turn `js2-imenu-recorder' into an imenu data structure."
-  (unless (eq js2-imenu-recorder 'empty)
-    (let* ((chains (js2-browse-postprocess-chains js2-imenu-recorder))
-           (result (js2-build-alist-trie chains nil)))
-      (js2-flatten-trie result))))
+  (when (eq js2-imenu-recorder 'empty)
+    (setq js2-imenu-recorder nil))
+  (let* ((chains (js2-browse-postprocess-chains))
+         (result (js2-build-alist-trie chains nil)))
+    (js2-flatten-trie result)))
 
 (defun js2-test-print-chains (chains)
   "Print a list of qname chains.



reply via email to

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