]> code.delx.au - gnu-emacs-elpa/commitdiff
Move module pattern support to `js2-imenu-extras`
authorDmitry Gutov <dgutov@yandex.ru>
Sun, 3 Jun 2012 00:48:12 +0000 (04:48 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Sun, 3 Jun 2012 01:02:56 +0000 (05:02 +0400)
js2-imenu-extras.el
js2-mode.el

index a85a41d5bed6b2e97f053fd775edfd19ce95fae2..32bfce31cafc21e8a492e94c4d1676d885d84bc3 100644 (file)
@@ -41,11 +41,23 @@ in a shared namespace."
   :type 'string\r
   :group 'js2-mode)\r
 \r
+(defcustom js2-imenu-show-module-pattern t\r
+  "Non-nil to recognize the module pattern:\r
+\r
+var foobs = (function(a) {\r
+  return {fib: function() {}, fub: function() {}};\r
+})(b);\r
+\r
+We record the returned hash as belonging to the named module, and\r
+prefix any functions defined inside the IIFE with the module name."\r
+  :type 'boolean\r
+  :group 'js2-mode)\r
+\r
 (defun js2-imenu-extras-setup ()\r
   (when js2-imenu-enabled-frameworks\r
     (add-to-list 'js2-post-parse-callbacks 'js2-imenu-record-declarations t))\r
-  (when js2-imenu-show-other-functions\r
-    (add-to-list 'js2-post-parse-callbacks 'js2-imenu-record-hashes t)))\r
+  (when (or js2-imenu-show-other-functions js2-imenu-show-module-pattern)\r
+    (add-to-list 'js2-post-parse-callbacks 'js2-imenu-walk-ast t)))\r
 \r
 (declare (special root))\r
 \r
@@ -104,22 +116,54 @@ in a shared namespace."
                                      (js2-compute-nested-prop-get subject)\r
                                      (js2-node-abs-pos methods)))))))\r
 \r
-(defun js2-imenu-record-hashes ()\r
+(defun js2-imenu-walk-ast ()\r
   (js2-visit-ast\r
    root\r
    (lambda (node end-p)\r
      (unless end-p\r
-       (if (and (js2-object-prop-node-p node)\r
-                (js2-function-node-p (js2-object-prop-node-right node)))\r
-           (let ((fn-node (js2-object-prop-node-right node)))\r
-             (unless (and js2-imenu-function-map\r
-                          (gethash fn-node js2-imenu-function-map))\r
-               (let ((key-node (js2-object-prop-node-left node)))\r
-                 (js2-record-imenu-entry fn-node\r
-                                         (list js2-imenu-other-functions-ns\r
-                                               (js2-prop-node-name key-node))\r
-                                         (js2-node-abs-pos key-node))))\r
-             nil)\r
-         t)))))\r
+       (cond\r
+        ((and js2-imenu-show-other-functions\r
+              (js2-object-prop-node-p node))\r
+         (js2-imenu-record-orphan-function node))\r
+        ((and js2-imenu-show-module-pattern\r
+              (js2-assign-node-p node))\r
+         (js2-imenu-record-module-pattern node)))\r
+       t))))\r
+\r
+(defun js2-imenu-record-orphan-function (node)\r
+  "Record orphan function when it's the value of NODE.\r
+NODE must be `js2-object-prop-node'."\r
+  (when (js2-function-node-p (js2-object-prop-node-right node))\r
+    (let ((fn-node (js2-object-prop-node-right node)))\r
+      (unless (and js2-imenu-function-map\r
+                   (gethash fn-node js2-imenu-function-map))\r
+        (let ((key-node (js2-object-prop-node-left node)))\r
+          (js2-record-imenu-entry fn-node\r
+                                  (list js2-imenu-other-functions-ns\r
+                                        (js2-prop-node-name key-node))\r
+                                  (js2-node-abs-pos key-node)))))))\r
+\r
+(defun js2-imenu-record-module-pattern (node)\r
+  "Recognize and record module pattern use instance.\r
+NODE must be `js2-assign-node'."\r
+  (let ((init (js2-assign-node-right node)))\r
+    (when (js2-call-node-p init)\r
+      (let ((target (js2-assign-node-left node))\r
+            (callt (js2-call-node-target init)))\r
+        ;; Just basic call form: (function() {...})();\r
+        ;; TODO: Handle variations without duplicating `js2-wrapper-function-p'?\r
+        (when (and (js2-paren-node-p callt)\r
+                   (js2-function-node-p (js2-paren-node-expr callt)))\r
+          (let* ((fn (js2-paren-node-expr callt))\r
+                 (blk (js2-function-node-body fn))\r
+                 (ret (car (last (js2-block-node-kids blk)))))\r
+            (when (and (js2-return-node-p ret)\r
+                       (js2-object-node-p (js2-return-node-retval ret)))\r
+              ;; TODO: Map function names when revealing module pattern is used.\r
+              (let ((retval (js2-return-node-retval ret)))\r
+                (js2-record-object-literal retval\r
+                                           (js2-compute-nested-prop-get target)\r
+                                           (js2-node-abs-pos retval)))\r
+              (js2-record-imenu-functions fn target))))))))\r
 \r
 (provide 'js2-imenu-extras)\r
index f61b5581fab6d0e450f5408dc1e24c75c7a6323d..915759f0e7411489277d47b3abf817b595904b6b 100644 (file)
@@ -6798,7 +6798,8 @@ the parent function, look up its qname, then prepend a copy of it to the chain."
 (defun js2-record-imenu-functions (node &optional var)
   "Record function definitions for imenu.
 NODE is a function node or an object literal.
-VAR, if non-nil, is the expression that NODE is being assigned to."
+VAR, if non-nil, is the expression that NODE is being assigned to.
+When passed arguments of wrong type, does nothing."
   (when js2-parse-ide-mode
     (let ((fun-p (js2-function-node-p node))
           qname left fname-node pos)
@@ -6874,34 +6875,6 @@ we append the property name to QNAME, then call `js2-record-imenu-entry'."
                                      (append qname (list (js2-infix-node-left e)))
                                      (+ pos (js2-node-pos right)))))))))
 
