branch: scratch/javaimp-wip commit dcc6bedf64189f7c4597f8382fea1abd84da8720 Author: Filipp Gunbin <fgun...@fastmail.fm> Commit: Filipp Gunbin <fgun...@fastmail.fm>
wip --- javaimp-parse.el | 128 ++++++++++++++-------- javaimp-tests.el | 230 +++++++++++++++++++++------------------ javaimp-util.el | 22 ++-- javaimp.el | 60 ++++------ testdata/test1-misc-classes.java | 9 +- 5 files changed, 254 insertions(+), 195 deletions(-) diff --git a/javaimp-parse.el b/javaimp-parse.el index 061b18d..76da646 100644 --- a/javaimp-parse.el +++ b/javaimp-parse.el @@ -54,18 +54,12 @@ present." "static" ;static initializer block )) -(defsubst javaimp--parse-is-classlike (scope) - (and scope - (member (symbol-name (javaimp-scope-type scope)) - javaimp--parse-classlike-keywords))) - -(defsubst javaimp--parse-is-named (scope) - (and scope - (memq (javaimp-scope-type scope) - javaimp--parse-named-scope-types))) +(defvar javaimp-syntax-table + (make-syntax-table java-mode-syntax-table) ;TODO don't depend + "Javaimp syntax table") (defvar javaimp--arglist-syntax-table - (let ((st (make-syntax-table java-mode-syntax-table))) ;TODO don't depend + (let ((st (make-syntax-table javaimp-syntax-table))) (modify-syntax-entry ?< "(>" st) (modify-syntax-entry ?> ")<" st) (modify-syntax-entry ?. "_" st) ; separates parts of fully-qualified type @@ -77,13 +71,16 @@ present." considered as stale. Usually set by modification change hooks. Should be set to (point-min) in major mode hook.") -(defmacro javaimp--parse-with-arglist-syntax (beg &rest body) - (declare (debug t)) + + +(defmacro javaimp--parse-with-syntax-table (syntax-table beg &rest body) + (declare (debug t) + (indent 2)) (let ((begin (make-symbol "begin"))) `(let ((,begin ,beg)) (syntax-ppss-flush-cache ,begin) (unwind-protect - (with-syntax-table javaimp--arglist-syntax-table + (with-syntax-table ,syntax-table ,@body) (syntax-ppss-flush-cache ,begin))))) @@ -93,6 +90,38 @@ Should be set to (point-min) in major mode hook.") (string-trim (substring str 0 end)) str))) +(defsubst javaimp--parse-is-classlike (scope) + (and scope + (member (symbol-name (javaimp-scope-type scope)) + javaimp--parse-classlike-keywords))) + +(defsubst javaimp--parse-is-named (scope) + (and scope + (memq (javaimp-scope-type scope) + javaimp--parse-named-scope-types))) + +(defsubst javaimp--parse-is-imenu-included-method (scope) + (and (eq (javaimp-scope-type scope) 'method) + (javaimp--parse-is-classlike (javaimp-scope-parent scope)))) + +(defun javaimp--parse-copy-scope (scope) + "Recursively copies SCOPE and its parents." + (let* ((res (copy-javaimp-scope scope)) + (tmp res) + orig-parent) + (while (setq orig-parent (javaimp-scope-parent tmp)) + (setf (javaimp-scope-parent tmp) (copy-javaimp-scope orig-parent)) + (setq tmp (javaimp-scope-parent tmp))) + res)) + +(defun javaimp--parse-concat-parent-names (scope) + (let (parents) + (while (setq scope (javaimp-scope-parent scope)) + (push scope parents)) + (mapconcat #'javaimp-scope-name parents "."))) + + + (defun javaimp--parse-rsb-keyword (regexp &optional bound noerror count) "Like `re-search-backward', but count only occurences outside syntactic context as given by `syntax-ppss-context'. Assumes @@ -110,7 +139,7 @@ point is outside of any context initially." "Parse arg list between BEG and END, of the form 'TYPE NAME, ...'. Return list of conses (TYPE . NAME). If ONLY-TYPE is non-nil, then name parsing is skipped." - (javaimp--parse-with-arglist-syntax beg + (javaimp--parse-with-syntax-table javaimp--arglist-syntax-table beg (save-excursion (save-restriction (narrow-to-region beg end) @@ -227,7 +256,7 @@ is unchanged." (catch 'found (while (javaimp--parse-rsb-keyword regexp bound t) (let ((scan-pos (match-end 0))) - (javaimp--parse-with-arglist-syntax scan-pos + (javaimp--parse-with-syntax-table javaimp--arglist-syntax-table scan-pos (while (and scan-pos (<= scan-pos (nth 1 state))) (if (ignore-errors (= (scan-lists scan-pos 1 -1) ;As in javaimp--parse-preceding @@ -419,7 +448,7 @@ nil then goes all the way up. Examines and sets property (setq scope (run-hook-with-args-until-success 'javaimp--parse-scope-hook state)) (put-text-property (point) (1+ (point)) - 'javaimp--parse-scope scope)) + 'javaimp-parse-scope scope)) (push scope res) (if (javaimp-scope-start scope) (goto-char (javaimp-scope-start scope))))) @@ -439,20 +468,23 @@ nil then goes all the way up. Examines and sets property res)) (defun javaimp--parse-all-scopes () - "Parses scopes in this buffer which are after -`javaimp--parse-dirty-pos', if it is non-nil. Resets this -variable after parsing is done." + "Entry point to the scope parsing. Parses scopes in this buffer +which are after `javaimp--parse-dirty-pos', if it is non-nil. +Resets this variable after parsing is done." (when javaimp--parse-dirty-pos (remove-text-properties javaimp--parse-dirty-pos (point-max) '(javaimp-parse-scope nil)) (goto-char (point-max)) - (let ((parse-sexp-ignore-comments t) ; FIXME remove with major mode + ;; FIXME With major mode we could set these, as well as syntax + ;; table, in mode function. + (let ((parse-sexp-ignore-comments t) (parse-sexp-lookup-properties nil)) - (while (javaimp--parse-rsb-keyword "{" javaimp--parse-dirty-pos t) - (save-excursion - (forward-char) - ;; Set props at this brace and all the way up - (javaimp--parse-scopes nil)))) + (javaimp--parse-with-syntax-table javaimp-syntax-table (point-min) + (while (javaimp--parse-rsb-keyword "{" javaimp--parse-dirty-pos t) + (save-excursion + (forward-char) + ;; Set props at this brace and all the way up + (javaimp--parse-scopes nil))))) (setq javaimp--parse-dirty-pos nil))) @@ -462,27 +494,24 @@ variable after parsing is done." (defun javaimp--parse-get-package () (goto-char (point-max)) (when (javaimp--parse-rsb-keyword - "^\\s-*package\\s-+\\([^;\n]+\\)\\s-*;" nil t 1) + "^[ \t]*package[ \t]+\\([^;\n]+\\)[ \t]*;" nil t 1) (match-string 1))) (defun javaimp--parse-get-all-classlikes (&optional reparse) (mapcar (lambda (scope) (let ((name (javaimp-scope-name scope)) - (tmp scope)) - (while (setq tmp (javaimp-scope-parent tmp)) - (setq name (concat (javaimp-scope-name tmp) "." name))) - name)) + (parent-names (javaimp--parse-concat-parent-names scope))) + (if (string-empty-p parent-names) + name + (concat parent-names "." name)))) (javaimp--parse-get-all-scopes reparse #'javaimp--parse-is-classlike))) -(defun javaimp--parse-get-forest-for-imenu (&optional reparse) +(defun javaimp--parse-get-imenu-forest (&optional reparse) (let* ((methods (javaimp--parse-get-all-scopes - reparse - (lambda (s) - (and (eq (javaimp-scope-type s) 'method) - (javaimp--parse-is-classlike (javaimp-scope-parent s)))))) + reparse #'javaimp-imenu--included-method)) (classes (javaimp--parse-get-all-scopes - nil ; no need to reparse + nil ; no need to reparse again #'javaimp--parse-is-classlike)) (top-classes (mapcar (lambda (s) (null (javaimp-scope-parent s))) @@ -503,13 +532,26 @@ reparsing is done." (when reparse (setq javaimp--parse-dirty-pos (point-min))) (javaimp--parse-all-scopes) - (goto-char (point-max)) - (let (match res) - (while (setq match (text-property-search-backward - 'javaimp-parse-scope nil nil)) - (when (or (null pred) - (funcall pred (prop-match-value match))) - (push (prop-match-value match) res))) + (let ((pos (point-max)) + scope res) + (while (setq pos (previous-single-property-change + pos 'javaimp-parse-scope)) + (setq scope (get-text-property pos 'javaimp-parse-scope)) + (when (and scope + (or (null pred) + (funcall pred scope))) + (let* ((tmp (javaimp--parse-copy-scope scope)) + (parent (javaimp-scope-parent tmp))) + (while (and tmp parent) + (if (funcall pred parent) + ;; go up + (setq parent (javaimp-scope-parent parent) + tmp parent) + ;; skip this parent + (setq parent (javaimp-scope-parent parent)) + (setf (javaimp-scope-parent tmp) parent) + (setq tmp parent))) + (push tmp res)))) res)) (defun javaimp--parse-update-dirty-pos (beg _end _old-len) diff --git a/javaimp-tests.el b/javaimp-tests.el index b4788e2..62d96a2 100644 --- a/javaimp-tests.el +++ b/javaimp-tests.el @@ -8,7 +8,7 @@ (require 'ert) (require 'javaimp) -;; Low-level helpers of scope parsers. +;; Tests for low-level helpers of scope parsers. (ert-deftest javaimp-test--parse-arglist () (dolist (data '(("") @@ -34,7 +34,6 @@ ("String[][]" . "arr")) )) (with-temp-buffer - (java-mode) (insert (car data)) (should (equal (javaimp--parse-arglist (point-min) (point-max)) (cdr data)))))) @@ -57,7 +56,6 @@ Exception4<? super Exception5>>") ("Exception6") ("Exception7<Exception8>")))) (with-temp-buffer - (java-mode) (insert (car data)) (should (equal (javaimp--parse-arglist (point-min) (point-max) t) (cdr data)))))) @@ -114,7 +112,9 @@ extends Bar<? extends Baz<? extends Baz2>> {" anonymous-class "Object")))) (ert-deftest javaimp-test--parse-scope-method-or-stmt () - (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-method-or-stmt)) + (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-method-or-stmt) + (javaimp-parse-format-method-name + #'javaimp--parse-format-method-name-full)) (javaimp-test--check-single-scope '("static void foo_bar ( String a , int b ) {" method "foo_bar(String a, int b)") @@ -161,7 +161,6 @@ throws E1 {" (dolist (item test-items) (with-temp-buffer (insert (nth 0 item)) - (java-mode) (let* ((scope (car (javaimp--parse-get-all-scopes t)))) (should-not (null scope)) (should (eq (javaimp-scope-type scope) (nth 1 item))) @@ -188,27 +187,29 @@ throws E1 {" "Top.IInner1" "Top.IInner1.IInner1_CInner1" "Top.IInner1.IInner1_IInner1" - "Top.EInner1" - "Top.EInner1.EInner1_EInner1" + "Top.EnumInner1" + "Top.EnumInner1.EnumInner1_EInner1" "ColocatedTop"))))) (ert-deftest javaimp-test--parse-get-all-scopes () (with-temp-buffer (insert-file-contents (concat javaimp--basedir "testdata/test1-misc-classes.java")) - ;; - ;; parse full buffer - (javaimp-test--check-named-scopes - (javaimp--parse-get-all-scopes t #'javaimp--parse-is-named)) - ;; - ;; reparse half of buffer - (setq javaimp--parse-dirty-pos (/ (- (point-max) (point-min)) 2)) - (javaimp-test--check-named-scopes - (javaimp--parse-get-all-scopes nil #'javaimp--parse-is-named)) - ;; - ;; use cache - (javaimp-test--check-named-scopes - (javaimp--parse-get-all-scopes nil #'javaimp--parse-is-named)))) + (let ((javaimp-parse-format-method-name + #'javaimp--parse-format-method-name-types)) + ;; + ;; parse full buffer + (javaimp-test--check-named-scopes + (javaimp--parse-get-all-scopes t #'javaimp--parse-is-named)) + ;; + ;; reparse half of buffer + (setq javaimp--parse-dirty-pos (/ (- (point-max) (point-min)) 2)) + (javaimp-test--check-named-scopes + (javaimp--parse-get-all-scopes nil #'javaimp--parse-is-named)) + ;; + ;; use cache + (javaimp-test--check-named-scopes + (javaimp--parse-get-all-scopes nil #'javaimp--parse-is-named))))) (defun javaimp-test--check-named-scopes (scopes) (let ((actual @@ -224,61 +225,66 @@ throws E1 {" (expected '(((class "Top")) ((class "CInner1") (class "Top")) - ((method "foo") (class "CInner1") (class "Top")) + ((method "foo()") (class "CInner1") (class "Top")) ((local-class "CInner1_CLocal1") - (method "foo") (class "CInner1") (class "Top")) - ((method "foo") + (method "foo()") (class "CInner1") (class "Top")) + ((method "foo()") (local-class "CInner1_CLocal1") - (method "foo") (class "CInner1") (class "Top")) + (method "foo()") (class "CInner1") (class "Top")) ((local-class "CInner1_CLocal1_CLocal1") - (method "foo") + (method "foo()") (local-class "CInner1_CLocal1") - (method "foo") (class "CInner1") (class "Top")) - ((method "foo") + (method "foo()") (class "CInner1") (class "Top")) + ((method "foo()") (local-class "CInner1_CLocal1_CLocal1") - (method "foo") + (method "foo()") (local-class "CInner1_CLocal1") - (method "foo") (class "CInner1") (class "Top")) + (method "foo()") (class "CInner1") (class "Top")) ((local-class "CInner1_CLocal2") - (method "foo") (class "CInner1") (class "Top")) - ((method "foo") + (method "foo()") (class "CInner1") (class "Top")) + ((method "foo()") (local-class "CInner1_CLocal2") - (method "foo") (class "CInner1") (class "Top")) + (method "foo()") (class "CInner1") (class "Top")) - ((class "CInner1_CInner") (class "CInner1") (class "Top")) - ((method "foo") - (class "CInner1_CInner") (class "CInner1") (class "Top")) - ((method "bar") - (class "CInner1_CInner") (class "CInner1") (class "Top")) + ((method "toString()") + (class "CInner1") (class "Top")) + + ((class "CInner1_CInner1") (class "CInner1") (class "Top")) + ((method "foo()") + (class "CInner1_CInner1") (class "CInner1") (class "Top")) + ((method "bar()") + (class "CInner1_CInner1") (class "CInner1") (class "Top")) ((interface "IInner1") (class "Top")) - ((method "foo") (interface "IInner1") (class "Top")) + ((method "foo()") (interface "IInner1") (class "Top")) ((class "IInner1_CInner1") (interface "IInner1") (class "Top")) - ((method "foo") + ((method "foo()") (class "IInner1_CInner1") (interface "IInner1") (class "Top")) - ((method "defaultMethod") (interface "IInner1") (class "Top")) + ((method "defaultMethod(String)") + (interface "IInner1") (class "Top")) ((interface "IInner1_IInner1") (interface "IInner1") (class "Top")) - ((method "defaultMethod") + ((method "defaultMethod(String)") (interface "IInner1_IInner1") (interface "IInner1") (class "Top")) ((enum "EnumInner1") (class "Top")) - ((method "EnumInner1") (enum "EnumInner1") (class "Top")) - ((method "foo") (enum "EnumInner1") (class "Top")) + ((method "EnumInner1()") (enum "EnumInner1") (class "Top")) + ((method "foo()") (enum "EnumInner1") (class "Top")) ((enum "EnumInner1_EInner1") (enum "EnumInner1") (class "Top")) ((class "ColocatedTop")) - ((method "foo") (class "ColocatedTop"))))) + ((method "foo()") (class "ColocatedTop")) + ((method "bar(String, String)") (class "ColocatedTop"))))) (should (= (length expected) (length actual))) (dotimes (i (length expected)) (should (equal (nth i expected) (nth i actual))))) ;; (let ((data `((,(nth 0 scopes) "Top" 26 36) - (,(nth 15 scopes) "Top.IInner1.IInner1_CInner1.foo" 1810 1816) - (,(nth 22 scopes) "Top.EnumInner1_EInner1" 2452 2476) - (,(nth 24 scopes) "ColocatedTop.foo" 2544 2550)))) + (,(nth 15 scopes) "Top.IInner1.IInner1_CInner1.foo" 1798 1804) + (,(nth 22 scopes) "Top.EnumInner1_EInner1" 24574 2498) + (,(nth 24 scopes) "ColocatedTop.foo" 2566 2572)))) (dolist (elt data) (let ((scope (nth 0 elt))) (should (equal (nth 1 elt) (javaimp-scope-name scope))) @@ -291,77 +297,95 @@ throws E1 {" (ert-deftest javaimp-test--imenu-group () (let* ((javaimp-imenu-group-methods t) - (actual (javaimp-test--imenu-get-index))) + (javaimp-parse-format-method-name + #'javaimp--parse-format-method-name-types) + (actual + (javaimp-test--imenu-simplify-entries + (with-temp-buffer + (insert-file-contents + (concat javaimp--basedir "testdata/test1-misc-classes.java")) + (javaimp-imenu-create-index))))) (should (equal actual '(("Top" ("CInner1" - ("foo" . 98) + ("foo()" . 98) ("CInner1_CInner1" - ("foo" . 1099) - ("bar" . 1192))) + ("foo()" . 1099) + ("bar()" . 1192))) ("IInner1" - ("foo" . 1603) + ("foo()" . 1603) ("IInner1_CInner1" - ("foo" . 1810)) - ("defaultMethod" . 1975) + ("foo()" . 1810)) + ("defaultMethod(String)" . 1975) ("IInner1_IInner1" - ("defaultMethod" . 2158))) + ("defaultMethod(String)" . 2169))) ("EnumInner1" - ("EnumInner1" . 2343) - ("foo" . 2389) - ;; "EnumInner1_EInner1" empty - omitted + ("EnumInner1()" . 2365) + ("foo()" . 2411) + ;; "EnumInner1_EInner1" omitted because no methods inside )) ("ColocatedTop" - ("foo" . 2544))))))) - -(ert-deftest javaimp-test--imenu-simple () - (let* ((javaimp-imenu-group-methods nil) - (actual (javaimp-test--imenu-get-index))) - (should - (equal - actual - '(("foo (Top.CInner1)" . 98) - ("foo (Top.CInner1.CInner1_CInner1)" . 1099) - ("bar" . 1192) - ("foo (Top.IInner1)" . 1603) - ("foo (Top.IInner1.IInner1_CInner1)" . 1810) - ("defaultMethod (Top.IInner1)" . 1975) - ("defaultMethod (Top.IInner1.IInner1_IInner1)" . 2158) - ("EnumInner1" . 2343) - ("foo (Top.EnumInner1)" . 2389) - ("foo (ColocatedTop)" . 2544)))))) - -(ert-deftest javaimp-test--imenu-qualified () - (let* ((javaimp-imenu-group-methods 'qualified) - (actual - (mapcar (lambda (entry) + ("foo()" . 2566) + ("bar(String, String)" . 2578))))))) - (javaimp-test--imenu-get-index))) - (should - (equal +(defun javaimp-test--imenu-simplify-entries (alist) + (dolist (elt alist) + (if (and (= (length elt) 4) + (functionp (nth 2 elt))) + (setcdr elt (nth 1 elt)) + (javaimp-test--imenu-simplify-entries (cdr elt))))) - (lambda (s) - (cons (javaimp-scope-name entry) (javaimp-scope-start entry))) +(ert-deftest javaimp-test--imenu-simple () + (let ((javaimp-parse-format-method-name + #'javaimp--parse-format-method-name-types) + (javaimp-imenu-group-methods nil)) + (javaimp-test--imenu-method-list 0))) - actual - '(("Top.CInner1.foo" . 98) - ("Top.CInner1.CInner1_CInner1.foo" . 1099) - ("Top.CInner1.CInner1_CInner1.bar" . 1192) - ("Top.IInner1.foo" . 1603) - ("Top.IInner1.IInner1_CInner1.foo" . 1810) - ("Top.IInner1.defaultMethod" . 1975) - ("Top.IInner1.IInner1_IInner1.defaultMethod" . 2158) - ("Top.EnumInner1.EnumInner1" . 2343) - ("Top.EnumInner1.foo" . 2389) - ("ColocatedTop.foo" . 2544)))))) - -(defun javaimp-test--imenu-get-index () - (with-temp-buffer - (insert-file-contents - (concat javaimp--basedir "testdata/test1-misc-classes.java")) - (javaimp-imenu-create-index))) +(ert-deftest javaimp-test--imenu-qualified () + (let ((javaimp-parse-format-method-name + #'javaimp--parse-format-method-name-types) + (javaimp-imenu-group-methods 'qualified)) + (javaimp-test--imenu-method-list 1))) + +(defun javaimp-test--imenu-method-list (exp-name-idx) + (let* ((actual + (with-temp-buffer + (insert-file-contents + (concat javaimp--basedir "testdata/test1-misc-classes.java")) + (javaimp-imenu-create-index))) + (expected + '(("foo() [Top.CInner1]" + "Top.CInner1.foo()" 98) + ("foo() [Top.CInner1.CInner1_CInner1]" + "Top.CInner1.CInner1_CInner1.foo()" 1099) + ("bar()" + "Top.CInner1.CInner1_CInner1.bar()" 1192) + ("foo() [Top.IInner1]" + "Top.IInner1.foo()" 1603) + ("foo() [Top.IInner1.IInner1_CInner1]" + "Top.IInner1.IInner1_CInner1.foo()" 1810) + ("defaultMethod(String) [Top.IInner1]" + "Top.IInner1.defaultMethod(String)" 1975) + ("defaultMethod(String) [Top.IInner1.IInner1_IInner1]" + "Top.IInner1.IInner1_IInner1.defaultMethod(String)" 2169) + ("EnumInner1()" + "Top.EnumInner1.EnumInner1()" 2365) + ("foo() [Top.EnumInner1]" + "Top.EnumInner1.foo()" 2411) + ("foo() [ColocatedTop]" + "ColocatedTop.foo()" 2566) + ("bar(String, String)" + "ColocatedTop.bar(String, String)" 2578)))) + (should (= (length expected) (length actual))) + (dotimes (i (length expected)) + (let ((exp (nth i expected)) + (act (nth i actual))) + ;; name + (should (equal (nth exp-name-idx exp) (nth 0 act))) + ;; pos + (should (= (nth 2 exp) (nth 1 act))))))) (provide 'javaimp-tests) diff --git a/javaimp-util.el b/javaimp-util.el index 1bf2a79..25dd12d 100644 --- a/javaimp-util.el +++ b/javaimp-util.el @@ -160,9 +160,9 @@ PARENT-NODE is indented for recursive calls." (defun javaimp--find-node (pred forest &optional unwrap) (catch 'found (dolist (tree forest) - (javaimp--find-node-in-tree-1 tree pred unwrap)))) + (javaimp--find-node-in-tree tree pred unwrap)))) -(defun javaimp--find-node-in-tree-1 (tree pred unwrap) +(defun javaimp--find-node-in-tree (tree pred unwrap) (when tree (if (funcall pred (javaimp-node-contents tree)) (throw 'found @@ -170,23 +170,25 @@ PARENT-NODE is indented for recursive calls." (javaimp-node-contents tree) tree))) (dolist (child (javaimp-node-children tree)) - (javaimp--find-node-in-tree-1 child pred unwrap)))) + (javaimp--find-node-in-tree child pred unwrap)))) (defun javaimp--collect-nodes (pred forest) (apply #'seq-concatenate 'list (mapcar (lambda (tree) - (javaimp--collect-nodes-from-tree tree pred)) + (delq nil + (javaimp--collect-nodes-from-tree tree pred))) forest))) (defun javaimp--collect-nodes-from-tree (tree pred) (when tree - (append (when (funcall pred (javaimp-node-contents tree)) - (list (javaimp-node-contents tree))) - (apply #'seq-concatenate 'list - (mapcar (lambda (child) - (javaimp--collect-nodes-from-tree child pred)) - (javaimp-node-children tree)))))) + (cons (and (funcall pred (javaimp-node-contents tree)) + (javaimp-node-contents tree)) + (apply #'seq-concatenate 'list + (mapcar (lambda (child) + (delq nil + (javaimp--collect-nodes-from-tree child pred))) + (javaimp-node-children tree)))))) (defun javaimp--map-nodes (mapper pred forest) diff --git a/javaimp.el b/javaimp.el index 86b16cd..2bd4d2f 100644 --- a/javaimp.el +++ b/javaimp.el @@ -571,32 +571,33 @@ is `ordinary' or `static'. Interactively, NEW-IMPORTS is nil." (defun javaimp-imenu-create-index () "Function to use as `imenu-create-index-function'." (let ((forest (save-excursion - (javaimp--parse-get-forest-for-imenu)))) + (javaimp--parse-get-imenu-forest)))) (cond ((not javaimp-imenu-group-methods) ;; plain list of methods - (let ((entries (mapcar #'javaimp-imenu--make-entry - (javaimp--collect-nodes - #'javaimp-imenu--included-method forest)))) + (let ((entries + (mapcar #'javaimp-imenu--make-entry + (javaimp--collect-nodes + #'javaimp--parse-is-imenu-included-method forest)))) (mapcar (lambda (entry) - ;; disambiguate similar method names + ;; disambiguate same method names (when (assoc (car entry) entries) (setcar entry - (format "%s (%s)" + (format "%s [%s]" (car entry) - (javaimp-imenu--concat-parent-names + (javaimp--parse-concat-parent-names (nth 3 entry)))))) entries))) ((eq javaimp-imenu-group-methods 'qualified) ;; list of qualified methods (mapcar (lambda (entry) ;; prepend parents to name - (setcar entry (concat (javaimp-imenu--concat-parent-names + (setcar entry (concat (javaimp--parse-concat-parent-names (nth 3 entry)) "." (car entry)))) - (mapcar #'javaimp-imenu-make-entry + (mapcar #'javaimp-imenu--make-entry (javaimp--collect-nodes - #'javaimp-imenu--included-method forest)))) + #'javaimp--parse-is-imenu-included-method forest)))) (t ;; group methods inside their enclosing class @@ -605,46 +606,21 @@ is `ordinary' or `static'. Interactively, NEW-IMPORTS is nil." (cond ((javaimp--parse-is-classlike scope) ;; this will be a sub-alist's car (javaimp-scope-name scope)) - ((javaimp-imenu--included-method scope) + ((javaimp--parse-is-imenu-included-method scope) (javaimp-imenu--make-entry scope)))) #'cdr ;don't include empty container scopes forest))))) -(defsubst javaimp-imenu--included-method (scope) - (and (eq (javaimp-scope-type scope) 'method) - (javaimp--parse-is-classlike (javaimp-scope-parent scope)))) - (defsubst javaimp-imenu--make-entry (scope) (list (javaimp-scope-name scope) (javaimp-scope-start scope) #'javaimp-imenu--go scope)) -(defun javaimp-imenu--concat-parent-names (scope) - (let (parents) - (while (setq scope (javaimp-scope-parent scope)) - (push scope parents)) - (mapconcat #'javaimp-scope-name parents "."))) - - (defun javaimp-imenu--go (scope) (goto-char (javaimp-scope-start scope)) (back-to-indentation)) - - -;; Misc - -(defun javaimp-reset (arg) - "Forget loaded trees state. With prefix arg, also reset jars -cache." - (interactive "P") - (setq javaimp-project-forest nil - javaimp--jdk-classes 'need-init) - (when arg - (setq javaimp-cached-jars nil))) - - ;; Help @@ -713,6 +689,18 @@ scopes cache." (setq buffer-read-only t)) (display-buffer buf))) + +;; Misc + +(defun javaimp-reset (arg) + "Forget loaded trees state. With prefix arg, also reset jars +cache." + (interactive "P") + (setq javaimp-project-forest nil + javaimp--jdk-classes 'need-init) + (when arg + (setq javaimp-cached-jars nil))) + (provide 'javaimp) ;;; javaimp.el ends here diff --git a/testdata/test1-misc-classes.java b/testdata/test1-misc-classes.java index d916221..c010604 100644 --- a/testdata/test1-misc-classes.java +++ b/testdata/test1-misc-classes.java @@ -72,7 +72,7 @@ public class Top { } } - String bar(String arg1, String arg2); + String abstract_method(); static class IInner1_CInner1 { public void foo() { @@ -84,14 +84,14 @@ public class Top { void baz(); - default void defaultMethod() { + default void defaultMethod(String arg1) { System.out.println(""); } interface IInner1_IInner1 extends A<B, C>, Serializable { void foo(); - default String defaultMethod() { + default String defaultMethod(String arg2) { System.out.println(""); } @@ -119,4 +119,7 @@ public class Top { class ColocatedTop { void foo() { } + + void bar(String arg1, String arg2) { + } }