emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/javaimp ed09795: Improve decl-suffix handling


From: Filipp Gunbin
Subject: [elpa] externals/javaimp ed09795: Improve decl-suffix handling
Date: Thu, 29 Jul 2021 21:47:57 -0400 (EDT)

branch: externals/javaimp
commit ed09795175cb728a5da6cb52e5ca491b3f10c4eb
Author: Filipp Gunbin <fgunbin@okko.tv>
Commit: Filipp Gunbin <fgunbin@okko.tv>

    Improve decl-suffix handling
---
 javaimp-parse.el | 129 +++++++++++++++++++++++++++++--------------------------
 javaimp-tests.el |   5 +++
 2 files changed, 72 insertions(+), 62 deletions(-)

diff --git a/javaimp-parse.el b/javaimp-parse.el
index 009bbc4..e123c2a 100644
--- a/javaimp-parse.el
+++ b/javaimp-parse.el
@@ -57,6 +57,15 @@ present."
     st)
   "Enables parsing angle brackets as lists")
 
+(defmacro javaimp--parse-with-arglist-syntax (beg &rest body)
+  (declare (debug t))
+  (let ((begin (make-symbol "begin")))
+    `(let ((,begin ,beg))
+       (syntax-ppss-flush-cache ,begin)
+       (unwind-protect
+           (with-syntax-table javaimp--arglist-syntax-table
+             ,@body)
+         (syntax-ppss-flush-cache ,begin)))))
 
 (defsubst javaimp--parse-substr-before-< (str)
   (let ((end (string-search "<" str)))
@@ -68,27 +77,24 @@ present."
   "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."
-  (save-excursion
-    (save-restriction
-      (syntax-ppss-flush-cache beg)
-      (narrow-to-region beg end)
-      (prog1
-          (with-syntax-table javaimp--arglist-syntax-table
-            (goto-char (point-max))
-            (ignore-errors
-              (let (res)
-                (while (progn
-                         (javaimp--parse-skip-back-until)
-                         (not (bobp)))
-                  (push (javaimp--parse-arglist-one-arg only-type) res)
-                  ;; move back to the previous argument, if any
-                  (when (javaimp--parse-skip-back-until
-                         (lambda (_last-what _last-pos)
-                           (and (not (bobp))
-                                (= (char-before) ?,))))
-                    (backward-char)))   ; skip comma
-                res)))
-        (syntax-ppss-flush-cache beg)))))
+  (javaimp--parse-with-arglist-syntax beg
+    (save-excursion
+      (save-restriction
+        (narrow-to-region beg end)
+        (goto-char (point-max))
+        (ignore-errors
+          (let (res)
+            (while (progn
+                     (javaimp--parse-skip-back-until)
+                     (not (bobp)))
+              (push (javaimp--parse-arglist-one-arg only-type) res)
+              ;; move back to the previous argument, if any
+              (when (javaimp--parse-skip-back-until
+                     (lambda (_last-what _last-pos)
+                       (and (not (bobp))
+                            (= (char-before) ?,))))
+                (backward-char)))       ; skip comma
+            res))))))
 
 (defun javaimp--parse-arglist-one-arg (only-type)
   "Parse one argument as type and name backwards starting from
@@ -179,28 +185,28 @@ as for `re-search-backward'."
             (1+ scope-start)))))
 
 (defun javaimp--parse-decl-suffix (regexp state &optional bound)
-  "Subroutine of scope parsers.  Attempts to parse declaration
-suffix backwards (but not farther than BOUND), returning ARGS in
-the same format as `javaimp--parse-arglist' (but here, only TYPE
-element component will be present).  Point is left at the
-position from where scope parsing may be continued.  Returns t if
-parsing failed and should not be continued."
+  "Attempts to parse declaration suffix backwards from point (but
+not farther than BOUND), returning non-nil on success.  More
+precisely, the value is the end of the match for REGEXP.  Point
+is left before the match.  Otherwise, the result is nil and point
+is unchanged."
   (let ((pos (point)))
-    (when (javaimp--rsb-outside-context regexp bound t)
-      (if (ignore-errors             ;As in javaimp--parse-preceding
-            (= (scan-lists (match-end 0) 1 -1)
-               (1+ (nth 1 state))))
-          (let ((res (save-match-data
-                       (javaimp--parse-arglist (match-end 0) pos t))))
-            (if res
-                (goto-char (match-beginning 0))
-              ;; Something's wrong here: tell the caller to stop
-              ;; parsing
-              (setq res t))
-            res)
-        ;; just return to where we started
-        (goto-char pos)
-        nil))))
+    (catch 'found
+      (while (javaimp--rsb-outside-context regexp bound t)
+        (let ((scan-pos (match-end 0)))
+          (javaimp--parse-with-arglist-syntax 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
+                       (1+ (nth 1 state))))
+                  (progn
+                    (goto-char (match-beginning 0))
+                    (throw 'found (match-end 0)))
+                (setq scan-pos (ignore-errors
+                                 (scan-lists scan-pos 1 0))))))))
+      ;; just return to start
+      (goto-char pos)
+      nil)))
 
 
 
@@ -250,26 +256,21 @@ those may later become 'local-class' (see 
`javaimp--parse-scopes')."
                                   (nth 1 state))
         (let* ((keyword-start (match-beginning 1))
                (keyword-end (match-end 1))
-               (decl-suffix (progn
-                              (goto-char (nth 1 state))
-                              (or (javaimp--parse-decl-suffix "\\<extends\\>"
-                                                              state 
keyword-end)
-                                  (javaimp--parse-decl-suffix 
"\\<implements\\>"
-                                                              state 
keyword-end)
-                                  (javaimp--parse-decl-suffix "\\<permits\\>"
-                                                              state 
keyword-end))))
                arglist)
-          (unless (eq decl-suffix t)
-            ;; we either skipped back over the valid declaration
-            ;; suffix(-es), or there isn't any
-            (setq arglist (javaimp--parse-arglist keyword-end (point) t))
-            (when (= (length arglist) 1)
-              (make-javaimp-scope :type (intern
-                                         (buffer-substring-no-properties
-                                          keyword-start keyword-end))
-                                  :name (javaimp--parse-substr-before-< (caar 
arglist))
-                                  :start keyword-start
-                                  :open-brace (nth 1 state))))))))
+          (goto-char (nth 1 state))
+          (or (javaimp--parse-decl-suffix "\\<extends\\>" state keyword-end)
+              (javaimp--parse-decl-suffix "\\<implements\\>" state keyword-end)
+              (javaimp--parse-decl-suffix "\\<permits\\>" state keyword-end))
+          ;; we either skipped back over the valid declaration
+          ;; suffix(-es), or there wasn't any
+          (setq arglist (javaimp--parse-arglist keyword-end (point) t))
+          (when (= (length arglist) 1)
+            (make-javaimp-scope :type (intern
+                                       (buffer-substring-no-properties
+                                        keyword-start keyword-end))
+                                :name (javaimp--parse-substr-before-< (caar 
arglist))
+                                :start keyword-start
+                                :open-brace (nth 1 state)))))))
 
 (defun javaimp--parse-scope-simple-stmt (state)
   "Attempts to parse `simple-statement' scope."
@@ -311,7 +312,11 @@ those may later become 'local-class' (see 
`javaimp--parse-scopes')."
 (defun javaimp--parse-scope-method-or-stmt (state)
   "Attempts to parse `method' or `statement' scope."
   (save-excursion
-    (let ((throws-args (javaimp--parse-decl-suffix "\\<throws\\>" state)))
+    (let ((throws-args
+           (let ((pos (javaimp--parse-decl-suffix "\\<throws\\>" state)))
+             (when pos
+               (or (javaimp--parse-arglist pos (nth 1 state) t)
+                   t)))))
       (when (and (not (eq throws-args t))
                  (progn
                    (javaimp--parse-skip-back-until)
diff --git a/javaimp-tests.el b/javaimp-tests.el
index 55bcbc0..d46ee37 100644
--- a/javaimp-tests.el
+++ b/javaimp-tests.el
@@ -56,6 +56,11 @@
     '("class Foo<Bar, Baz> extends FooSuper<Bar, Baz> \
 implements Interface1<Bar, Baz>, Interface2 {"
       class "Foo")
+    '("class Foo<E extends Bar> {"
+      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 {"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]