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

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

[elpa] scratch/javaimp-parse e884e02 1/2: wip


From: Filipp Gunbin
Subject: [elpa] scratch/javaimp-parse e884e02 1/2: wip
Date: Wed, 2 Jun 2021 23:23:07 -0400 (EDT)

branch: scratch/javaimp-parse
commit e884e0297b4faaefabc6b4f8bc5969e79021604e
Author: Filipp Gunbin <fgunbin@fastmail.fm>
Commit: Filipp Gunbin <fgunbin@fastmail.fm>

    wip
---
 javaimp-parse.el | 162 ++++++++++++++++++++++++++++++++++++-------------------
 javaimp-tests.el |  21 ++++++++
 2 files changed, 127 insertions(+), 56 deletions(-)

diff --git a/javaimp-parse.el b/javaimp-parse.el
index b29b2e8..2b0c3e3 100644
--- a/javaimp-parse.el
+++ b/javaimp-parse.el
@@ -20,6 +20,7 @@
 
 (require 'cl-lib)
 (require 'seq)
+(require 'cc-mode)                      ;for java-mode-syntax-table
 
 (cl-defstruct javaimp-scope
   type ; one of anonymous-class, class, interface, enum, local-class,
@@ -47,18 +48,80 @@
 (defsubst javaimp--parse-is-class (scope)
   (member (symbol-name (javaimp-scope-type scope)) 
javaimp--parse-class-keywords))
 
+(defvar javaimp--arglist-syntax-table
+  "Enables parsing angle brackets as lists"
+  (let ((st (make-syntax-table java-mode-syntax-table)))
+    (modify-syntax-entry ?< "(>" st)
+    (modify-syntax-entry ?> ")<" st)
+    st))
 
-(defun javaimp--parse-get-package ()
+
+
+;;; Arglist
+
+(defun javaimp--parse-arglist (beg end)
   (save-excursion
     (save-restriction
-      (widen)
-      (goto-char (point-min))
-      (catch 'found
-        (while (re-search-forward "^\\s *package\\s +\\([^;]+\\)\\s *;" nil t)
-          (let ((state (syntax-ppss)))
-            (unless (syntax-ppss-context state)
-              (throw 'found (match-string 1)))))))))
+      (narrow-to-region beg end)
+      (with-syntax-table javaimp--arglist-syntax-table ;skip generics like 
lists
+        (goto-char (point-max))
+        (ignore-errors
+          (let (res)
+            (while (not (bobp))
+              (push (javaimp--parse-arglist-one-arg) res)
+              ;; move back to the previous argument, if any
+              (javaimp--parse-arglist-until (lambda ()
+                                              (= (char-before) ?,)))
+              (unless (bobp)
+                (backward-char)))
+            res))))))
+
+(defun javaimp--parse-arglist-one-arg ()
+  ;; Parse one argument backwards starting from point and return it in
+  ;; the form (TYPE . NAME).  Leave point at where the job is done:
+  ;; skipping further backwards is done by the caller.
+  (let ((pos (progn
+               (skip-syntax-backward "-")
+               (point)))
+        name type)
+    (if (= 0 (skip-syntax-backward "w_"))
+        (error "Cannot parse argument name"))
+    (setq name (buffer-substring-no-properties (point) pos))
+    (skip-syntax-backward "-")
+    (setq pos (point))
+    ;; Parse type: allow anything, but stop at the word boundary which
+    ;; is not inside list (this is presumably the type start..)
+    (javaimp--parse-arglist-until (lambda ()
+                                    (looking-at "\\<")))
+    (if (bobp)
+        (error "Cannot parse argument type")
+      (setq type (replace-regexp-in-string
+                  "[[:space:]]+" " "
+                  (buffer-substring-no-properties (point) pos)))
+      (cons type name))))
 
+(defun javaimp--parse-arglist-until (stop-p)
+  ;; Goes backwards until position at which STOP-P returns non-nil.
+  ;; STOP-P is invoked without arguments and should not move point.
+  (catch 'done
+    (while t
+      (skip-syntax-backward "-")
+      (let ((state (syntax-ppss)))
+        (cond ((bobp)
+               (throw 'done nil))
+              ((= (char-syntax (char-before)) ?\))
+               (backward-list))
+              ((syntax-ppss-context state)
+               ;; move out of comment/string if in one
+               (goto-char (nth 8 state)))
+              ((funcall stop-p)
+               (throw 'done nil))
+              (t
+               (backward-char)))))))
+
+
+
+;;; Scopes
 
 (defvar javaimp--parse-scope-hook
   '(;; should be before method/stmt because looks similar, but with
@@ -107,12 +170,12 @@
 (defun javaimp--parse-scope-method-or-stmt (state)
   (save-excursion
     (when (and (ignore-errors
-                 (goto-char             ;skip over 1 list
+                 (goto-char
                   (scan-lists (nth 1 state) -1 0)))
                (eq (char-after) ?\())
-      (let* ((arglist (buffer-substring-no-properties
-                       (point)
-                       (scan-lists (point) 1 0)))
+      (let* (;; leave open/close parens out
+             (arglist-region (cons (1+ (point))
+                                   (1- (scan-lists (point) 1 0))))
              (count (progn
                       (skip-syntax-backward "-")
                       (skip-syntax-backward "w_")))
@@ -123,50 +186,22 @@
                      (if (member name javaimp--parse-stmt-keywords)
                          'statement 'method))))
         (when type
-          (make-javaimp-scope :type type
-                              :name (if (eq type 'statement)
-                                        name
-                                      (concat name
-                                              ;; to distinguish overloaded 
methods
-                                              (javaimp--parse-arglist 
arglist)))
-                              :start (point)
-                              :open-brace (nth 1 state)))))))
-
-(defun javaimp--parse-arglist (arglist)
-  (with-temp-buffer
-    (with-syntax-table 'javaimp--arglist-syntax-table ;TODO <>
-      (condition-case nil
-          (let (name end res curr)
-            (insert arglist)
-            (backward-char)               ; `)'
-            (while (not (bobp))
-              (setq end (point))
-              ;; name
-              (if (= 0 (skip-syntax-backward "w_"))
-                  (error "No name")
-                (setq name (buffer-substring (point) end)))
-              (skip-syntax-backward "-")
-              (setq start nil
-                    end (point))
-              ;; type - allow anything but skip over angle brackets
-              (while (not start)
-                (cond ((bobp)
-                       (error "Invalid type"))
-                      ((= (char-before) ? )
-                       (setq start (point)))
-                      ((= (char-before) ?>)
-                       ;; skip over generics
-                       (goto-char
-                        (scan-lists (point) -1 0)))
-                      (t
-                       (backward-char))))
-              (push (cons (buffer-substring start end) name) res)
-              (setq curr nil)
-              ;; TODO skip everything up to comma or open-paren
-              )
-            res)
-        (t nil)))))
-
+          (make-javaimp-scope
+           :type type
+           :name (if (eq type 'statement)
+                     name
+                   (concat name
+                           "("
+                           (mapconcat (lambda (arg)
+                                        ;; omit name?
+                                        (concat (car arg) " " (cdr arg)))
+                                      (javaimp--parse-arglist
+                                       (car arglist-region) (cdr 
arglist-region))
+                                      ", ")
+                           ")"
+                           ))
+           :start (point)
+           :open-brace (nth 1 state)))))))
 
 (defun javaimp--parse-scope-class (state)
   (save-excursion
@@ -215,6 +250,21 @@
         (setq tmp (cdr tmp))))
     res))
 
+
+
+;; Main
+
+(defun javaimp--parse-get-package ()
+  (save-excursion
+    (save-restriction
+      (widen)
+      (goto-char (point-min))
+      (catch 'found
+        (while (re-search-forward "^\\s *package\\s +\\([^;]+\\)\\s *;" nil t)
+          (let ((state (syntax-ppss)))
+            (unless (syntax-ppss-context state)
+              (throw 'found (match-string 1)))))))))
+
 (defun javaimp--parse-get-file-classes (file)
   (with-temp-buffer
     (insert-file-contents file)
diff --git a/javaimp-tests.el b/javaimp-tests.el
index 9951a81..055e21a 100644
--- a/javaimp-tests.el
+++ b/javaimp-tests.el
@@ -23,6 +23,27 @@
       (should (eql (length projects) 2)))))
 
 
+(ert-deftest javaimp-test--parse-arglist ()
+  (dolist (data '(("")
+                  ("  ")
+                  ("int i"
+                   ("int" . "i"))
+                  ("List<? extends Comparable<? super T>> list, T... elements"
+                   ("List<? extends Comparable<? super T>>" . "list")
+                   ("T..." . "elements"))
+                  ("org.foo.Map <? extends K,   ? extends V> m, String [] 
array, int i"
+                   ;; TODO fix code to clear up extra ws here
+                   ("org.foo.Map <? extends K, ? extends V>" . "m")
+                   ("String []" . "array")
+                   ("int" . "i"))
+                  ("Bi_Function<? super K, ? super V, ? extends V> function"
+                   ("Bi_Function<? super K, ? super V, ? extends V>" . 
"function"))))
+    (with-temp-buffer
+      (java-mode)
+      (insert (car data))
+      (should (equal (javaimp--parse-arglist (point-min) (point-max))
+                     (cdr data))))))
+
 (ert-deftest javaimp-test--parse-get-package ()
   (with-temp-buffer
     (insert "//package org.commented1;



reply via email to

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