branch: externals/javaimp commit 7fc2b51924ef0a4c16f38674f7428637050bf85f Author: Filipp Gunbin <fgun...@fastmail.fm> Commit: Filipp Gunbin <fgun...@fastmail.fm>
More simplifications --- javaimp-parse.el | 18 ++-- javaimp-tests.el | 308 +++++++++++++++++++++++++++---------------------------- javaimp-util.el | 26 ----- javaimp.el | 46 +++------ 4 files changed, 174 insertions(+), 224 deletions(-) diff --git a/javaimp-parse.el b/javaimp-parse.el index 91002a0..a9cef3b 100644 --- a/javaimp-parse.el +++ b/javaimp-parse.el @@ -275,11 +275,10 @@ the position of opening brace.") (1+ (point)))))) (when search-bound (let ((throws-args - (let ((pos (javaimp--parse-decl-suffix - "\\_<throws\\_>" brace-pos search-bound))) - (when pos - (or (javaimp--parse-arglist pos brace-pos t) - t))))) + (when-let ((pos (javaimp--parse-decl-suffix + "\\_<throws\\_>" brace-pos search-bound))) + (or (javaimp--parse-arglist pos brace-pos t) + t)))) (when (and (not (eq throws-args t)) (progn (javaimp--parse-skip-back-until) @@ -306,11 +305,10 @@ the position of opening brace.") :type type :name (if (eq type 'statement) name - (funcall javaimp-format-method-name - name - (javaimp--parse-arglist (car arglist-region) - (cdr arglist-region)) - throws-args)) + (let ((args (javaimp--parse-arglist + (car arglist-region) + (cdr arglist-region)))) + (concat name "(" (mapconcat #'car args ",") ")"))) :start (point) :open-brace brace-pos))))))))) diff --git a/javaimp-tests.el b/javaimp-tests.el index d102527..1b50257 100644 --- a/javaimp-tests.el +++ b/javaimp-tests.el @@ -66,106 +66,102 @@ Exception4<? super Exception5>>") ;; `javaimp--parse-scope-hook'. (ert-deftest javaimp-test--parse-scope-class () - (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-class)) - (javaimp-test--check-single-scope - '("class Foo {" - class "Foo") - '("class Foo extends Bar {" - class "Foo") - '("class Foo implements Bar {" - class "Foo") - '("class Foo implements Bar, Baz {" - class "Foo") - '("public class Foo extends Bar implements Baz1 , Baz2 {" - class "Foo") - `(,(subst-char-in-string - ? ?\n - "public class Foo extends Bar implements Baz1 , Baz2 {") - class "Foo") - '("class Foo<Bar, Baz> extends FooSuper<Bar, Baz> \ + (javaimp-test--single-parser #'javaimp--parse-scope-class + '("class Foo {" + class "Foo") + '("class Foo extends Bar {" + class "Foo") + '("class Foo implements Bar {" + class "Foo") + '("class Foo implements Bar, Baz {" + class "Foo") + '("public class Foo extends Bar implements Baz1 , Baz2 {" + class "Foo") + `(,(subst-char-in-string + ? ?\n + "public class Foo extends Bar implements Baz1 , Baz2 {") + class "Foo") + '("class Foo<Bar, Baz> extends FooSuper<Bar, Baz> \ implements Interface1<Bar, Baz>, Interface2 {" - class "Foo") - '("class Foo<E extends Bar> {" - class "Foo") - '("class Foo<Enum<?>> {" - class "Foo") - '("class Foo<T extends Baz<? extends Baz2>> \ + class "Foo") + '("class Foo<E extends Bar> {" + class "Foo") + '("class Foo<Enum<?>> {" + class "Foo") + '("class Foo<T extends Baz<? extends Baz2>> \ extends Bar<? extends Baz<? extends Baz2>> {" - class "Foo") - '("interface Foo<Bar, Baz> {" - interface "Foo") - '("private enum Foo {" - enum "Foo") - ))) + class "Foo") + '("interface Foo<Bar, Baz> {" + interface "Foo") + '("private enum Foo {" + enum "Foo") + )) (ert-deftest javaimp-test--parse-scope-anonymous-class () - (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-anonymous-class)) - (javaimp-test--check-single-scope - '(" = new Object < Class1 , Class2 > ( 1 + 1 , baz ) {" - anonymous-class "Object") - `(,(subst-char-in-string - ? ?\n - " = new Object < Class1 , Class2 > ( 1 + 1 , baz ) {") - anonymous-class "Object") - '(" = (obj.getField()).new Object<Class1, Class2>(1, baz) {" - anonymous-class "Object") - '(" = obj.new Object<>(1, baz) {" - anonymous-class "Object") - ))) + (javaimp-test--single-parser #'javaimp--parse-scope-anonymous-class + '(" = new Object < Class1 , Class2 > ( 1 + 1 , baz ) {" + anonymous-class "Object") + `(,(subst-char-in-string + ? ?\n + " = new Object < Class1 , Class2 > ( 1 + 1 , baz ) {") + anonymous-class "Object") + '(" = (obj.getField()).new Object<Class1, Class2>(1, baz) {" + anonymous-class "Object") + '(" = obj.new Object<>(1, baz) {" + anonymous-class "Object") + )) (ert-deftest javaimp-test--parse-scope-method-or-stmt () - (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-method-or-stmt) - (javaimp-format-method-name #'javaimp-format-method-name-full)) - (javaimp-test--check-single-scope - '("static void foo_bar ( String a , int b ) {" - method "foo_bar(String a, int b)") - `(,(subst-char-in-string - ? ?\n - "static void foo_bar ( String a , int b ) {") - method "foo_bar(String a, int b)") - '("void foo_bar(String a, int b) throws E1, E2 {" - method "foo_bar(String a, int b) throws E1, E2") - '("void foo_bar() + (javaimp-test--single-parser #'javaimp--parse-scope-method-or-stmt + '("static void foo_bar ( String a , int b ) {" + method "foo_bar(String,int)") + `(,(subst-char-in-string + ? ?\n + "static void foo_bar ( String a , int b ) {") + method "foo_bar(String,int)") + '("void foo_bar(String a, int b) throws E1, E2 {" + method "foo_bar(String,int)") + '("void foo_bar() throws E1 {" - method "foo_bar() throws E1") - '("if (foo_bar(a, b) < 2) {" - statement "if") - ))) + method "foo_bar()") + '("if (foo_bar(a, b) < 2) {" + statement "if") + )) (ert-deftest javaimp-test--parse-scope-simple-stmt () - (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-simple-stmt)) - (javaimp-test--check-single-scope - '(" try {" - simple-statement "try") - `(,(subst-char-in-string ? ?\n " try {") - simple-statement "try") - ;; static initializer - '("static {" - simple-statement "static") - ;; lambda - '("it -> {" - simple-statement "lambda") - '("(x, y) -> {" - simple-statement "lambda") - ))) + (javaimp-test--single-parser #'javaimp--parse-scope-simple-stmt + '(" try {" + simple-statement "try") + `(,(subst-char-in-string ? ?\n " try {") + simple-statement "try") + ;; static initializer + '("static {" + simple-statement "static") + ;; lambda + '("it -> {" + simple-statement "lambda") + '("(x, y) -> {" + simple-statement "lambda") + )) (ert-deftest javaimp-test--parse-scope-array () - (let ((javaimp--parse-scope-hook #'javaimp--parse-scope-array)) - (javaimp-test--check-single-scope - '("new String[] {" - array "") - ;; TODO fix - ;; '("new Object[][] { {" - ;; array "") - ;; '("new int[] {{1, 2}, {" - ;; array "") - ))) - -(defun javaimp-test--check-single-scope (&rest test-items) + (javaimp-test--single-parser #'javaimp--parse-scope-array + '("new String[] {" + array "") + ;; TODO fix + ;; '("new Object[][] { {" + ;; array "") + ;; '("new int[] {{1, 2}, {" + ;; array "") + )) + +(defun javaimp-test--single-parser (parser &rest test-items) + (declare (indent 1)) (dolist (item test-items) (with-temp-buffer (insert (nth 0 item)) - (let ((scopes (javaimp--parse-get-all-scopes))) + (let* ((javaimp--parse-scope-hook parser) + (scopes (javaimp--parse-get-all-scopes))) (should (= 1 (length scopes))) (should (eq (javaimp-scope-type (car scopes)) (nth 1 item))) (should (equal (javaimp-scope-name (car scopes)) (nth 2 item))))))) @@ -186,16 +182,15 @@ package commented.block; (with-temp-buffer (insert-file-contents (concat javaimp--basedir "testdata/test1-misc-classes.java")) - (let ((javaimp-format-method-name #'javaimp-format-method-name-types)) - ;; parse full buffer - (javaimp-test--check-named-scopes) - ;; - ;; reparse half of buffer - (setq javaimp--parse-dirty-pos (/ (- (point-max) (point-min)) 2)) - (javaimp-test--check-named-scopes) - ;; - ;; don't reparse - (javaimp-test--check-named-scopes)))) + ;; parse full buffer + (javaimp-test--check-named-scopes) + ;; + ;; reparse half of buffer + (setq javaimp--parse-dirty-pos (/ (- (point-max) (point-min)) 2)) + (javaimp-test--check-named-scopes) + ;; + ;; don't reparse + (javaimp-test--check-named-scopes))) (defun javaimp-test--check-named-scopes () (let* ((scopes (javaimp--parse-get-all-scopes @@ -266,7 +261,7 @@ package commented.block; ((class "ColocatedTop")) ((method "foo()") (class "ColocatedTop")) - ((method "bar(String, String)") (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)))) @@ -305,71 +300,68 @@ package commented.block; ;; Tests for imenu function (ert-deftest javaimp-test--imenu () - (let* ((javaimp-format-method-name #'javaimp-format-method-name-types) - (actual - (with-temp-buffer - (insert-file-contents - (concat javaimp--basedir "testdata/test1-misc-classes.java")) - (let ((imenu-use-markers nil)) - (javaimp-imenu-create-index)))) - (expected-names - '("foo() [Top.CInner1]" - "foo() [Top.CInner1.CInner1_CInner1]" - "abstract_method() [Top.CInner1.CInner1_CInner1]" - "bar()" - "baz() [Top.CInner1.CInner1_CInner1]" - "foo() [Top.IInner1]" - "abstract_method() [Top.IInner1]" - "foo() [Top.IInner1.IInner1_CInner1]" - "baz() [Top.IInner1]" - "defaultMethod(String) [Top.IInner1]" - "foo() [Top.IInner1.IInner1_IInner1]" - "defaultMethod(String) [Top.IInner1.IInner1_IInner1]" - "baz() [Top.IInner1.IInner1_IInner1]" - "EnumInner1()" - "foo() [Top.EnumInner1]" - "foo() [ColocatedTop]" - "bar(String, String)"))) + (let ((actual (with-temp-buffer + (insert-file-contents + (concat javaimp--basedir "testdata/test1-misc-classes.java")) + (let ((imenu-use-markers nil)) + (javaimp-imenu-create-index)))) + (expected-names + '("foo() [Top.CInner1]" + "foo() [Top.CInner1.CInner1_CInner1]" + "abstract_method() [Top.CInner1.CInner1_CInner1]" + "bar()" + "baz() [Top.CInner1.CInner1_CInner1]" + "foo() [Top.IInner1]" + "abstract_method() [Top.IInner1]" + "foo() [Top.IInner1.IInner1_CInner1]" + "baz() [Top.IInner1]" + "defaultMethod(String) [Top.IInner1]" + "foo() [Top.IInner1.IInner1_IInner1]" + "defaultMethod(String) [Top.IInner1.IInner1_IInner1]" + "baz() [Top.IInner1.IInner1_IInner1]" + "EnumInner1()" + "foo() [Top.EnumInner1]" + "foo() [ColocatedTop]" + "bar(String,String)"))) (should (= (length expected-names) (length actual))) (dotimes (i (length expected-names)) (should (equal (nth i expected-names) (car (nth i actual))))))) -(ert-deftest javaimp-test--imenu-group-methods () - (let* ((javaimp-format-method-name #'javaimp-format-method-name-types) - (javaimp-imenu-group-methods t) - (actual (with-temp-buffer - (insert-file-contents - (concat javaimp--basedir "testdata/test1-misc-classes.java")) - (let ((imenu-use-markers nil)) - (javaimp-imenu-create-index)))) - (expected - '(("Top" - ("CInner1" - ("foo()" . 98) - ("CInner1_CInner1" - ("foo()" . 1099) - ("abstract_method()" . 1148) - ("bar()" . 1192) - ("baz()" . 1281))) - ("IInner1" - ("foo()" . 1603) - ("abstract_method()" . 1715) - ("IInner1_CInner1" - ("foo()" . 1798)) - ("baz()" . 1934) - ("defaultMethod(String)" . 1963) - ("IInner1_IInner1" - ("foo()" . 2122) - ("defaultMethod(String)" . 2157) - ("baz()" . 2258))) - ("EnumInner1" - ("EnumInner1()" . 2353) - ("foo()" . 2399) - ;; "EnumInner1_EInner1" omitted because no methods inside - )) - ("ColocatedTop" - ("foo()" . 2554) - ("bar(String, String)" . 2578))))) +(ert-deftest javaimp-test--imenu-use-sub-alists () + (let ((actual (with-temp-buffer + (insert-file-contents + (concat javaimp--basedir "testdata/test1-misc-classes.java")) + (let ((imenu-use-markers nil) + (javaimp-imenu-use-sub-alists t)) + (javaimp-imenu-create-index)))) + (expected + '(("Top" + ("CInner1" + ("foo()" . 98) + ("CInner1_CInner1" + ("foo()" . 1099) + ("abstract_method()" . 1148) + ("bar()" . 1192) + ("baz()" . 1281))) + ("IInner1" + ("foo()" . 1603) + ("abstract_method()" . 1715) + ("IInner1_CInner1" + ("foo()" . 1798)) + ("baz()" . 1934) + ("defaultMethod(String)" . 1963) + ("IInner1_IInner1" + ("foo()" . 2122) + ("defaultMethod(String)" . 2157) + ("baz()" . 2258))) + ("EnumInner1" + ("EnumInner1()" . 2353) + ("foo()" . 2399) + ;; "EnumInner1_EInner1" omitted because no methods inside + )) + ("ColocatedTop" + ("foo()" . 2554) + ("bar(String,String)" . 2578))))) (javaimp-test--imenu-simplify-entries actual) (should (equal expected actual)))) diff --git a/javaimp-util.el b/javaimp-util.el index 15052d2..5f1c2df 100644 --- a/javaimp-util.el +++ b/javaimp-util.el @@ -145,32 +145,6 @@ left." res)) -;;; Formatting - -(defsubst javaimp-format-method-name-full (name args throws-args) - "Outputs NAME, ARGS (name and type) and THROWS-ARGS (only type)." - (concat name - "(" - (mapconcat (lambda (arg) - (concat (car arg) " " (cdr arg))) - args - ", ") - ")" - (if throws-args - (concat " throws " - (mapconcat #'car throws-args ", "))) - )) - -(defsubst javaimp-format-method-name-types (name args _throws-args) - "Outputs NAME and ARGS (only type)." - (concat name - "(" - (mapconcat #'car args ", ") - ")" - )) - - - ;; Tree (defun javaimp--build-tree (this all child-p &optional parent-node sort-pred) diff --git a/javaimp.el b/javaimp.el index 0cc7ade..cae2e8a 100644 --- a/javaimp.el +++ b/javaimp.el @@ -149,13 +149,10 @@ files in the current project and add their fully-qualified names to the completion alternatives list." :type 'boolean) -(defcustom javaimp-imenu-group-methods nil - "Non-nil means group methods in their enclosing scopes. -nil (the default) means just use flat list of simple method -names. See also `javaimp-format-method-name'." - :type '(choice :tag "Group methods" - (const :tag "Grouped" t) - (const :tag "Simple list" nil))) +(defcustom javaimp-imenu-use-sub-alists nil + "If non-nil, make sub-alist for each containing scope (e.g. a +class)." + :type 'boolean) (defcustom javaimp-cygpath-program (if (eq system-type 'cygwin) "cygpath") @@ -163,13 +160,6 @@ names. See also `javaimp-format-method-name'." the program is not on `exec-path'." :type 'string) -(defcustom javaimp-format-method-name #'javaimp-format-method-name-full - "Function to format method name, invoked with 3 arguments: -NAME, ARGS and THROWS-ARGS. The last two are lists with elements -of the form (TYPE . NAME). For THROWS-ARGS, only TYPE is -present." - :type 'function) - (defcustom javaimp-mvn-program "mvn" "Path to the `mvn' program. Customize it if the program is not on `exec-path'." @@ -625,8 +615,7 @@ is `ordinary' or `static'. Interactively, NEW-IMPORTS is nil." "Function to use as `imenu-create-index-function', can be set in a major mode hook." (let ((forest (javaimp-imenu--get-forest))) - (if javaimp-imenu-group-methods - ;; group methods inside parents + (if javaimp-imenu-use-sub-alists (javaimp--map-nodes (lambda (scope) (if (eq (javaimp-scope-type scope) 'method) @@ -638,16 +627,21 @@ in a major mode hook." (or (functionp (nth 2 res)) ;entry (cdr res))) ;non-empty sub-alist forest) - ;; plain list of methods - (let ((entries (javaimp-imenu--make-entries-simple forest)) - name-alist) + (let ((entries + (mapcar #'javaimp-imenu--make-entry + (seq-sort-by #'javaimp-scope-start #'< + (javaimp--collect-nodes + (lambda (scope) + (eq (javaimp-scope-type scope) 'method)) + forest)))) + alist) (mapc (lambda (entry) - (setf (alist-get (car entry) name-alist 0 nil #'equal) - (1+ (alist-get (car entry) name-alist 0 nil #'equal)))) + (setf (alist-get (car entry) alist 0 nil #'equal) + (1+ (alist-get (car entry) alist 0 nil #'equal)))) entries) (mapc (lambda (entry) ;; disambiguate same method names - (when (> (alist-get (car entry) name-alist 0 nil #'equal) 1) + (when (> (alist-get (car entry) alist 0 nil #'equal) 1) (setcar entry (format "%s [%s]" (car entry) @@ -691,14 +685,6 @@ in a major mode hook." (javaimp-scope-start s2))))) top-classes))) -(defun javaimp-imenu--make-entries-simple (forest) - (mapcar #'javaimp-imenu--make-entry - (seq-sort-by #'javaimp-scope-start #'< - (javaimp--collect-nodes - (lambda (scope) - (eq (javaimp-scope-type scope) 'method)) - forest)))) - (defsubst javaimp-imenu--make-entry (scope) (list (javaimp-scope-name scope) (if imenu-use-markers