branch: scratch/javaimp-wip
commit dcc6bedf64189f7c4597f8382fea1abd84da8720
Author: Filipp Gunbin <[email protected]>
Commit: Filipp Gunbin <[email protected]>
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) {
+ }
}