[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;