-(defun js2-record-assign-functions (init target)
-  "Record the functions involved in the assignment for imenu.
-TARGET is the target node, INIT is the value node."
-  (cond
-   ((or (js2-object-node-p init)
-        (js2-function-node-p init))
-    (js2-record-imenu-functions init target))
-   ((js2-call-node-p init)
-    ;; Module pattern: var foobs = (function(a) {return {fib: fun...}})(b);
-    ;; We record the returned hash as belonging to the named module, and prefix
-    ;; any functions defined inside IIFE with the module name.
-    (let ((callt (js2-call-node-target init)))
-      ;; Just basic call form: (function() {...})();
-      ;; TODO: Handle variations without duplicating `js2-wrapper-function-p'?
-      (when (and (js2-paren-node-p callt)
-                 (js2-function-node-p (js2-paren-node-expr callt)))
-        (let* ((fn (js2-paren-node-expr callt))
-               (blk (js2-function-node-body fn))
-               (ret (car (last (js2-block-node-kids blk)))))
-          (when (and (js2-return-node-p ret)
-                     (js2-object-node-p (js2-return-node-retval ret)))
-            ;; TODO: Map function names when revealing module pattern is used.
-            (let ((retval (js2-return-node-retval ret)))
-              (js2-record-object-literal retval
-                                         (js2-compute-nested-prop-get target)
-                                         (js2-node-abs-pos retval)))
-            (js2-record-imenu-functions fn target))))))))
-
 (defsubst js2-node-top-level-decl-p (node)
   "Return t if NODE's name is defined in the top-level scope.
 Also returns t if NODE's name is not defined in any scope, since it implies
@@ -8520,8 +8493,7 @@ Returns the parsed `js2-var-decl-node' expression node."
       (when (js2-match-token js2-ASSIGN)
         (setq init (js2-parse-assign-expr)
               end (js2-node-end init))
-        (when js2-parse-ide-mode
-          (js2-record-assign-functions init name)))
+        (js2-record-imenu-functions init name))
       (when name
         (js2-set-face nbeg nend (if (js2-function-node-p init)
                                     'font-lock-function-name-face
@@ -8682,7 +8654,7 @@ If NODE is non-nil, it is the AST node associated with the symbol."
                                        :right right))
         (when js2-parse-ide-mode
           (js2-highlight-assign-targets pn left right)
-          (js2-record-assign-functions right left))
+          (js2-record-imenu-functions right left))
         ;; do this last so ide checks above can use absolute positions
         (js2-node-add-children pn left right))
       pn)))