[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.
- [elpa] 29/46: Fontify negation operator, (continued)
- [elpa] 29/46: Fontify negation operator, Dmitry Gutov, 2014/11/15
- [elpa] 32/46: Fix #171, Dmitry Gutov, 2014/11/15
- [elpa] 31/46: js2-mode-find-enclosing-node: Make docstring and impl consistent with name, Dmitry Gutov, 2014/11/15
- [elpa] 33/46: js2-parse-primary-expr: Make some vars "more" local, Dmitry Gutov, 2014/11/15
- [elpa] 34/46: Add imenu support for the Sencha framework, Dmitry Gutov, 2014/11/15
- [elpa] 36/46: Indent before inequality operator at bol, Dmitry Gutov, 2014/11/15
- [elpa] 38/46: Indent after `+=', Dmitry Gutov, 2014/11/15
- [elpa] 37/46: Support object destructuring inside arrow function args, Dmitry Gutov, 2014/11/15
- [elpa] 30/46: js2-imenu-extras.el: Use Unix-style EOL, Dmitry Gutov, 2014/11/15
- [elpa] 42/46: js2-imenu-walk-ast: Look up js2-imenu-show-module-pattern in v-i-n case, too, Dmitry Gutov, 2014/11/15
- [elpa] 40/46: Support orphan functions on the right side of assignments,
Dmitry Gutov <=
- [elpa] 35/46: Merge pull request #173 from lelit/master, Dmitry Gutov, 2014/11/15
- [elpa] 43/46: Fix toggling single-line comments, Dmitry Gutov, 2014/11/15
- [elpa] 41/46: js2-imenu-record-module-pattern: Support `js2-var-init-node', Dmitry Gutov, 2014/11/15
- [elpa] 46/46: Merge commit '2c744815cf9e4653625dd25f2e7f8b59c152782d' from js2-mode, Dmitry Gutov, 2014/11/15
- [elpa] 45/46: Bump the version, Dmitry Gutov, 2014/11/15
- [elpa] 44/46: Merge pull request #180 from simenheg/master, Dmitry Gutov, 2014/11/15
- [elpa] 39/46: Check in LICENSE, Dmitry Gutov, 2014/11/15